FreeRDP/libfreerdp/utils/passphrase.c

140 lines
2.9 KiB
C

/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Passphrase Handling Utils
*
* Copyright 2011 Shea Levy <shea@shealevy.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <freerdp/utils/passphrase.h>
#ifdef _WIN32
char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz, int from_stdin)
{
errno = ENOSYS;
return NULL;
}
#elif !defined(ANDROID)
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <freerdp/utils/signal.h>
char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz, int from_stdin)
{
char read_char;
char* buf_iter;
char term_name[L_ctermid];
int term_file, write_file;
ssize_t nbytes;
size_t read_bytes = 0;
if (bufsiz == 0)
{
errno = EINVAL;
return NULL;
}
ctermid(term_name);
if (from_stdin || strcmp(term_name, "") == 0 || (term_file = open(term_name, O_RDWR)) == -1)
{
write_file = STDERR_FILENO;
terminal_fildes = STDIN_FILENO;
}
else
{
write_file = term_file;
terminal_fildes = term_file;
}
if (tcgetattr(terminal_fildes, &orig_flags) != -1)
{
new_flags = orig_flags;
new_flags.c_lflag &= ~ECHO;
new_flags.c_lflag |= ECHONL;
terminal_needs_reset = 1;
if (tcsetattr(terminal_fildes, TCSAFLUSH, &new_flags) == -1)
terminal_needs_reset = 0;
}
if (write(write_file, prompt, strlen(prompt)) == (ssize_t)-1)
goto error;
buf_iter = buf;
while ((nbytes = read(terminal_fildes, &read_char, sizeof read_char)) == (sizeof read_char))
{
if (read_char == '\n')
break;
if (read_bytes < (bufsiz - (size_t)1))
{
read_bytes++;
*buf_iter = read_char;
buf_iter++;
}
}
*buf_iter = '\0';
buf_iter = NULL;
read_char = '\0';
if (nbytes == (ssize_t)-1)
goto error;
if (terminal_needs_reset)
{
if (tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags) == -1)
goto error;
terminal_needs_reset = 0;
}
if (terminal_fildes != STDIN_FILENO)
{
if (close(terminal_fildes) == -1)
goto error;
}
return buf;
error:
{
int saved_errno = errno;
buf_iter = NULL;
read_char = '\0';
if (terminal_needs_reset)
tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
if (terminal_fildes != STDIN_FILENO)
close(terminal_fildes);
errno = saved_errno;
return NULL;
}
}
#else
char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz, int from_stdin)
{
return NULL;
}
#endif