1\input texinfo                      @c -*-texinfo-*-
2@c %**start of header
3@setfilename pinentry.info
4
5@include version.texi
6
7@macro copyrightnotice
8Copyright @copyright{} 2002, 2005, 2015 g10 Code GmbH
9@end macro
10@macro permissionnotice
11Permission is granted to copy, distribute and/or modify this document
12under the terms of the GNU General Public License as published by the
13Free Software Foundation; either version 2 of the License, or (at your
14option) any later version. The text of the license can be found in the
15section entitled ``Copying''.
16@end macro
17
18@macro pinentry
19@sc{pinentry}
20@end macro
21
22@settitle Using the PIN-Entry
23
24@c Create a separate index for command line options.
25@defcodeindex op
26@c Merge the standard indexes into a single one.
27@syncodeindex fn cp
28@syncodeindex vr cp
29@syncodeindex ky cp
30@syncodeindex pg cp
31@syncodeindex tp cp
32
33@c printing stuff taken from gcc.
34@macro gnupgtabopt{body}
35@code{\body\}
36@end macro
37@macro gnupgoptlist{body}
38@smallexample
39\body\
40@end smallexample
41@end macro
42@c Makeinfo handles the above macro OK, TeX needs manual line breaks;
43@c they get lost at some point in handling the macro.  But if @macro is
44@c used here rather than @alias, it produces double line breaks.
45@iftex
46@alias gol = *
47@end iftex
48@ifnottex
49@macro gol
50@end macro
51@end ifnottex
52
53
54@c %**end of header
55
56@ifnottex
57@dircategory GNU Utilities
58@direntry
59* pinentry: (pinentry).    Securely ask for a passphrase or PIN.
60@end direntry
61This file documents the use and the internals of the @pinentry{}.
62
63This is edition @value{EDITION}, last updated @value{UPDATED}, of
64@cite{The `PINEntry' Manual}, for version @value{VERSION}.
65@sp 1
66Published by g10 Code GmbH@*
67Hüttenstr. 61@*
6840699 Erkrath, Germany
69@sp 1
70@copyrightnotice{}
71@sp 1
72@permissionnotice{}
73@end ifnottex
74
75@setchapternewpage odd
76
77@titlepage
78@title Using the PIN-Entry
79@subtitle Version @value{VERSION}
80@subtitle @value{UPDATED}
81@author Werner Koch @code{(wk@@gnupg.org)}
82
83@page
84@vskip 0pt plus 1filll
85@copyrightnotice{}
86@sp 2
87@permissionnotice{}
88@end titlepage
89@summarycontents
90@contents
91@page
92
93
94@node Top
95@top Introduction
96@cindex introduction
97
98This manual documents how to use the @pinentry{} and its protocol.
99
100The @pinentry{} is a small GUI application used to enter PINs or
101passphrases. It is usually invoked by @sc{gpg-agent}
102(@pxref{Invoking GPG-AGENT, ,Invoking the gpg-agent, gnupg,
103    The `GNU Privacy Guard' Manual}, for details).
104
105@pinentry{} comes in several flavors to fit the look and feel of the
106used GUI toolkit: A @sc{GTK+} based one named @code{pinentry-gtk}; a
107@sc{Qt} based one named @code{pinentry-qt}; and, two non-graphical
108ones @code{pinentry-curses}, which uses curses, and
109@code{pinentry-tty}, which doesn't require anything more than a simple
110terminal.  Not all of them are necessarily available on your
111installation.  If curses is supported on your system, the GUI-based
112flavors fall back to curses when the @code{DISPLAY} variable is not
113set.
114
115
116@menu
117* Using pinentry::      How to use the beast.
118* Front ends::          Description and comparison of the front ends
119
120Developer information
121
122* Protocol::            The Assuan protocol description.
123* Implementation Details:: For those extending or writing a new pinentry.
124
125Miscellaneous
126
127* Copying::             GNU General Public License says
128                        how you can copy and share PIN-Entry
129                        as well as this manual.
130
131Indices
132
133* Option Index::        Index to command line options.
134* Index::	        Index of concepts and symbol names.
135@end menu
136
137@node Using pinentry
138@chapter How to use the @pinentry{}
139
140@c man begin DESCRIPTION
141
142You may run @pinentry{} directly from the command line and pass the
143commands according to the Assuan protocol via stdin/stdout.
144
145
146@c man end
147
148@c man begin OPTIONS
149
150Here is a list of options supported by all flavors of pinentry:
151
152@table @gnupgtabopt
153@item --version
154@opindex version
155Print the program version and licensing information.
156
157@item --help
158@opindex help
159Print a usage message summarizing the most useful command line options.
160
161@item --debug
162@itemx -d
163@opindex debug
164@opindex d
165Turn on some debugging.  Mostly useful for the maintainers.  Note that
166this may reveal sensitive information like the entered passphrase.
167
168@c @item --enhanced
169@c @itemx -e
170@c @opindex enhanced
171@c @opindex e
172@c Ask for timeouts and insurance, too.  Note that this is currently not
173@c fully supported.
174
175@item --no-global-grab
176@itemx -g
177@opindex no-global-grab
178@opindex g
179Grab the keyboard only when the window is focused.  Use this option if
180you are debugging software using the @pinentry{}; otherwise you may
181not be able to to access your X session anymore (unless you have other
182means to connect to the machine to kill the @pinentry{}).
183
184@item --parent-wid @var{n}
185@opindex parent-wid
186Use window ID @var{n} as the parent window for positioning the window.
187Note, that this is not fully supported by all flavors of @pinentry{}.
188
189@item --timeout @var{seconds}
190@opindex timeout
191Give up waiting for input from the user after the specified number of
192seconds and return an error. The error returned is the same as if the
193Cancel button was selected. To disable the timeout and wait
194indefinitely, set this to 0, which is the default.
195
196@item --display @var{string}
197@itemx --ttyname @var{string}
198@itemx --ttytype @var{string}
199@itemx --lc-ctype @var{string}
200@itemx --lc-messages @var{string}
201@opindex display
202@opindex ttyname
203@opindex ttytype
204@opindex lc-ctype
205@opindex lc-messa
206These options are used to pass localization information to
207@pinentry{}.  They are required because @pinentry{} is usually called
208by some background process which does not have any information about
209the locale and terminal to use.  It is also possible to pass these
210options using Assuan protocol options.
211@end table
212
213@node Front ends
214@chapter Front Ends
215
216There are several different flavors of @pinentry{}.  Concretely, there
217are Gtk+2, Qt@tie{}4, TQt, EFL, FLTK, Gnome@tie{}3, Emacs, curses and
218tty variants.  These different implementations provide higher levels
219of integration with a specific environment.  For instance, the
220Gnome@tie{}3 @pinentry{} uses Gnome@tie{}3 widgets to display the
221prompts.  For Gnome@tie{}3 users, this higher level of integration
222provides a more consistent aesthetic.  However, this comes at a cost.
223Because this @pinentry{} uses so many components, there is a larger
224chance of a failure.  In particular, there is a larger chance that the
225passphrase is saved in memory and that memory is exposed to an
226attacker (consider the OpenSSL Heartbeat vulnerability).
227
228To understand how many components touch the passphrase, consider again
229the Gnome@tie{}3 implementation.  When a user presses a button on the
230keyboard, the key is passed from the kernel to the X@tie{}server to
231the toolkit (Gtk+) and to the actual text entry widget.  Along the
232way, the key is saved in memory and processed.  In fact, the key
233presses are probably read using standard C library functions, which
234buffer the input.  None of this code is careful to make sure the
235contents of the memory are not leaked by keeping the data in unpagable
236memory and wiping it when the buffer is freed.  However, even if they
237did, there is still the problem that when a computer hibernates, the
238system writes unpagable memory to disk anyway.  Further, many
239installations are virtualized (e.g., running on Xen) and have little
240control over their actual environment.
241
242The curses variant uses a significant smaller software stack and the
243tty variant uses an even smaller one.  However, if they are run in an
244X@tie{}terminal, then a similar number of components are handling the
245passphrase as in the Gnome@tie{}3 case!  Thus, to be most secure, you
246need to direct GPG@tie{}Agent to use a fixed virtual console.  Since
247you need to remain logged in for GPG@tie{}Agent to use that console,
248you should run there and have @code{screen} or @code{tmux} lock the
249tty.
250
251The Emacs pinentry implementation interacts with a running Emacs
252session and directs the Emacs instance to display the passphrase
253prompt.  Since this doesn't work very well if there is no Emacs
254running, the generic @pinentry{} backend checks if a
255@pinentry{}-enabled Emacs should be used.  Specifically, it looks to
256see if the @code{INSIDE_EMACS} variable is set and then attempts to
257establish a connection to the specified address.  If this is the case,
258then instead of, e.g., @code{pinentry-gtk2} displaying a Gtk+2
259pinentry, it interacts with the Emacs session.  This functionality can
260be explicitly disabled by passing @code{--disable-inside-emacs} to
261@code{configure} when building @pinentry{}.
262
263Having Emacs get the passphrase is convenient, however, it is a
264significant security risk.  Emacs is a huge program, which doesn't
265provide any process isolation to speak of.  As such, having it handle
266the passphrase adds a huge chunk of code to the user's trusted computing
267base.  Because of this concern, Emacs doesn't enable this by default,
268unless the @code{allow-emacs-pinentry} option is explicitly set in his
269or her @code{.gnupg/gpg-agent.conf} file.
270
271Similar to the inside-emacs check, the @pinentry{} frontends check
272whether the @code{DISPLAY} variable is set and a working X server is
273available.  If this is not the case, then they fallback to the curses
274front end.  This can also be disabled by passing
275@code{--disable-fallback-curses} to @code{configure} at build time.
276
277@c
278@c  Assuan Protocol
279@c
280@node Protocol
281@chapter @pinentry{}'s Assuan Protocol
282
283The @pinentry{} should never service more than one connection at once.
284It is reasonable to exec the @pinentry{} prior to a request.
285
286The @pinentry{} does not need to stay in memory because the
287@sc{gpg-agent} has the ability to cache passphrases.  The usual way to
288run the @pinentry{} is by setting up a pipe (not a socket) and then
289fork/exec the @pinentry{}.  The communication is then done by means of
290the protocol described here until the client is satisfied with the
291result.
292
293Although it is called a @pinentry{}, it allows entering reasonably
294long strings (strings that are up to 2048 characters long are
295supported by every pinentry).  The client using the @pinentry{} has to
296check for correctness.
297
298Note that all strings are expected to be encoded as UTF-8; @pinentry{}
299takes care of converting it to the locally used codeset.  To include
300linefeeds or other special characters, you may percent-escape them
301(e.g., a line feed is encoded as @code{%0A}, the percent sign itself
302is encoded as @code{%25}, etc.).
303
304The following is a list of supported commands:
305
306@table @gnupgtabopt
307
308@item Set the timeout before returning an error
309@example
310  C: SETTIMEOUT 30
311  S: OK
312@end example
313
314@item Set the descriptive text to display
315@example
316  C: SETDESC Enter PIN for Richard Nixon <nobody@@trickydicky.gov>
317  S: OK
318@end example
319
320@item Set the prompt to show
321When asking for a PIN, set the text just before the widget for
322passphrase entry.
323@example
324  C: SETPROMPT PIN:
325  S: OK
326@end example
327
328You should use an underscore in the text only if you know that a
329modern version of pinentry is used.  Modern versions underline the
330next character after the underscore and use the first such underlined
331character as a keyboard accelerator.  Use a double underscore to
332escape an underscore.
333
334@item Set the window title
335This command may be used to change the default window title.  When
336using this feature you should take care that the window is still
337identifiable as the pinentry.
338@example
339  C: SETTITLE Tape Recorder Room
340  S: OK
341@end example
342
343@item Set the button texts
344There are three texts which should be used to override the English
345defaults:
346
347To set the text for the button signaling confirmation (in UTF-8).
348See SETPROMPT on how to use an keyboard accelerator.
349@example
350  C: SETOK Yes
351  S: OK
352@end example
353
354
355To set the text for the button signaling cancellation or disagreement
356(in UTF-8).  See SETPROMPT on how to use an keyboard accelerator.
357@example
358  C: SETCANCEL No
359  S: OK
360@end example
361
362
363In case three buttons are required, use the following command to set
364the text (UTF-8) for the non-affirmative response button.  The
365affirmative button text is still set using SETOK and the CANCEL button
366text with SETCANCEL.  See SETPROMPT on how to use an keyboard
367accelerator.
368@example
369  C: SETNOTOK Do not do this
370  S: OK
371@end example
372
373
374
375@item Set the Error text
376This is used by the client to display an error message.  In contrast
377to the other commands, the error message is automatically reset with
378a GETPIN or CONFIRM, and is only displayed when asking for a PIN.
379@example
380  C: SETERROR Invalid PIN entered - please try again
381  S: OK
382@end example
383
384@item Enable a passphrase quality indicator
385Adds a quality indicator to the GETPIN window.  This indicator is
386updated as the passphrase is typed.  The clients needs to implement an
387inquiry named "QUALITY" which gets passed the current passphrase
388(percent-plus escaped) and should send back a string with a single
389numerical value between -100 and 100.  Negative values will be
390displayed in red.
391@example
392  C: SETQUALITYBAR
393  S: OK
394@end example
395
396If a custom label for the quality bar is required, just add that label
397as an argument as a percent-escaped string.  You will need this
398feature to translate the label because @pinentry{} has no internal
399gettext except for stock strings from the toolkit library.
400
401If you want to show a tooltip for the quality bar, you may use
402@example
403  C: SETQUALITYBAR_TT string
404  S: OK
405@end example
406
407@noindent
408With STRING being a percent escaped string shown as the tooltip.
409
410
411@item Ask for a PIN
412The meat of this tool is to ask for a passphrase of PIN, it is done with
413this command:
414@example
415  C: GETPIN
416  S: D no more tapes
417  S: OK
418@end example
419Note that the passphrase is transmitted in clear using standard data
420responses.  Expect it to be in UTF-8.
421
422@item Ask for confirmation
423To ask for a confirmation (yes or no), you can use this command:
424@example
425  C: CONFIRM
426  S: OK
427@end example
428The client should use SETDESC to set an appropriate text before
429issuing this command, and may use SETPROMPT to set the button texts.
430The value returned is either OK for YES or the error code
431@code{ASSUAN_Not_Confirmed}.
432
433@item Show a message
434To show a message, you can use this command:
435@example
436  C: MESSAGE
437  S: OK
438@end example
439alternatively you may add an option to confirm:
440@example
441  C: CONFIRM --one-button
442  S: OK
443@end example
444The client should use SETDESC to set an appropriate text before issuing
445this command, and may use SETOK to set the text for the dismiss button.
446The value returned is OK or an error message.
447
448@item Set the output device
449When using X, the @pinentry{} program must be invoked with an
450appropriate @code{DISPLAY} environment variable or the
451@code{--display} option.
452
453When using a text terminal:
454@example
455  C: OPTION ttyname=/dev/tty3
456  S: OK
457  C: OPTION ttytype=vt100
458  S: OK
459  C: OPTION lc-ctype=de_DE.UTF-8
460  S: OK
461@end example
462The client should use the @code{ttyname} option to set the output TTY
463file name, the @code{ttytype} option to the @code{TERM} variable
464appropriate for this tty and @code{lc-ctype} to the locale which
465defines the character set to use for this terminal.
466
467@item Set the default strings
468To avoid having translations in Pinentry proper, the caller may set
469certain translated strings which are used by @pinentry{} as default
470strings.
471
472@example
473  C: OPTION default-ok=_Korrekt
474  S: OK
475  C: OPTION default-cancel=Abbruch
476  S: OK
477  C: OPTION default-prompt=PIN eingeben:
478  S: OK
479@end example
480The strings are subject to accelerator marking, see SETPROMPT for
481details.
482
483@item Passphrase caching
484
485Some environments, such as GNOME, cache passwords and passphrases.
486The @pinentry{} should only use an external cache if the
487@code{allow-external-password-cache} option was set and a stable key
488identifier (using SETKEYINFO) was provided.  In this case, if the
489passphrase was read from the cache, the @pinentry{} should send the
490@code{PASSWORD_FROM_CACHE} status message before returning the
491passphrase.  This indicates to GPG Agent that it should not increment
492the passphrase retry counter.
493
494@example
495  C: OPTION allow-external-password-cache
496  S: OK
497  C: SETKEYINFO key-grip
498  S: OK
499  C: getpin
500  S: S PASSWORD_FROM_CACHE
501  S: D 1234
502  S: OK
503@end example
504
505Note: if @code{allow-external-password-cache} is not specified, an
506external password cache must not be used: this can lead to subtle
507bugs.  In particular, if this option is not specified, then GPG Agent
508does not recognize the @code{PASSWORD_FROM_CACHE} status message and
509will count trying a cached password against the password retry count.
510If the password retry count is 1, then the user will never have the
511opportunity to correct the cached password.
512
513Note: it is strongly recommended that a pinentry supporting this
514feature provide the user an option to enable it manually.  That is,
515saving a passphrase in an external password manager should be opt-in.
516
517The key identifier provided SETKEYINFO must be considered opaque and
518may change in the future.  It currently has the form
519@code{X/HEXSTRING} where @code{X} is either @code{n}, @code{s}, or
520@code{u}.  In the former two cases, the HEXSTRING corresponds to the
521key grip.  The key grip is not the OpenPGP Key ID, but it can be
522mapped to the key using the following:
523
524@example
525  # gpg2 --with-keygrip --list-secret-keys
526@end example
527
528@noindent
529and searching the output for the key grip.  The same command-line
530options can also be used with gpgsm.
531
532@end table
533
534@node Implementation Details
535@chapter Implementation Details
536
537The pinentry source code can be divided into three categories.  There
538is a backend module, which lives in @code{pinentry/}, there are
539utility functions, e.g., in @code{secmem/}, and there are various
540frontends.
541
542All of the low-level logic lives in the backend.  This frees the
543frontends from having to implement, e.g., the Assuan protocol.  When
544the backend receives an option, it updates the state in a
545@code{pinentry_t} struct.  The frontend is called when the client
546either calls @code{GETPIN}, @code{CONFIRM} or @code{MESSAGE}.  In
547these cases, the backend invokes the @code{pinentry_cmd_handler},
548which is passed the @code{pinentry_t} struct.
549
550When the callback is invoked, the frontend should create a window
551based on the state in the @code{pinentry_t} struct.  For instance, the
552title to use for the dialog's window (if any) is stored in the
553@code{title} field.  If the is @code{NULL}, the frontend should choose
554a reasonable default value.  (Default is not always provided, because
555different tool kits and environments have different reasonable
556defaults.)
557
558The widget needs to support a number of different interactions with
559the user.  Each of them is described below.
560
561@table @gnupgtabopt
562@item Passphrase Confirmation
563
564When creating a new key, the passphrase should be entered twice.  The
565client (typically GPG Agent) indicates this to the @pinentry{} by
566invoking @code{SETREPEAT}.  In this case, the backend sets the
567@code{repeat_passphrase} field to a copy of the passed string.  The
568value of this field should be used to label a second text input.
569
570It is the frontend's responsibility to check that the passwords match.
571If they don't match, the frontend should display an error message and
572continue to prompt the user.
573
574If the passwords do match, then, when the user presses the okay
575button, the @code{repeat_okay} field should be set to @code{1} (this
576causes the backend to emit the @code{S PIN_REPEATED} status message).
577
578@item Message Box
579
580Sometimes GPG Agent needs to display a message.  In this case, the
581@code{pin} variable is @code{NULL}.
582
583At the Assuan level, this mode is selected by using either the
584@code{MESSAGE} or the @code{CONFIRM} command instead of the
585@code{GETPIN} command.  The @code{MESSAGE} command never shows the
586cancel or an other button.  The same holds for @code{CONFIRM} if it
587was passed the ``--one-button'' argument.  If @code{CONFIRM} was not
588passed this argument, the dialog for @code{CONFIRM} should show both
589the @code{ok} and the @code{cancel} buttons and optionally the
590@code{notok} button.  The frontend can determine whether the dialog is
591a one-button dialog by inspecting the @code{one_button} variable.
592
593@item Passphrase Entry
594
595If neither of the above cases holds, then GPG Agent is simply
596requesting the passphrase.  In this case, the @code{ok} and
597@code{cancel} buttons should be displayed.
598
599@end table
600
601The layout of the three variants is quite similar.  Here are the
602relevant elements that describe the layout:
603
604@table @gnupgtabopt
605@item @code{title}
606The window's title.
607
608@item @code{description}
609The reason for the dialog.  When requesting a passphrase, this
610describes the key.  When showing a message box, this is the message to
611show.
612
613@item @code{error}
614If GPG Agent determines that the passphrase was incorrect, it will
615call @code{GETPIN} again (up to a configurable number of times) to
616again prompt the user.  In this case, this variable contains a
617description of the error message.  This text should typically be
618highlighted in someway.
619
620@item @code{prompt}, @code{default-prompt}
621The string to associate with the passphrase entry box.
622
623There is a subtle difference between @code{prompt} and
624@code{default-prompt}.  @code{default-prompt} means that a stylized
625prompt (e.g., an icon suggesting a prompt) may be used.  @code{prompt}
626means that the entry's meaning is not consistent with such a style
627and, as such, no icon should be used.
628
629If both variables are set, the @code{prompt} variant takes precedence.
630
631@item @code{repeat_passphrase}
632The string to associate with the second passphrase entry box.  The
633second passphrase entry box should only be shown if this is not
634@code{NULL}.
635
636@item @code{ok}, @code{default-ok}
637The string to show in the @code{ok} button.
638
639If there are any @code{_} characters, the following character should
640be used as an accelerator.  (A double underscore means a plain
641underscore should be shown.)  If the frontend does not support
642accelerators, then the underscores should be removed manually.
643
644There is a subtle difference between @code{ok} and @code{default-ok}.
645@code{default-ok} means that a stylized OK button should be used.  For
646instance, it could include a check mark.  @code{ok} means that the
647button's meaning is not consistent with such an icon and, as such, no
648icon should be used.  Thus, if the @code{ok} button should have the
649text ``No password required'' then @code{ok} should be used because a
650check mark icon doesn't make sense.
651
652If this variable is @code{NULL}, the frontend should choose a
653reasonable default.
654
655If both variables are set, the @code{ok} variant takes precedence.
656
657@item @code{cancel}, @code{default-cancel}
658Like the @code{ok} and @code{default-ok} buttons except these strings
659are used for the cancel button.
660
661This button should not be shown if @code{one_button} is set.
662
663@code{default-notok}
664Like the @code{default-ok} button except this string is used for the
665other button.
666
667This button should only be displayed when showing a message box.  If
668these variables are @code{NULL} or @code{one_button} is set, this
669button should not be displayed.
670
671@item @code{quality_bar}
672If this is set, a widget should be used to show the password's
673quality.  The value of this field is a label for the widget.
674
675Note: to update the password quality, whenever the password changes,
676call the @code{pinentry_inq_quality} function and then update the
677password quality widget correspondingly.
678
679@item @code{quality_bar_tt}
680A tooltip for the quality bar.
681
682@item @code{default_pwmngr}
683If @code{may_cache_password} and @code{keyinfo} are set and the user
684consents, then the @pinentry{} may cache the password with an external
685manager.  Note: getting the user's consent is essential, because
686password managers often provide a different level of security.  If the
687above condition is true and @code{tried_password_cache} is false, then
688a check box with the specified string should be displayed.  The check
689box must default to off.
690
691@item @code{default-cf-visi}
692The string to show with a question if you want to confirm that
693the user wants to change the visibility of the password.
694
695@item @code{default-tt-visi}
696Tooltip for an action that would reveal the entered password.
697
698@item @code{default-tt-hide}
699Tooltip for an action that would hide the password revealed
700by the action labeld with @code{default-tt-visi}
701
702@end table
703
704When the handler is done, it should store the passphrase in
705@code{pin}, if appropriate.  This variable is allocated in secure
706memory.  Use @code{pinentry_setbufferlen} to size the buffer.
707
708The actual return code is dependent on whether the dialog is in
709message mode or in passphrase mode.
710
711If the dialog is in message mode and the user pressed ok, return 1.
712Otherwise, return 0.  If an error occurred, indicate this by setting it
713in @code{specific_err} or setting @code{locale_err} to @code{1} (for
714locale specific errors).  If the dialog was canceled, then the handler
715should set the @code{canceled} variable to @code{1}.  If the not ok
716button was pressed, don't do anything else.
717
718If the dialog is in passphrase mode return @code{1} if the user
719entered a password and pressed ok.  If an error occurred, return
720@code{-1} and set @code{specific_err} or @code{locale_err}, as above.
721If the user canceled the dialog box, return @code{-1}.
722
723If the window was closed, then the handler should set the
724@code{close_button} variable and otherwise act as if the cancel button
725was pressed.
726
727
728
729@c ---------------------------------------------------------------------
730@c Legal Blurbs
731@c ---------------------------------------------------------------------
732
733@include gpl.texi
734
735@c ---------------------------------------------------------------------
736@c Indexes
737@c ---------------------------------------------------------------------
738
739@node Option Index
740@unnumbered Option Index
741
742@printindex op
743
744@node Index
745@unnumbered Index
746
747@printindex cp
748
749@c ---------------------------------------------------------------------
750@c Epilogue
751@c ---------------------------------------------------------------------
752
753@bye
754