\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename libpassphrase.info @settitle libpassphrase @afourpaper @documentencoding UTF-8 @documentlanguage en @finalout @c %**end of header @dircategory Library @direntry * libpassphrase: (libpassphrase). Personalisable terminal passphrase reading library @end direntry @copying Copyright @copyright{} 2013, 2014, 2015 Mattias Andrée @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @ifnottex @node Top @top libpassphrase -- Personalisable terminal passphrase reading library @insertcopying @end ifnottex @titlepage @title libpassphrase @subtitle Personalisable terminal passphrase reading library @author by Mattias Andrée (maandree) @page @vskip 0pt plus 1filll @insertcopying @end titlepage @contents @menu * Overview:: Brief overview of libpassphrase. * Application Programming Interface:: How to take advantage of libpassphrase in your application. * Configuring libpassphrase:: How to configure libpassphrase. * GNU Free Documentation License:: Copying and sharing this manual. @detailmenu --- The Detailed Node Listing --- Application Programming Interface * Example:: Example of how to use libpassphrase @end detailmenu @end menu @node Overview @chapter Overview libpassphrase is a small C library for reading passphrases from the terminal via the standard input channel. The purpose of libpassphrase is to provide a way to personalise the behaviour in the terminal when applications that takes advantage of libpassphrase reads a passphrase. Among other configurations, you can configure libpassphrase to print asterisks instead of disabling echoing. libpassphrase's advanced programming interface is very small and simple, if libpassphrase cannot do exactly what you want, you can either modify the source code to do what it you want or write your own replacement. @node Application Programming Interface @chapter Application Programming Interface @menu * Example:: Example of how to use libpassphrase @end menu To use libpassphrase, add the option @option{-lpassphrase} to the linker. In other words add @option{-lpassphrase} to the arguments when invoking GCC @footnote{Or your compile or choice.}, when it creates an executable file. libpassphrase should be dynamically linked as static linking would require recompilation of the program and not just libpassphrase to reconfigure libpassphrase. Include the system header file @file{passphrase.h}, in the file you want to use libpassphrase. @file{passphrase.h} uses the inclusion guard @code{__PASSPHRASE_H__}. Including @file{passphrase.h} gives you three functions: @table @code @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. @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. @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. @code{passphrase_read} is deprecated and is equivalent to @code{passphrase_read2(STDIN_FILENO, 0)}. @code{flags} is used to tweak the behaviour if the function. It should be a combination of the constants @table @code @item PASSPHRASE_READ_EXISTING @code{passphrase_read2} shall not do any thing special, just accept the passphrase. This should be used when getting authentication. Should not be combined with @code{PASSPHRASE_READ_NEW}. @item PASSPHRASE_READ_NEW @code{passphrase_read2} shall draw a pasphrase strength meter if such capability is available. This should be used when create a new passphrase. Should not be combined with @code{PASSPHRASE_READ_EXISTING}. @item PASSPHRASE_READ_SCREEN_FREE @code{passphrase_read2} may do as it please with the the screen. This is only used if combined with @code{PASSPHRASE_READ_NEW} and not with @code{PASSPHRASE_READ_BELOW_FREE}. @code{passphrase_read2} will create make a line below the new current line and use that line to draw the passphrase strength meter if such capability is available. The label for the passphrase strength meter can be modified by setting the environment variable @env{LIBPASSPHRASE_STRENGTH_LABEL}. @item PASSPHRASE_READ_BELOW_FREE @code{passphrase_read2} may do as it please with the line below the current line. This is only used if combined with @code{PASSPHRASE_READ_NEW}. @code{passphrase_read2} will draw the passphrase strength meter on the line below if such capability is available. @end table @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_echo1}. It will revert all settings to the terminal made by @code{passphrase_disable_echo1}. If you have made settings changes to the terminal after @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_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) @itemx void passphrase_wipe1(char*) When you are done using passhprase you should erase it from the memory before freeing its allocation. To do this securtly, call @code{passphrase_wipe} with the passphase as the first argument and the length of the passphrase as the second argument. @code{passphrase_wipe1} will determine the length of the passphrase by itself. @end table These three functions could be made into one function, it is however separated so that you can hide the passphrase earlier than you can read the passphrase, to minimise the risk that the user starts typing before the echoing has been disabled. @node Example @section Example @example #include /* For libpassphrase */ #include /* For output */ #include /* For free */ #include /* For open, O_RDONLY */ #include /* For close */ int main(int argc, char** argv) @{ /* Variables for the passphrase */ char* passphrase; /* Get file descriptor to the terminal */ int fd = open("/dev/tty", O_RDONLY); if (fd == -1) @{ perror(*argv); return 1; @} /* Hide the passphrase */ passphrase_disable_echo1(fd); /* Do things needed before reading the passphrase */ printf("Passphrase: "); fflush(stdout); /* Read the passphrase */ passphrase = passphrase_read2(fd, PASSPHRASE_READ_NEW | PASSPHRASE_READ_SCREEN_FREE); if (passphrase == NULL) @{ /* Something went wrong, print what and exit */ perror(*argv); passphrase_reenable_echo1(fd); close(fd); return 1; @} /* Use the passphrase */ printf("You entered: %s\n", passphrase); /* Wipe and free the passphrase */ passphrase_wipe1(passphrase); free(passphrase); /* Stop hiding user input */ passphrase_reenable_echo1(fd); /* End of program */ close(fd); return 0; /* `argc` was never used */ (void) argc; @} @end example @node Configuring libpassphrase @chapter Configuring libpassphrase libpassphrase is configured at compile time. Its makefile contains the variable @var{OPTIONS} which is composed of the definitions you want to add to the C preprocessor when compiling libpassphrase. The definitions are blank space separated, for example @command{make OPTIONS="PASSPHRASE_STAR PASSPHRASE_REALLOC"} will compile libpassphrase with the options @code{PASSPHRASE_STAR} and @code{PASSPHRASE_REALLOC}. The following options are defined: @table @asis @item @code{PASSPHRASE_ECHO} Do not hide the passphrase. @item @code{PASSPHRASE_STAR} @footnote{May not be combined with @code{PASSPHRASE_ECHO} or @code{PASSPHRASE_TEXT}.} Use `*' for each character instead of disabling echoing. @item @code{PASSPHRASE_TEXT} @footnote{May not be combined with @code{PASSPHRASE_STAR} or @code{PASSPHRASE_ECHO}.} Use the texts `(empty)' and `(not empty)' to describe whether anything has been entered or not the instead of disabling echoing. @item @code{PASSPHRASE_REALLOC} Soften security by using @code{realloc} instead of using @code{malloc} and wiping the passphrase from the old allocation after duplicating it. @item @code{PASSPHRASE_MOVE} Add the possibilty to move the point (cursor), even if the passphrase is hidden this is usable. If using this options you should use at least one of @code{PASSPHRASE_INSERT} and @code{PASSPHRASE_OVERRIDE}, and at least on of @code{PASSPHRASE_CONTROL} and @code{PASSPHRASE_DEDICATED}. Provided that all options that requires @code{PASSPHRASE_MOVE} are used, the following key combinations are recognised: @table @kbd @item @itemx C-b Move the point one step to the left. @item @itemx C-f Move the point one step to the right. @item @itemx C-a Move the point to the beginning of the passphrase. @item @itemx C-e Move the point to the end of the passphrase. @item backspace @itemx C-h Erase the letter before the point. @item @itemx C-d Reverse erase: erase the letter at the point. @item Switch between insert mode and override mode. @end table @item @code{PASSPHRASE_INSERT} @footnote{Requires @code{PASSPHRASE_MOVE}.} Enable insert mode. @item @code{PASSPHRASE_OVERRIDE} @footnote{Requires @code{PASSPHRASE_MOVE}.} Enable override mode. @item @code{PASSPHRASE_DELETE} @footnote{Requires @code{PASSPHRASE_MOVE}.} Enable reversed erase command. @item @code{PASSPHRASE_CONTROL} @footnote{Requires @code{PASSPHRASE_MOVE}.} Enable use of key combinations using the control modifier. @item @code{PASSPHRASE_DEDICATED} @footnote{Requires @code{PASSPHRASE_MOVE}.} Enable use of keys with specific purpose, such as the Delete key and the arrow keys. @item @code{DEFAULT_INSERT} @footnote{Requires @code{PASSPHRASE_INSERT} and @code{PASSPHRASE_OVERRIDE}.} Use insert mode and not override mode as default. It is toggleable with the Insert key if @code{PASSPHRASE_DEDICATED} is used. @item @code{PASSPHRASE_INVALID} Prevent duplication of non-initialised memory. Only allocated memory will be duplication, but at the end of the passphrase allocation non-initialised memory can be read. Adding @code{PASSPHRASE_INVALID} ensures that all read memory is initialised by NUL-terminating the passphrase before it is completed when it is possible that non-initialised memory is about to be read. This options is not really needed, but not using it means that you can get warnings in @command{valgrind}. @item @code{PASSPHRASE_METER} When the @code{PASSPHRASE_READ_METER} flag is used, and @code{PASSPHRASE_READ_SCREEN_FREE} or @code{PASSPHRASE_READ_BELOW_FREE}, use @command{passcheck} to evaluate the strength of the passphrase and display a passphrase strength meter. @command{passcheck} will be started by the real user, not the effective user, and the real group. It possibly to select another program than @command{passcheck} by specifying it setting the environment variable @env{LIBPASSPHRASE_METER}. @env{LIBPASSPHRASE_METER} will be treated as one argument. The selected program must behave similar to @command{passcheck}: for each line to stdin, it must print a non-negative int integer, optinally coloured with one signal escape sequence, followed by a new line or whitespace; the rest of the is ignored. The program must also accept the flag @code{-r}, telling it not to discard any input. @end table In addition, you may use the follow flags. @table @asis @item @code{PASSPHRASE_STAR_CHAR} The text to print instead of the character `*' when @code{PASSPHRASE_STAR} is used. For example, you may run @example make OPTIONS=PASSPHRASE_STAR \ PASSPHRASE_STAR_CHAR="#" @end example @item @code{PASSPHRASE_TEXT_EMPTY} The text to print instead of the `(empty)' when @code{PASSPHRASE_TEXT} is used. For example, you may run @example make OPTIONS=PASSPHRASE_TEXT \ PASSPHRASE_TEXT_EMPTY="there is nothing here" @end example @item @code{PASSPHRASE_TEXT_NOT_EMPTY} The text to print instead of the `(not empty)' when @code{PASSPHRASE_TEXT} is used. For example, you may run @example make OPTIONS=PASSPHRASE_TEXT \ PASSPHRASE_TEXT_NOT_EMPTY="there is something here" @end example @item @code{LIBPASSPHRASE_STRENGTH_LABEL} The text to print instead of the `Strength:' when @code{PASSPHRASE_METER} is used and a new passphrase is being entered. For example, you may run @example make OPTIONS=PASSPHRASE_METER \ LIBPASSPHRASE_STRENGTH_LABEL="Hope meter:" @end example @item @code{PASSPHRASE_STRENGTH_LIMITS_HEADER} A header file to include that defines the macro @code{LIST_PASSPHRASE_STRENGTH_LIMITS}. If used, this value should either be a system header file and enclosed in ASCII angle brackets, or a local header file relative to the @file{src/passphrase_helper.h} and enclosed in ASCII double quotes. The @code{LIST_PASSPHRASE_STRENGTH_LIMITS} should be define similar to @example #define LIST_PASSPHRASE_STRENGTH_LIMITS(V) \ X(V == 0, "1;31", "Well-known common password") \ X(V <= 150, "31", "Extremely week") \ X(V <= 200, "33", "Week") \ X(V <= 250, "32", "Good") \ X(V <= 350, "1;32", "Strong") \ X(1, "1;7;32", "Perfect") @end example The macro @code{X} is defined when the macro [@code{LIST_PASSPHRASE_STRENGTH_LIMITS}] is used. Its first argument should evalute to truth if @code{V} from @code{LIST_PASSPHRASE_STRENGTH_LIMITS} can be designed in the string in the third argument. It is important that it [the first argument] always evaluates to truth for the last expansion of the macro [@code{X}]. The second argument is the Select Graphic Rendition parameters --- semi-colon separate -- used to colour the description (the third argument). @end table @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texinfo @bye