Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-utils / passphrase.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Passphrase Handling Utils
4  *
5  * Copyright 2011 Shea Levy <shea@shealevy.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <errno.h>
21 #include <freerdp/utils/passphrase.h>
22 #ifdef _WIN32
23 char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz)
24 {
25         errno=ENOSYS;
26         return NULL;
27 }
28 #else
29 #include <fcntl.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <termios.h>
34 #include <unistd.h>
35 #include <freerdp/utils/signal.h>
36
37 char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz)
38 {
39         char read_char;
40         char* buf_iter;
41         char term_name[L_ctermid];
42         int term_file, write_file;
43         ssize_t nbytes;
44         size_t read_bytes = 0;
45
46         if (bufsiz == 0)
47         {
48                 errno = EINVAL;
49                 return NULL;
50         }
51
52         ctermid(term_name);
53         if(strcmp(term_name, "") == 0
54                 || (term_file = open(term_name, O_RDWR)) == -1)
55         {
56                 write_file = STDERR_FILENO;
57                 terminal_fildes = STDIN_FILENO;
58         }
59         else
60         {
61                 write_file = term_file;
62                 terminal_fildes = term_file;
63         }
64
65         if (tcgetattr(terminal_fildes, &orig_flags) != -1)
66         {
67                 new_flags = orig_flags;
68                 new_flags.c_lflag &= ~ECHO;
69                 new_flags.c_lflag |= ECHONL;
70                 terminal_needs_reset = 1;
71                 if (tcsetattr(terminal_fildes, TCSAFLUSH, &new_flags) == -1)
72                         terminal_needs_reset = 0;
73         }
74
75         if (write(write_file, prompt, strlen(prompt)) == (ssize_t) -1)
76                 goto error;
77
78         buf_iter = buf;
79         while ((nbytes = read(terminal_fildes, &read_char, sizeof read_char)) == (sizeof read_char))
80         {
81                 if (read_char == '\n')
82                         break;
83                 if (read_bytes < (bufsiz - (size_t) 1))
84                 {
85                         read_bytes++;
86                         *buf_iter = read_char;
87                         buf_iter++;
88                 }
89         }
90         *buf_iter = '\0';
91         buf_iter = NULL;
92         read_char = '\0';
93         if (nbytes == (ssize_t) -1)
94                 goto error;
95
96         if (terminal_needs_reset)
97         {
98                 if (tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags) == -1)   
99                         goto error;
100                 terminal_needs_reset = 0;
101         }
102
103         if (terminal_fildes != STDIN_FILENO)
104         {
105                 if (close(terminal_fildes) == -1)
106                         goto error;
107         }
108
109         return buf;
110
111         error:
112         {
113                 int saved_errno = errno;
114                 buf_iter = NULL;
115                 read_char = '\0';
116                 if (terminal_needs_reset)
117                         tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
118                 if (terminal_fildes != STDIN_FILENO)
119                         close(terminal_fildes);
120                 errno = saved_errno;
121                 return NULL;
122         }
123 }
124 #endif