aboutsummaryrefslogtreecommitdiffstats
path: root/src/passphrase_helper.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/passphrase_helper.h313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/passphrase_helper.h b/src/passphrase_helper.h
new file mode 100644
index 0000000..7ec57a8
--- /dev/null
+++ b/src/passphrase_helper.h
@@ -0,0 +1,313 @@
+/**
+ * libpassphrase – Personalisable library for TTY passphrase reading
+ *
+ * Copyright © 2013, 2014, 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef PASSPHRASE_HELPER_H
+#define PASSPHRASE_HELPER_H
+
+
+/* Fix conflicting configurations */
+#if defined(PASSPHRASE_TEXT) && defined(PASSPHRASE_STAR)
+# warning You cannot have both PASSPHRASE_TEXT and PASSPHRASE_STAR
+# undef PASSPHRASE_TEXT
+#endif
+
+
+/* Default texts */
+#ifndef PASSPHRASE_STAR_CHAR
+# define PASSPHRASE_STAR_CHAR "*" /* TODO document */
+#endif
+#ifndef PASSPHRASE_TEXT_EMPTY
+# define PASSPHRASE_TEXT_EMPTY "(empty)" /* TODO document */
+#endif
+#ifndef PASSPHRASE_TEXT_NOT_EMPTY
+# define PASSPHRASE_TEXT_NOT_EMPTY "(not empty)" /* TODO document */
+#endif
+
+
+
+/* Control keys. */
+
+/**
+ * Home-key.
+ * Character sequences: \e[1~ \eOH
+ * Control-key combination: ^A
+ */
+#define KEY_HOME -1
+
+/**
+ * Insert-key.
+ * Character sequences: \e[2~
+ */
+#define KEY_INSERT -2
+
+/**
+ * Delete-key.
+ * Character sequences: \e[3~
+ * Control-key combination: ^D
+ */
+#define KEY_DELETE -3
+
+/**
+ * End-key.
+ * Character sequences: \e[4~ \eOF
+ * Control-key combination: ^E
+ */
+#define KEY_END -4
+
+/**
+ * Erase-key, also known as backspace.
+ * Character sequences: \d8 \d127
+ */
+#define KEY_ERASE -5
+
+/**
+ * Right-key.
+ * Character sequences: \e[C
+ * Control-key combination: ^F
+ */
+#define KEY_RIGHT -6
+
+/**
+ * Left-key.
+ * Character sequences: \e[D
+ * Control-key combination: ^B
+ */
+#define KEY_LEFT -7
+
+
+
+/* Custom fflush and fprintf */
+#if defined(PASSPHRASE_STAR) || defined(PASSPHRASE_TEXT)
+# define xprintf(...) fprintf(stderr, __VA_ARGS__)
+# define xflush() fflush(stderr)
+#elif defined(PASSPHRASE_MOVE) && !defined(PASSPHRASE_ECHO)
+# define xprintf(...) ({ /* do nothing */ })
+# define xflush() ({ /* do nothing */ })
+#elif defined(PASSPHRASE_MOVE)
+# define xprintf(...) fprintf(stderr, __VA_ARGS__)
+# define xflush() fflush(stderr)
+#else
+# define xflush() fflush(stderr)
+#endif
+
+
+
+/* Custom putchar */
+#if defined(PASSPHRASE_STAR)
+# define xputchar(C) (((C & 0xC0) != 0x80) ? fprintf(stderr, "%s", PASSPHRASE_STAR_CHAR) : 0)
+#elif defined(PASSPHRASE_ECHO) && defined(PASSPHRASE_MOVE)
+# define xputchar(C) fputc(C, stderr)
+#else
+# define xputchar(C) ({ /* be silent */ })
+#endif
+
+
+
+/* Is insert active by default? */
+#if defined(PASSPHRASE_OVERRIDE) && defined(PASSPHRASE_INSERT)
+# if defined(DEFAULT_INSERT)
+# define DEFAULT_INSERT_VALUE 1
+# else
+# define DEFAULT_INSERT_VALUE 0
+# endif
+#endif
+
+
+
+/* PASSPHRASE_INVALID's affect */
+#if defined(PASSPHRASE_INVALID)
+# define null_terminate() (*(rc + len) = 0)
+#else
+# define null_terminate() ({ /* do nothing*/ })
+#endif
+
+
+
+/* Implementation of the right-key's action */
+#define move_right() \
+ ({ \
+ xprintf("\033[C"); \
+ do \
+ point++; \
+ while ((len != point) && ((*(rc + point) & 0xC0) == 0x80)); \
+ })
+
+
+/* Implementation of the left-key's action */
+#define move_left() \
+ ({ \
+ xprintf("\033[D"); \
+ point--; \
+ while (point && ((*(rc + point) & 0xC0) == 0x80)) \
+ point--; \
+ })
+
+
+/* Implementation of the home-key's action */
+#define move_home() \
+ ({ \
+ size_t n = 0; \
+ for (i = 0; i < point; i++) \
+ if ((*(rc + i) & 0xC0) != 0x80) \
+ n++; \
+ xprintf("\033[%zuD", n); \
+ point = 0; \
+ })
+
+
+/* Implementation of the end-key's action */
+#define move_end() \
+ ({ \
+ size_t n = 0; \
+ for (i = point; i < len; i++) \
+ if ((*(rc + i) & 0xC0) != 0x80) \
+ n++; \
+ xprintf("\033[%zuC", n); \
+ point = len; \
+ })
+
+
+/* Implementation of the delete-key's action upon the passphrase buffer */
+#define delete_next() \
+ ({ \
+ null_terminate(); \
+ do \
+ { \
+ for (i = point; i < len; i++) \
+ *(rc + i) = *(rc + i + 1); \
+ len--; \
+ } \
+ while ((len != point) && ((*(rc + point) & 0xC0) == 0x80)); \
+ })
+
+
+/* Implementation of the erase-key's action upon the passphrase buffer */
+#if defined(PASSPHRASE_MOVE)
+#define erase_prev() \
+ ({ \
+ char redo = 1; \
+ null_terminate(); \
+ while (redo) \
+ { \
+ redo = (*(rc + point - 1) & 0xC0) == 0x80; \
+ for (i = point; i < len; i++) \
+ *(rc + i - 1) = *(rc + i); \
+ if (point <= len) \
+ *(rc + len - 1) = *(rc + len); \
+ point--; \
+ len--; \
+ } \
+ })
+#else
+# define erase_prev() (*(rc + --len) = 0)
+#endif
+
+
+#if defined(PASSPHRASE_MOVE)
+# define append_char() (xputchar(c), *(rc + len++) = (char)c, point++)
+#elif defined(PASSPHRASE_TEXT)
+# define append_char() \
+ ({ \
+ if (len == 0) \
+ { \
+ xprintf("\e[K%s%zn", PASSPHRASE_TEXT_NOT_EMPTY, &printed_len); \
+ if (printed_len) \
+ xprintf("\e[%zuD", printed_len); \
+ } \
+ *(rc + len++) = (char)c; \
+ })
+#else
+# define append_char() (xputchar(c), *(rc + len++) = (char)c)
+#endif
+
+
+#define insert_char() \
+ ({ \
+ if ((c & 0xC0) != 0x80) \
+ xprintf("\033[@"); \
+ xputchar(c); \
+ for (i = len; i > point; i--) \
+ *(rc + i) = *(rc + i - 1); \
+ len++; \
+ *(rc + point++) = (char)c; \
+ })
+
+
+#define override_char() \
+ ({ \
+ size_t n = 1; \
+ char cn = (char)c; \
+ while ((*(rc + point + n) & 0xC0) == 0x80) \
+ n++; \
+ for (i = point + n; i < len; i++) \
+ *(rc + i - n) = *(rc + i); \
+ passphrase_wipe(rc + len - n, n); \
+ len -= n; \
+ n = 0; \
+ while (cn & 0x80) \
+ { \
+ cn = (char)(cn << 1); \
+ n++; \
+ } \
+ n = n ?: 1; \
+ if (len + n > size) \
+ { \
+ if ((rc = xrealloc(rc, size, size << 1L)) == NULL) \
+ return NULL; \
+ size <<= 1L; \
+ } \
+ len += n; \
+ for (i = len - 1; i > point + n; i--) \
+ *(rc + i) = *(rc + i - n); \
+ if (len - 1 >= point + n) \
+ *(rc + point + n) = *(rc + point); \
+ for (i = 0; i < n; i++) \
+ { \
+ if (i) \
+ c = getchar(); \
+ xputchar(c); \
+ *(rc + point++) = (char)c; \
+ } \
+ })
+
+
+/* Implementation of the delete-key's action upon the display */
+#if defined(PASSPHRASE_TEXT)
+# define print_erase() \
+ (len == 0 ? 0 : (xprintf("\e[K%s%zn", PASSPHRASE_TEXT_EMPTY, &printed_len), \
+ (printed_len ? xprintf("\e[%zuD", printed_len) : 0)))
+#else
+# define print_delete() xprintf("\033[P")
+#endif
+
+
+/* Implementation of the erase-key's action upon the display */
+#if defined(PASSPHRASE_TEXT)
+# define print_erase() \
+ (len == 0 ? 0 : (xprintf("\e[K%s%zn", PASSPHRASE_TEXT_EMPTY, &printed_len), \
+ (printed_len ? xprintf("\e[%zuD", printed_len) : 0)))
+#elif defined(PASSPHRASE_MOVE)
+# define print_erase() xprintf("\033[D\033[P")
+#elif defined(PASSPHRASE_STAR)
+# define print_erase() xprintf("\033[D \033[D")
+#endif
+
+
+
+#endif
+