1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Amend the agent code with more comments.

* agent/command.c (server_local_s): Remove unused field MESSAGE_FD.
This commit is contained in:
Werner Koch 2011-12-05 10:54:59 +01:00
parent 239659d3a0
commit 477360e8cd
3 changed files with 161 additions and 46 deletions

View File

@ -73,17 +73,20 @@ struct
/* True if we handle sigusr2. */ /* True if we handle sigusr2. */
int sigusr2_enabled; int sigusr2_enabled;
/* Environment setting gathered at program start or changed using the /* Environment settings gathered at program start or changed using the
Assuan command UPDATESTARTUPTTY. */ Assuan command UPDATESTARTUPTTY. */
session_env_t startup_env; session_env_t startup_env;
char *startup_lc_ctype; char *startup_lc_ctype;
char *startup_lc_messages; char *startup_lc_messages;
const char *pinentry_program; /* Filename of the program to start as /* Filename of the program to start as pinentry. */
pinentry. */ const char *pinentry_program;
const char *scdaemon_program; /* Filename of the program to handle
smartcard tasks. */ /* Filename of the program to handle smartcard tasks. */
const char *scdaemon_program;
int disable_scdaemon; /* Never use the SCdaemon. */ int disable_scdaemon; /* Never use the SCdaemon. */
int no_grab; /* Don't let the pinentry grab the keyboard */ int no_grab; /* Don't let the pinentry grab the keyboard */
/* The name of the file pinentry shall tocuh before exiting. If /* The name of the file pinentry shall tocuh before exiting. If
@ -98,31 +101,51 @@ struct
/* Flag disallowing bypassing of the warning. */ /* Flag disallowing bypassing of the warning. */
int enforce_passphrase_constraints; int enforce_passphrase_constraints;
/* The require minmum length of a passphrase. */ /* The require minmum length of a passphrase. */
unsigned int min_passphrase_len; unsigned int min_passphrase_len;
/* The minimum number of non-alpha characters in a passphrase. */ /* The minimum number of non-alpha characters in a passphrase. */
unsigned int min_passphrase_nonalpha; unsigned int min_passphrase_nonalpha;
/* File name with a patternfile or NULL if not enabled. */ /* File name with a patternfile or NULL if not enabled. */
const char *check_passphrase_pattern; const char *check_passphrase_pattern;
/* If not 0 the user is asked to change his passphrase after these /* If not 0 the user is asked to change his passphrase after these
number of days. */ number of days. */
unsigned int max_passphrase_days; unsigned int max_passphrase_days;
/* If set, a passphrase history will be written and checked at each /* If set, a passphrase history will be written and checked at each
passphrase change. */ passphrase change. */
int enable_passhrase_history; int enable_passhrase_history;
int running_detached; /* We are running detached from the tty. */ int running_detached; /* We are running detached from the tty. */
/* If this global option is true, the passphrase cache is ignored
for signing operations. */
int ignore_cache_for_signing; int ignore_cache_for_signing;
/* If this global option is true, the user is allowed to
interactively mark certificate in trustlist.txt as trusted. */
int allow_mark_trusted; int allow_mark_trusted;
/* If this global option is true, the Assuan command
PRESET_PASSPHRASE is allowed. */
int allow_preset_passphrase; int allow_preset_passphrase;
/* If this global option is true, the Assuan option
pinentry-mode=loopback is allowed. */
int allow_loopback_pinentry; int allow_loopback_pinentry;
int keep_tty; /* Don't switch the TTY (for pinentry) on request */ int keep_tty; /* Don't switch the TTY (for pinentry) on request */
int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */
int ssh_support; /* Enable ssh-agent emulation. */
/* This global option enables the ssh-agent subsystem. */
int ssh_support;
} opt; } opt;
/* Bit values for the --debug option. */
#define DBG_COMMAND_VALUE 1 /* debug commands i/o */ #define DBG_COMMAND_VALUE 1 /* debug commands i/o */
#define DBG_MPI_VALUE 2 /* debug mpi details */ #define DBG_MPI_VALUE 2 /* debug mpi details */
#define DBG_CRYPTO_VALUE 4 /* debug low level crypto */ #define DBG_CRYPTO_VALUE 4 /* debug low level crypto */
@ -130,8 +153,9 @@ struct
#define DBG_CACHE_VALUE 64 /* debug the caching */ #define DBG_CACHE_VALUE 64 /* debug the caching */
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ #define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
#define DBG_HASHING_VALUE 512 /* debug hashing operations */ #define DBG_HASHING_VALUE 512 /* debug hashing operations */
#define DBG_ASSUAN_VALUE 1024 #define DBG_ASSUAN_VALUE 1024 /* Enable Assuan debugging. */
/* Test macros for the debug option. */
#define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE) #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE)
#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) #define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE)
#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) #define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE)
@ -139,14 +163,18 @@ struct
#define DBG_HASHING (opt.debug & DBG_HASHING_VALUE) #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
#define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE) #define DBG_ASSUAN (opt.debug & DBG_ASSUAN_VALUE)
/* Forward reference for local definitions in command.c. */
struct server_local_s; struct server_local_s;
/* Forward reference for local definitions in call-scd.c. */
struct scd_local_s; struct scd_local_s;
/* Collection of data per session (aka connection). */ /* Collection of data per session (aka connection). */
struct server_control_s struct server_control_s
{ {
/* Private data used to fire up the connection thread. We use this /* Private data used to fire up the connection thread. We use this
structure do avoid an extra allocation for just a few bytes. */ structure do avoid an extra allocation for only a few bytes while
spawning a new connection thread. */
struct { struct {
gnupg_fd_t fd; gnupg_fd_t fd;
} thread_startup; } thread_startup;
@ -157,6 +185,7 @@ struct server_control_s
/* Private data of the SCdaemon (call-scd.c). */ /* Private data of the SCdaemon (call-scd.c). */
struct scd_local_s *scd_local; struct scd_local_s *scd_local;
/* Environment settings for the connection. */
session_env_t session_env; session_env_t session_env;
char *lc_ctype; char *lc_ctype;
char *lc_messages; char *lc_messages;
@ -177,37 +206,47 @@ struct server_control_s
unsigned char keygrip[20]; unsigned char keygrip[20];
int have_keygrip; int have_keygrip;
int use_auth_call; /* Hack to send the PKAUTH command instead of the /* A flag to enable a hack to send the PKAUTH command instead of the
PKSIGN command to the scdaemon. */ PKSIGN command to the scdaemon. */
int in_passwd; /* Hack to inhibit enforced passphrase change int use_auth_call;
during an explicit passwd command. */
unsigned long s2k_count; /* Other than the calibrated count. */ /* A flag to inhibit enforced passphrase change during an explicit
passwd command. */
int in_passwd;
/* The current S2K which might be different from the calibrated
count. */
unsigned long s2k_count;
}; };
/* Information pertaining to pinentry requests. */
struct pin_entry_info_s struct pin_entry_info_s
{ {
int min_digits; /* min. number of digits required or 0 for freeform entry */ int min_digits; /* min. number of digits required or 0 for freeform entry */
int max_digits; /* max. number of allowed digits allowed*/ int max_digits; /* max. number of allowed digits allowed*/
int max_tries; int max_tries; /* max. number of allowed tries. */
int failed_tries; int failed_tries; /* Number of tries so far failed. */
int with_qualitybar; /* Set if the quality bar should be displayed. */ int with_qualitybar; /* Set if the quality bar should be displayed. */
int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */
void *check_cb_arg; /* optional argument which might be of use in the CB */ void *check_cb_arg; /* optional argument which might be of use in the CB */
const char *cb_errtext; /* used by the cb to display a specific error */ const char *cb_errtext; /* used by the cb to display a specific error */
size_t max_length; /* allocated length of the buffer */ size_t max_length; /* Allocated length of the buffer PIN. */
char pin[1]; char pin[1]; /* The buffer to hold the PIN or passphrase.
It's actual allocated length is given by
MAX_LENGTH (above). */
}; };
/* Types of the private keys. */
enum enum
{ {
PRIVATE_KEY_UNKNOWN = 0, PRIVATE_KEY_UNKNOWN = 0, /* Type of key is not known. */
PRIVATE_KEY_CLEAR = 1, PRIVATE_KEY_CLEAR = 1, /* The key is not protected. */
PRIVATE_KEY_PROTECTED = 2, PRIVATE_KEY_PROTECTED = 2, /* The key is protected. */
PRIVATE_KEY_SHADOWED = 3, PRIVATE_KEY_SHADOWED = 3, /* The key is a stub for a smartcard
PROTECTED_SHARED_SECRET = 4 based key. */
PROTECTED_SHARED_SECRET = 4 /* RFU. */
}; };

View File

@ -50,31 +50,57 @@
/* The size of the import/export KEK key (in bytes). */ /* The size of the import/export KEK key (in bytes). */
#define KEYWRAP_KEYSIZE (128/8) #define KEYWRAP_KEYSIZE (128/8)
/* A shortcut to call assuan_set_error using an gpg_err_code_t and a
text string. */
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
/* Check that the maximum digest length we support has at least the
length of the keygrip. */
#if MAX_DIGEST_LEN < 20 #if MAX_DIGEST_LEN < 20
#error MAX_DIGEST_LEN shorter than keygrip #error MAX_DIGEST_LEN shorter than keygrip
#endif #endif
/* Data used to associate an Assuan context with local server data */ /* Data used to associate an Assuan context with local server data.
This is this modules local part of the server_control_s struct. */
struct server_local_s struct server_local_s
{ {
/* Our Assuan context. */
assuan_context_t assuan_ctx; assuan_context_t assuan_ctx;
int message_fd;
/* If this flag is true, the passphrase cache is used for signing
operations. It defaults to true but may be set on a per
connection base. The global option opt.ignore_cache_for_signing
takes precedence over this flag. */
int use_cache_for_signing; int use_cache_for_signing;
char *keydesc; /* Allocated description for the next key
operation. */ /* An allocated description for the next key operation. This is
int pause_io_logging; /* Used to suppress I/O logging during a command */ used if a pinnetry needs to be popped up. */
int stopme; /* If set to true the agent will be terminated after char *keydesc;
the end of this session. */
int allow_pinentry_notify; /* Set if pinentry notifications should /* Flags to suppress I/O logging during a command. */
be done. */ int pause_io_logging;
void *import_key; /* Malloced KEK for the import_key command. */
void *export_key; /* Malloced KEK for the export_key command. */ /* If this flags is set to true the agent will be terminated after
int allow_fully_canceled; /* Client is aware of GPG_ERR_FULLY_CANCELED. */ the end of the current session. */
char *last_cache_nonce; /* Last CACHE_NOCNE sent as status (malloced). */ int stopme;
char *last_passwd_nonce; /* Last PASSWD_NOCNE sent as status (malloced). */
/* Flag indicating whether pinentry notifications shall be done. */
int allow_pinentry_notify;
/* Malloced KEK (Key-Encryption-Key) for the import_key command. */
void *import_key;
/* Malloced KEK for the export_key command. */
void *export_key;
/* Client is aware of the error code GPG_ERR_FULLY_CANCELED. */
int allow_fully_canceled;
/* Last CACHE_NONCE sent as status (malloced). */
char *last_cache_nonce;
/* Last PASSWD_NONCE sent as status (malloced). */
char *last_passwd_nonce;
}; };
@ -156,6 +182,8 @@ write_and_clear_outbuf (assuan_context_t ctx, membuf_t *mb)
} }
/* Clear the nonces used to enable the passphrase cache for certain
multi-command command sequences. */
static void static void
clear_nonce_cache (ctrl_t ctrl) clear_nonce_cache (ctrl_t ctrl)
{ {
@ -176,6 +204,9 @@ clear_nonce_cache (ctrl_t ctrl)
} }
/* This function is called by Libassuan whenever thee client sends a
reset. It has been registered similar to the other Assuan
commands. */
static gpg_error_t static gpg_error_t
reset_notify (assuan_context_t ctx, char *line) reset_notify (assuan_context_t ctx, char *line)
{ {
@ -196,8 +227,13 @@ reset_notify (assuan_context_t ctx, char *line)
} }
/* Skip over options. /* Skip over options in LINE.
Blanks after the options are also removed. */
Blanks after the options are also removed. Options are indicated
by two leading dashes followed by a string consisting of non-space
characters. The special option "--" indicates an explicit end of
options; all what follows will not be considered an option. The
first no-option string also indicates the end of option parsing. */
static char * static char *
skip_options (const char *line) skip_options (const char *line)
{ {
@ -213,7 +249,11 @@ skip_options (const char *line)
return (char*)line; return (char*)line;
} }
/* Check whether the option NAME appears in LINE */
/* Check whether the option NAME appears in LINE. An example for a
line with options is:
--algo=42 --data foo bar
This function would then only return true if NAME is "data". */
static int static int
has_option (const char *line, const char *name) has_option (const char *line, const char *name)
{ {
@ -226,6 +266,7 @@ has_option (const char *line, const char *name)
return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n)));
} }
/* Same as has_option but does only test for the name of the option /* Same as has_option but does only test for the name of the option
and ignores an argument, i.e. with NAME being "--hash" it would and ignores an argument, i.e. with NAME being "--hash" it would
return true for "--hash" as well as for "--hash=foo". */ return true for "--hash" as well as for "--hash=foo". */
@ -242,8 +283,9 @@ has_option_name (const char *line, const char *name)
&& (!s[n] || spacep (s+n) || s[n] == '=')); && (!s[n] || spacep (s+n) || s[n] == '='));
} }
/* Return a pointer to the argument of the option with NAME. If such /* Return a pointer to the argument of the option with NAME. If such
an option is not given, it returns NULL. */ an option is not given, NULL is retruned. */
static char * static char *
option_value (const char *line, const char *name) option_value (const char *line, const char *name)
{ {
@ -265,7 +307,7 @@ option_value (const char *line, const char *name)
} }
/* Replace all '+' by a blank. */ /* Replace all '+' by a blank in the string S. */
static void static void
plus_to_blank (char *s) plus_to_blank (char *s)
{ {
@ -296,8 +338,9 @@ parse_hexstring (assuan_context_t ctx, const char *string, size_t *len)
return 0; return 0;
} }
/* Parse the keygrip in STRING into the provided buffer BUF. BUF must /* Parse the keygrip in STRING into the provided buffer BUF. BUF must
provide space for 20 bytes. BUF is not changed if the function provide space for 20 bytes. BUF is not changed if the function
returns an error. */ returns an error. */
static int static int
parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
@ -319,7 +362,11 @@ parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf)
} }
/* Write an assuan status line. */ /* Write an Assuan status line. KEYWORD is the first item on the
status line. The following arguments are all separated by a space
in the output. The last argument must be a NULL. Linefeeds and
carriage returns characters (which are not allowed in an Assuan
status line) are silently quoted in C-style. */
gpg_error_t gpg_error_t
agent_write_status (ctrl_t ctrl, const char *keyword, ...) agent_write_status (ctrl_t ctrl, const char *keyword, ...)
{ {
@ -463,6 +510,7 @@ bump_key_eventcounter (void)
eventcounter.any++; eventcounter.any++;
} }
/* This function should be called for all card reader status /* This function should be called for all card reader status
changes. This function is assured not to do any context changes. This function is assured not to do any context
switches. */ switches. */
@ -1069,6 +1117,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
} }
/* Entry int for the command KEYINFO. This function handles the
command option processing. For details see hlp_keyinfo above. */
static gpg_error_t static gpg_error_t
cmd_keyinfo (assuan_context_t ctx, char *line) cmd_keyinfo (assuan_context_t ctx, char *line)
{ {
@ -1140,6 +1190,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
/* Helper for cmd_get_passphrase. */
static int static int
send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw) send_back_passphrase (assuan_context_t ctx, int via_data, const char *pw)
{ {
@ -2415,6 +2466,8 @@ cmd_getinfo (assuan_context_t ctx, char *line)
/* This function is called by Libassuan to parse the OPTION command.
It has been registered similar to the other Assuan commands. */
static gpg_error_t static gpg_error_t
option_handler (assuan_context_t ctx, const char *key, const char *value) option_handler (assuan_context_t ctx, const char *key, const char *value)
{ {
@ -2574,7 +2627,8 @@ command_has_option (const char *cmd, const char *cmdopt)
} }
/* Tell the assuan library about our commands */ /* Tell Libassuan about our commands. Also register the other Assuan
handlers. */
static int static int
register_commands (assuan_context_t ctx) register_commands (assuan_context_t ctx)
{ {
@ -2733,6 +2787,8 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
} }
/* Helper for the pinentry loopback mode. It merely passes the
parameters on to the client. */
gpg_error_t gpg_error_t
pinentry_loopback(ctrl_t ctrl, const char *keyword, pinentry_loopback(ctrl_t ctrl, const char *keyword,
unsigned char **buffer, size_t *size, unsigned char **buffer, size_t *size,

View File

@ -309,6 +309,9 @@ static unsigned long pth_thread_id (void)
Functions. Functions.
*/ */
/* Allocate a string describing a library version by calling a GETFNC.
This function is expected to be called only once. GETFNC is
expected to have a semantic like gcry_check_version (). */
static char * static char *
make_libversion (const char *libname, const char *(*getfnc)(const char*)) make_libversion (const char *libname, const char *(*getfnc)(const char*))
{ {
@ -326,7 +329,9 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
return result; return result;
} }
/* Return strings describing this program. The case values are
described in common/argparse.c:strusage. The values here override
the default values given by strusage. */
static const char * static const char *
my_strusage (int level) my_strusage (int level)
{ {
@ -448,6 +453,9 @@ remove_socket (char *name)
} }
} }
/* Cleanup code for this program. This is either called has an atexit
handler or directly. */
static void static void
cleanup (void) cleanup (void)
{ {
@ -1268,6 +1276,8 @@ main (int argc, char **argv )
} }
/* Exit entry point. This function should be called instead of a
plain exit. */
void void
agent_exit (int rc) agent_exit (int rc)
{ {
@ -1294,6 +1304,11 @@ agent_exit (int rc)
} }
/* Each thread has its own local variables conveyed by a control
structure usually identified by an argument named CTRL. This
function is called immediately after allocating the control
structure. Its purpose is to setup the default values for that
structure. */
static void static void
agent_init_default_ctrl (ctrl_t ctrl) agent_init_default_ctrl (ctrl_t ctrl)
{ {
@ -1319,6 +1334,8 @@ agent_init_default_ctrl (ctrl_t ctrl)
} }
/* Release all resources allocated by default in the control
structure. This is the counterpart to agent_init_default_ctrl. */
static void static void
agent_deinit_default_ctrl (ctrl_t ctrl) agent_deinit_default_ctrl (ctrl_t ctrl)
{ {
@ -1720,6 +1737,7 @@ agent_sighup_action (void)
} }
/* A helper function to handle SIGUSR2. */
static void static void
agent_sigusr2_action (void) agent_sigusr2_action (void)
{ {
@ -1730,6 +1748,8 @@ agent_sigusr2_action (void)
} }
/* The signal handler for this program. It is expected to be run in
its own trhead and not in the context of a signal handler. */
static void static void
handle_signal (int signo) handle_signal (int signo)
{ {