1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
\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 <passphrase.h> /* For libpassphrase */
#include <stdio.h> /* For output */
#include <stdlib.h> /* For free */
#include <fcntl.h> /* For open, O_RDONLY */
#include <unistd.h> /* 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 <left>
@itemx C-b
Move the point one step to the left.
@item <right>
@itemx C-f
Move the point one step to the right.
@item <home>
@itemx C-a
Move the point to the beginning of the passphrase.
@item <end>
@itemx C-e
Move the point to the end of the passphrase.
@item backspace
@itemx C-h
Erase the letter before the point.
@item <delete>
@itemx C-d
Reverse erase: erase the letter at the point.
@item <insert>
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
|