diff options
author | Mattias Andrée <maandree@operamail.com> | 2015-12-05 00:22:34 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2015-12-05 00:22:34 +0100 |
commit | 18894103fcf337dfa672481ffc6b4906f340adff (patch) | |
tree | d703c56133818df28a6714db9128c647da1c1bc9 | |
parent | m (diff) | |
download | libpassphrase-18894103fcf337dfa672481ffc6b4906f340adff.tar.gz libpassphrase-18894103fcf337dfa672481ffc6b4906f340adff.tar.bz2 libpassphrase-18894103fcf337dfa672481ffc6b4906f340adff.tar.xz |
accept input from any fd
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | info/libpassphrase.texinfo | 52 | ||||
-rw-r--r-- | src/passphrase.c | 84 | ||||
-rw-r--r-- | src/passphrase.h | 46 | ||||
-rw-r--r-- | src/test.c | 6 |
5 files changed, 150 insertions, 42 deletions
@@ -118,11 +118,11 @@ bin/libpassphrase.a: obj/passphrase.o bin/test: bin/libpassphrase.so obj/test.o $(CC) $(LD_FLAGS) -Lbin -lpassphrase -o "$@" obj/test.o $(LDFLAGS) -obj/passphrase.o: src/passphrase.c src/passphrase.h src/passphrase_helper.h +obj/passphrase.o: src/passphrase.c src/*.h @mkdir -p "$(shell dirname "$@")" $(CC) $(CC_FLAGS) -fPIC -o "$@" -c "$<" $(CFLAGS) $(CPPFLAGS) -obj/test.o: src/test.c src/test.h +obj/test.o: src/test.c src/test.h src/passphrase.h @mkdir -p "$(shell dirname "$@")" $(CC) $(CC_FLAGS) -o "$@" -c "$<" $(CFLAGS) $(CPPFLAGS) diff --git a/info/libpassphrase.texinfo b/info/libpassphrase.texinfo index d981a3f..a5a27f1 100644 --- a/info/libpassphrase.texinfo +++ b/info/libpassphrase.texinfo @@ -105,33 +105,53 @@ Including @file{passphrase.h} gives you three functions: @table @code -@item void passphrase_disable_echo(void) -Invoking @code{passphrase_disable_echo} will hide +@item void passphrase_disable_echo1(int fdin) +@itemx void passphrase_disable_echo(void) +Invoking @code{passphrase_disable_echo1} will hide the user input in the terminal (unless passphrase hiding is diabled). This is the first thing you -should call. - -@item char* passphrase_read(void) -@code{passphrase_read} reads the passphrase -from standard input. On error @code{NULL} +should call. @code{fdin} should be a file descriptor +to the terminal. One can be acquired by opening +@file{/dev/tty}. + +@code{passphrase_disable_echo} is deprecated +and is equivalent to +@code{passphrase_disable_echo1(STDIN_FILENO)}. + +@item char* passphrase_read2(int fdin, int flags) +@itemx char* passphrase_read(void) +@code{passphrase_read2} reads the passphrase +from the terminal. On error @code{NULL} will be returned, otherwise a NUL-terminated -passphrase will be returned. +passphrase will be returned. @code{fdin} should +be a file descriptor to the terminal. One can +be acquired by opening @file{/dev/tty}. When you are done with the returned passphrase you should wipe it and free it. -@item void passphrase_reenable_echo(void) +@code{passphrase_read} is deprecated +and is equivalent to +@code{passphrase_read2(STDIN_FILENO, 0)}. + +@item void passphrase_reenable_echo1(int fdin) +@itemx void passphrase_reenable_echo(void) When you have read the passphrase you should -invoke @code{passphrase_reenable_echo}. It will +invoke @code{passphrase_reenable_echo1}. It will revert all settings to the terminal made by -@code{passphrase_disable_echo}. If you have +@code{passphrase_disable_echo1}. If you have made settings changes to the terminal after -@code{passphrase_reenable_echo} but before -@code{passphrase_disable_echo}, those change -may be lost as @code{passphrase_disable_echo} +@code{passphrase_reenable_echo1} but before +@code{passphrase_disable_echo1}, those change +may be lost as @code{passphrase_disable_echo1} saves all settings before changing them and -@code{passphrase_reenable_echo} applies to -saved settings. +@code{passphrase_reenable_echo1} applies to +saved settings. @code{fdin} should be a file +descriptor to the terminal. + +@code{passphrase_reenable_echo} is deprecated +and is equivalent to +@code{passphrase_reenable_echo1(STDIN_FILENO)}. @item void passphrase_wipe(char*, size_t) When you are done using passhprase you should diff --git a/src/passphrase.c b/src/passphrase.c index b44542f..ec21aad 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -22,6 +22,7 @@ #include <unistd.h> #include <signal.h> +#define PASSPHRASE_USE_DEPRECATED #include "passphrase.h" #include "passphrase_helper.h" @@ -57,23 +58,31 @@ static char* xrealloc(char* array, size_t cur_size, size_t new_size) #endif /* !PASSPHRASE_REALLOC */ +static int fdgetc(int fd) +{ + unsigned char c; + if (read(fd, &c, sizeof(c)) <= 0) + return -1; + return (int)c; +} + #if defined(PASSPHRASE_DEDICATED) && defined(PASSPHRASE_MOVE) -static int get_dedicated_control_key(void) +static int get_dedicated_control_key(int fdin) { - int c = getchar(); + int c = fdgetc(fdin); if (c == 'O') { - c = getchar(); + c = fdgetc(fdin); if (c == 'H') return KEY_HOME; if (c == 'F') return KEY_END; } else if (c == '[') { - c = getchar(); + c = fdgetc(fdin); if (c == 'C') return KEY_RIGHT; if (c == 'D') return KEY_LEFT; - if (('1' <= c) && (c <= '4') && (getchar() == '~')) + if (('1' <= c) && (c <= '4') && (fdgetc(fdin) == '~')) return -(c - '0'); } return 0; @@ -83,13 +92,15 @@ static int get_dedicated_control_key(void) #ifdef PASSPHRASE_MOVE -static int get_key(int c) +static int get_key(int c, int fdin) { # ifdef PASSPHRASE_DEDICATED - if (c == '\033') return get_dedicated_control_key(); + if (c == '\033') return get_dedicated_control_key(fdin); +# else /* PASSPHRASE_DEDICATED */ + (void) fdin; # endif /* PASSPHRASE_DEDICATED */ if ((c == 8) || (c == 127)) return KEY_ERASE; - if ((c < 0) || (c >= ' ')) return ((int)c) & 255; + if ((c < 0) || (c >= ' ')) return c & 255; # ifdef PASSPHRASE_CONTROL if (c == 'A' - '@') return KEY_HOME; if (c == 'B' - '@') return KEY_LEFT; @@ -106,10 +117,23 @@ static int get_key(int c) /** * Reads the passphrase from stdin * - * @return The passphrase, should be wiped `free`:ed, `NULL` on error + * @return The passphrase, should be wiped and `free`:ed, `NULL` on error */ char* passphrase_read(void) { + return passphrase_read2(STDIN_FILENO, 0); +} + + +/** + * Reads the passphrase from stdin + * + * @param fdin File descriptor for input + * @param flags Settings + * @return The passphrase, should be wiped and `free`:ed, `NULL` on error + */ +char* passphrase_read2(int fdin, int flags) +{ char* rc = malloc(START_PASSPHRASE_LIMIT * sizeof(char)); size_t size = START_PASSPHRASE_LIMIT; size_t len = 0; @@ -127,6 +151,7 @@ char* passphrase_read(void) #ifdef PASSPHRASE_MOVE int cc; #endif + (void) flags; if (rc == NULL) return NULL; @@ -142,12 +167,12 @@ char* passphrase_read(void) that in X.org) and can be echoed into stdin by the kernel. */ for (;;) { - c = getchar(); + c = fdgetc(fdin); if ((c < 0) || (c == '\n')) break; if (c == 0) continue; #if defined(PASSPHRASE_MOVE) - cc = get_key(c); + cc = get_key(c, fdin); if (cc > 0) { c = (char)cc; @@ -266,35 +291,62 @@ void passphrase_wipe(volatile char* ptr, size_t n) *(ptr + i) = 0; } + /** * Disable echoing and do anything else to the terminal settnings `passphrase_read` requires */ void passphrase_disable_echo(void) { + passphrase_disable_echo1(STDIN_FILENO); +} + + +/** + * Undo the actions of `passphrase_disable_echo` + */ +void passphrase_reenable_echo(void) +{ + passphrase_reenable_echo1(STDIN_FILENO); +} + +/** + * Disable echoing and do anything else to the terminal settnings `passphrase_read2` requires + * + * @param fdin File descriptor for input + */ +void passphrase_disable_echo1(int fdin) +{ #if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE) struct termios stty; - tcgetattr(STDIN_FILENO, &stty); + tcgetattr(fdin, &stty); saved_stty = stty; stty.c_lflag &= (tcflag_t)~ECHO; # if defined(PASSPHRASE_STAR) || defined(PASSPHRASE_TEXT) || defined(PASSPHRASE_MOVE) stty.c_lflag &= (tcflag_t)~ICANON; # endif /* PASSPHRASE_STAR || PASSPHRASE_TEXT || PASSPHRASE_MOVE */ - tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); + tcsetattr(fdin, TCSAFLUSH, &stty); +#else /* !PASSPHRASE_ECHO || PASSPHRASE_MOVE */ + (void) fdin; #endif /* !PASSPHRASE_ECHO || PASSPHRASE_MOVE */ } /** - * Undo the actions of `passphrase_disable_echo` + * Undo the actions of `passphrase_disable_echo1` + * + * @param fdin File descriptor for input */ -void passphrase_reenable_echo(void) +void passphrase_reenable_echo1(int fdin) { #if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE) - tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty); + tcsetattr(fdin, TCSAFLUSH, &saved_stty); +#else /* !PASSPHRASE_ECHO || !PASSPHRASE_MOVE */ + (void) fdin; #endif /* !PASSPHRASE_ECHO || !PASSPHRASE_MOVE */ } + #ifdef __GNUC__ # pragma GCC diagnostic pop #endif diff --git a/src/passphrase.h b/src/passphrase.h index 85faffd..24d4aa4 100644 --- a/src/passphrase.h +++ b/src/passphrase.h @@ -19,13 +19,30 @@ #ifndef PASSPHRASE_H #define PASSPHRASE_H +#if defined(__GNUC__) && !defined(PASSPHRASE_USE_DEPRECATED) +# define PASSPHRASE_DEPRECATED(MSG) __attribute__((__deprecated__(MSG))) +#else +# define PASSPHRASE_DEPRECATED(MSG) /* ignore */ +#endif + + /** * Reads the passphrase from stdin * - * @return The passphrase, should be wiped `free`:ed, `NULL` on error + * @return The passphrase, should be wiped and `free`:ed, `NULL` on error */ -extern char* passphrase_read(void); +PASSPHRASE_DEPRECATED("Please use 'passphrase_read2' instead.") +char* passphrase_read(void); + +/** + * Reads the passphrase + * + * @param fdin File descriptor for input + * @param flags Settings + * @return The passphrase, should be wiped and `free`:ed, `NULL` on error + */ +char* passphrase_read2(int, int); /** * Forcable write NUL characters to a passphrase @@ -33,18 +50,37 @@ extern char* passphrase_read(void); * @param ptr The password to wipe * @param n The number of characters to wipe */ -extern void passphrase_wipe(volatile char*, size_t); +void passphrase_wipe(volatile char*, size_t); /** * Disable echoing and do anything else to the terminal settnings `passphrase_read` requires */ -extern void passphrase_disable_echo(void); +PASSPHRASE_DEPRECATED("Please use 'passphrase_disable_echo1' instead.") +void passphrase_disable_echo(void); /** * Undo the actions of `passphrase_disable_echo` */ -extern void passphrase_reenable_echo(void); +PASSPHRASE_DEPRECATED("Please use 'passphrase_reenable_echo1' instead.") +void passphrase_reenable_echo(void); + +/** + * Disable echoing and do anything else to the terminal settnings `passphrase_read2` requires + * + * @param fdin File descriptor for input + */ +void passphrase_disable_echo1(int); + +/** + * Undo the actions of `passphrase_disable_echo1` + * + * @param fdin File descriptor for input + */ +void passphrase_reenable_echo1(int); + + +#undef PASSPHRASE_DEPRECATED #endif @@ -33,14 +33,14 @@ int main(int argc, char** argv) char* passphrase_; /* Hide the passphrase */ - passphrase_disable_echo(); + passphrase_disable_echo1(0); /* Do things needed before reading the passphrase */ printf("Passphrase: "); fflush(stdout); /* Read the passphrase */ - passphrase = passphrase_read(); + passphrase = passphrase_read2(0, 0); if (passphrase == NULL) { /* Something went wrong, print what and exit */ @@ -58,7 +58,7 @@ int main(int argc, char** argv) free(passphrase_); /* Stop hiding user input */ - passphrase_reenable_echo(); + passphrase_reenable_echo1(0); /* End of program */ return 0; |