20 #include <freerdp/config.h>
21 #include <freerdp/freerdp.h>
24 #include <freerdp/utils/passphrase.h>
33 static char read_chr(FILE* f)
36 const BOOL isTty = _isatty(_fileno(f));
39 if (fscanf_s(f,
"%c", &chr, (UINT32)
sizeof(
char)) && !feof(f))
44 int freerdp_interruptible_getc(rdpContext* context, FILE* f)
49 const char* freerdp_passphrase_read(rdpContext* context,
const char* prompt,
char* buf,
50 size_t bufsiz,
int from_stdin)
52 WCHAR UserNameW[CREDUI_MAX_USERNAME_LENGTH + 1] = {
'p',
'r',
'e',
'f',
'i',
53 'l',
'l',
'e',
'd',
'\0' };
54 WCHAR PasswordW[CREDUI_MAX_PASSWORD_LENGTH + 1] = { 0 };
57 WCHAR* promptW = ConvertUtf8ToWCharAlloc(prompt, NULL);
59 CredUICmdLinePromptForCredentialsW(promptW, NULL, 0, UserNameW, ARRAYSIZE(UserNameW),
60 PasswordW, ARRAYSIZE(PasswordW), &fSave, dwFlags);
62 if (ConvertWCharNToUtf8(PasswordW, ARRAYSIZE(PasswordW), buf, bufsiz) < 0)
67 #elif !defined(ANDROID)
75 #include <freerdp/utils/signal.h>
77 #if defined(WINPR_HAVE_POLL_H) && !defined(__APPLE__)
81 #include <sys/select.h>
84 static int wait_for_fd(
int fd,
int timeout)
87 #if defined(WINPR_HAVE_POLL_H) && !defined(__APPLE__)
88 struct pollfd pollset = { 0 };
90 pollset.events = POLLIN;
95 status = poll(&pollset, 1, timeout);
96 }
while ((status < 0) && (errno == EINTR));
100 struct timeval tv = { 0 };
106 tv.tv_sec = timeout / 1000;
107 tv.tv_usec = (timeout % 1000) * 1000;
112 status = select(fd + 1, &rset, NULL, NULL, timeout ? &tv : NULL);
113 }
while ((status < 0) && (errno == EINTR));
119 static void replace_char(
char* buffer,
size_t buffer_len,
const char* toreplace)
121 while (*toreplace !=
'\0')
124 while ((ptr = strrchr(buffer, *toreplace)) != NULL)
130 static const char* freerdp_passphrase_read_tty(rdpContext* context,
const char* prompt,
char* buf,
131 size_t bufsiz,
int from_stdin)
133 BOOL terminal_needs_reset = FALSE;
134 char term_name[L_ctermid] = { 0 };
145 int terminal_fildes = 0;
146 if (from_stdin || (strcmp(term_name,
"") == 0))
149 terminal_fildes = STDIN_FILENO;
153 const int term_file = open(term_name, O_RDWR);
157 terminal_fildes = STDIN_FILENO;
161 fout = fdopen(term_file,
"w");
167 terminal_fildes = term_file;
171 struct termios orig_flags = { 0 };
172 if (tcgetattr(terminal_fildes, &orig_flags) != -1)
174 struct termios new_flags = { 0 };
175 new_flags = orig_flags;
176 new_flags.c_lflag &= ~ECHO;
177 new_flags.c_lflag |= ECHONL;
178 terminal_needs_reset = TRUE;
179 if (tcsetattr(terminal_fildes, TCSAFLUSH, &new_flags) == -1)
180 terminal_needs_reset = FALSE;
183 FILE* fp = fdopen(terminal_fildes,
"r");
187 (void)fprintf(fout,
"%s", prompt);
193 const SSIZE_T res = freerdp_interruptible_get_line(context, &ptr, &ptr_len, fp);
196 replace_char(ptr, ptr_len,
"\r\n");
198 strncpy(buf, ptr, MIN(bufsiz, ptr_len));
200 if (terminal_needs_reset)
202 if (tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags) == -1)
206 if (terminal_fildes != STDIN_FILENO)
208 if (fclose(fp) == -1)
216 int saved_errno = errno;
217 if (terminal_needs_reset)
218 (void)tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
220 if (terminal_fildes != STDIN_FILENO)
230 static const char* freerdp_passphrase_read_askpass(
const char* prompt,
char* buf,
size_t bufsiz,
231 char const* askpass_env)
233 char command[4096] = { 0 };
235 (void)sprintf_s(command,
sizeof(command),
"%s 'FreeRDP authentication\n%s'", askpass_env,
237 FILE* askproc = popen(command,
"r");
240 WINPR_ASSERT(bufsiz <= INT32_MAX);
241 if (fgets(buf, (
int)bufsiz, askproc) != NULL)
242 buf[strcspn(buf,
"\r\n")] =
'\0';
245 const int status = pclose(askproc);
246 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
252 const char* freerdp_passphrase_read(rdpContext* context,
const char* prompt,
char* buf,
253 size_t bufsiz,
int from_stdin)
255 const char* askpass_env = getenv(
"FREERDP_ASKPASS");
258 return freerdp_passphrase_read_askpass(prompt, buf, bufsiz, askpass_env);
260 return freerdp_passphrase_read_tty(context, prompt, buf, bufsiz, from_stdin);
263 int freerdp_interruptible_getc(rdpContext* context, FILE* f)
266 const int fd = fileno(f);
268 const int orig = fcntl(fd, F_GETFL);
269 (void)fcntl(fd, F_SETFL, orig | O_NONBLOCK);
272 const int res = wait_for_fd(fd, 10);
276 const ssize_t rd = read(fd, &c, 1);
281 }
while (!freerdp_shall_disconnect_context(context));
283 (void)fcntl(fd, F_SETFL, orig);
289 const char* freerdp_passphrase_read(rdpContext* context,
const char* prompt,
char* buf,
290 size_t bufsiz,
int from_stdin)
295 int freerdp_interruptible_getc(rdpContext* context, FILE* f)
301 SSIZE_T freerdp_interruptible_get_line(rdpContext* context,
char** plineptr,
size_t* psize,
311 if (!plineptr || !psize)
322 n = realloc(ptr, len);
332 c = freerdp_interruptible_getc(context, stream);
334 ptr[used++] = (char)c;
335 }
while ((c !=
'\n') && (c !=
'\r') && (c != EOF));