aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-12-05 00:22:34 +0100
committerMattias Andrée <maandree@operamail.com>2015-12-05 00:22:34 +0100
commit18894103fcf337dfa672481ffc6b4906f340adff (patch)
treed703c56133818df28a6714db9128c647da1c1bc9
parentm (diff)
downloadlibpassphrase-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--Makefile4
-rw-r--r--info/libpassphrase.texinfo52
-rw-r--r--src/passphrase.c84
-rw-r--r--src/passphrase.h46
-rw-r--r--src/test.c6
5 files changed, 150 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 1ab3187..f91d104 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/src/test.c b/src/test.c
index 6aad5cf..e538316 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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;