pinentry: Implementation Details

1 
1 4 Implementation Details
1 ************************
1 
1 The pinentry source code can be divided into three categories.  There is
1 a backend module, which lives in 'pinentry/', there are utility
1 functions, e.g., in 'secmem/', and there are various frontends.
1 
1    All of the low-level logic lives in the backend.  This frees the
1 frontends from having to implement, e.g., the Assuan protocol.  When the
1 backend receives an option, it updates the state in a 'pinentry_t'
1 struct.  The frontend is called when the client either calls 'GETPIN',
1 'CONFIRM' or 'MESSAGE'.  In these cases, the backend invokes the
1 'pinentry_cmd_handler', which is passed the 'pinentry_t' struct.
1 
1    When the callback is invoked, the frontend should create a window
1 based on the state in the 'pinentry_t' struct.  For instance, the title
1 to use for the dialog's window (if any) is stored in the 'title' field.
1 If the is 'NULL', the frontend should choose a reasonable default value.
1 (Default is not always provided, because different tool kits and
1 environments have different reasonable defaults.)
1 
1    The widget needs to support a number of different interactions with
1 the user.  Each of them is described below.
1 
1 'Passphrase Confirmation'
1 
1      When creating a new key, the passphrase should be entered twice.
1      The client (typically GPG Agent) indicates this to the PINENTRY by
1      invoking 'SETREPEAT'.  In this case, the backend sets the
1      'repeat_passphrase' field to a copy of the passed string.  The
1      value of this field should be used to label a second text input.
1 
1      It is the frontend's responsibility to check that the passwords
1      match.  If they don't match, the frontend should display an error
1      message and continue to prompt the user.
1 
1      If the passwords do match, then, when the user presses the okay
1      button, the 'repeat_okay' field should be set to '1' (this causes
1      the backend to emit the 'S PIN_REPEATED' status message).
1 
1 'Message Box'
1 
1      Sometimes GPG Agent needs to display a message.  In this case, the
1      'pin' variable is 'NULL'.
1 
1      At the Assuan level, this mode is selected by using either the
1      'MESSAGE' or the 'CONFIRM' command instead of the 'GETPIN' command.
1      The 'MESSAGE' command never shows the cancel or an other button.
1      The same holds for 'CONFIRM' if it was passed the "-one-button"
1      argument.  If 'CONFIRM' was not passed this argument, the dialog
1      for 'CONFIRM' should show both the 'ok' and the 'cancel' buttons
1      and optionally the 'notok' button.  The frontend can determine
1      whether the dialog is a one-button dialog by inspecting the
1      'one_button' variable.
1 
1 'Passphrase Entry'
1 
1      If neither of the above cases holds, then GPG Agent is simply
1      requesting the passphrase.  In this case, the 'ok' and 'cancel'
1      buttons should be displayed.
1 
1    The layout of the three variants is quite similar.  Here are the
1 relevant elements that describe the layout:
1 
1 'title'
1      The window's title.
1 
1 'description'
1      The reason for the dialog.  When requesting a passphrase, this
1      describes the key.  When showing a message box, this is the message
1      to show.
1 
1 'error'
1      If GPG Agent determines that the passphrase was incorrect, it will
1      call 'GETPIN' again (up to a configurable number of times) to again
1      prompt the user.  In this case, this variable contains a
1      description of the error message.  This text should typically be
1      highlighted in someway.
1 
1 'prompt, default-prompt'
1      The string to associate with the passphrase entry box.
1 
1      There is a subtle difference between 'prompt' and 'default-prompt'.
1      'default-prompt' means that a stylized prompt (e.g., an icon
1      suggesting a prompt) may be used.  'prompt' means that the entry's
1      meaning is not consistent with such a style and, as such, no icon
1      should be used.
1 
1      If both variables are set, the 'prompt' variant takes precedence.
1 
1 'repeat_passphrase'
1      The string to associate with the second passphrase entry box.  The
1      second passphrase entry box should only be shown if this is not
1      'NULL'.
1 
1 'ok, default-ok'
1      The string to show in the 'ok' button.
1 
1      If there are any '_' characters, the following character should be
1      used as an accelerator.  (A double underscore means a plain
1      underscore should be shown.)  If the frontend does not support
1      accelerators, then the underscores should be removed manually.
1 
1      There is a subtle difference between 'ok' and 'default-ok'.
1      'default-ok' means that a stylized OK button should be used.  For
1      instance, it could include a check mark.  'ok' means that the
1      button's meaning is not consistent with such an icon and, as such,
1      no icon should be used.  Thus, if the 'ok' button should have the
1      text "No password required" then 'ok' should be used because a
1      check mark icon doesn't make sense.
1 
1      If this variable is 'NULL', the frontend should choose a reasonable
1      default.
1 
1      If both variables are set, the 'ok' variant takes precedence.
1 
1 'cancel, default-cancel'
1      Like the 'ok' and 'default-ok' buttons except these strings are
1      used for the cancel button.
1 
1      This button should not be shown if 'one_button' is set.
1 
1      'default-notok' Like the 'default-ok' button except this string is
1      used for the other button.
1 
1      This button should only be displayed when showing a message box.
1      If these variables are 'NULL' or 'one_button' is set, this button
1      should not be displayed.
1 
1 'quality_bar'
1      If this is set, a widget should be used to show the password's
1      quality.  The value of this field is a label for the widget.
1 
1      Note: to update the password quality, whenever the password
1      changes, call the 'pinentry_inq_quality' function and then update
1      the password quality widget correspondingly.
1 
1 'quality_bar_tt'
1      A tooltip for the quality bar.
1 
1 'default_pwmngr'
1      If 'may_cache_password' and 'keyinfo' are set and the user
1      consents, then the PINENTRY may cache the password with an external
1      manager.  Note: getting the user's consent is essential, because
1      password managers often provide a different level of security.  If
1      the above condition is true and 'tried_password_cache' is false,
1      then a check box with the specified string should be displayed.
1      The check box must default to off.
1 
1 'default-cf-visi'
1      The string to show with a question if you want to confirm that the
1      user wants to change the visibility of the password.
1 
1 'default-tt-visi'
1      Tooltip for an action that would reveal the entered password.
1 
1 'default-tt-hide'
1      Tooltip for an action that would hide the password revealed by the
1      action labeld with 'default-tt-visi'
1 
1    When the handler is done, it should store the passphrase in 'pin', if
1 appropriate.  This variable is allocated in secure memory.  Use
1 'pinentry_setbufferlen' to size the buffer.
1 
1    The actual return code is dependent on whether the dialog is in
1 message mode or in passphrase mode.
1 
1    If the dialog is in message mode and the user pressed ok, return 1.
1 Otherwise, return 0.  If an error occurred, indicate this by setting it
1 in 'specific_err' or setting 'locale_err' to '1' (for locale specific
1 errors).  If the dialog was canceled, then the handler should set the
1 'canceled' variable to '1'.  If the not ok button was pressed, don't do
1 anything else.
1 
1    If the dialog is in passphrase mode return '1' if the user entered a
1 password and pressed ok.  If an error occurred, return '-1' and set
1 'specific_err' or 'locale_err', as above.  If the user canceled the
1 dialog box, return '-1'.
1 
1    If the window was closed, then the handler should set the
1 'close_button' variable and otherwise act as if the cancel button was
1 pressed.
1