diff --git a/NEWS b/NEWS index b2639710b..96c0fd391 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ Noteworthy changes in version 2.0.9 (unreleased) ------------------------------------------------ + * Gpgsm always tries to locate missing certificates from a running + Dirmngr's cache. + Noteworthy changes in version 2.0.8 (2007-12-20) ------------------------------------------------ diff --git a/common/ChangeLog b/common/ChangeLog index c01ab4307..f8b2858e5 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2008-01-31 Werner Koch + + * audit.c (audit_print_result): Make sure that the output is + always UTF8. + 2008-01-27 Werner Koch * exechelp.c (gnupg_spawn_process): Add arg FLAGS and changed all diff --git a/common/audit.c b/common/audit.c index 59f881cd5..706012ebe 100644 --- a/common/audit.c +++ b/common/audit.c @@ -938,10 +938,13 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html) helptag_t helptag; const char *s; int show_raw = 0; + char *orig_codeset; if (!ctx) return; + orig_codeset = i18n_switchto_utf8 (); + /* We use an environment variable to include some debug info in the log. */ if ((s = getenv ("gnupg_debug_audit"))) @@ -1090,5 +1093,6 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html) ctx->outstream = NULL; ctx->use_html = 0; clear_helptags (ctx); + i18n_switchback (orig_codeset); } diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index aa5d14187..39f5fadf3 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -1182,6 +1182,8 @@ The value of @var{what} specifies the kind of information returned: @table @code @item version Return the version of the program. +@item pid +Return the process id of the process. @item socket_name Return the name of the socket used to connect the agent. @item ssh_socket_name diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 3a831a671..d936b3eb2 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -928,6 +928,7 @@ Assuan manual for details. * GPGSM EXPORT:: Export certificates. * GPGSM IMPORT:: Import certificates. * GPGSM DELETE:: Delete certificates. +* GPGSM GETINFO:: Information about the process @end menu @@ -1197,7 +1198,7 @@ import private keys; a helper program is used for that. @node GPGSM DELETE @subsection Delete certificates -To delete certificate the command +To delete a certificate the command @example DELKEYS @var{pattern} @@ -1210,6 +1211,22 @@ this requires that the usual escape quoting rules are done. The certificates must be specified unambiguously otherwise an error is returned. +@node GPGSM GETINFO +@subsection Return information about the process + +This is a multipurpose function to return a variety of information. + +@example +GETINFO @var{what} +@end example + +The value of @var{what} specifies the kind of information returned: +@table @code +@item version +Return the version of the program. +@item pid +Return the process id of the process. +@end table @mansect see also @ifset isman diff --git a/g10/ChangeLog b/g10/ChangeLog index 3492023fe..5659db147 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2008-02-11 Werner Koch + + * server.c (cmd_getinfo): New. + (register_commands): Register GETINFO. + 2008-02-09 Marcus Brinkmann * gpg.c (main): New variable default_configname. Use it if diff --git a/g10/server.c b/g10/server.c index 7e783e51e..6ca7dfa8b 100644 --- a/g10/server.c +++ b/g10/server.c @@ -1,5 +1,5 @@ /* server.c - server mode for gpg - * Copyright (C) 2006 Free Software Foundation, Inc. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -386,7 +386,36 @@ cmd_genkey (assuan_context_t ctx, char *line) } +/* GETINFO + Multipurpose function to return a variety of information. + Supported values for WHAT are: + + version - Return the version of the program. + pid - Return the process id of the server. + + */ +static int +cmd_getinfo (assuan_context_t ctx, char *line) +{ + int rc; + + if (!strcmp (line, "version")) + { + const char *s = VERSION; + rc = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "pid")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else + rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + return rc; +} @@ -414,6 +443,7 @@ register_commands (assuan_context_t ctx) { "LISTSECRETKEYS",cmd_listsecretkeys }, { "GENKEY", cmd_genkey }, { "DELKEYS", cmd_delkeys }, + { "GETINFO", cmd_getinfo }, { NULL } }; int i, rc; diff --git a/sm/ChangeLog b/sm/ChangeLog index dcbbff3cf..2ba2ee3b2 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,20 @@ +2008-02-13 Werner Koch + + * call-dirmngr.c (gpgsm_dirmngr_lookup): Add arg CACHE_ONLY. + * keylist.c (list_external_keys): Pass false for new arg. + * certchain.c (find_up_dirmngr): New. + (find_up): Also try to read from the dirmngr cache. + (find_up, find_up_external, gpgsm_walk_cert_chain) + (gpgsm_basic_cert_check, allowed_ca): Add arg CTRL and changed all + callers. + * call-agent.c (struct learn_parm_s): Add field CTRL. + (gpgsm_agent_learn): Set it. + +2008-02-11 Werner Koch + + * server.c (cmd_getinfo): New. + (gpgsm_server): Register GETINFO. + 2008-01-29 Marcus Brinkmann * keylist.c (list_internal_keys): New variable lastcert. Use it @@ -35,7 +52,7 @@ 2007-12-03 Werner Koch - * gpgsm.c (main): All gnupg_reopen_std. + * gpgsm.c (main): Call gnupg_reopen_std. h2007-11-22 Werner Koch diff --git a/sm/call-agent.c b/sm/call-agent.c index af35ac53a..e0461d95f 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -59,6 +59,7 @@ struct genkey_parm_s struct learn_parm_s { int error; + ctrl_t ctrl; assuan_context_t ctx; membuf_t *data; }; @@ -638,7 +639,7 @@ learn_cb (void *opaque, const void *buffer, size_t length) return 0; } - rc = gpgsm_basic_cert_check (cert); + rc = gpgsm_basic_cert_check (parm->ctrl, cert); if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT) { /* For later use we store it in the ephemeral database. */ log_info ("issuer certificate missing - storing as ephemeral\n"); @@ -679,6 +680,7 @@ gpgsm_agent_learn (ctrl_t ctrl) init_membuf (&data, 4096); learn_parm.error = 0; + learn_parm.ctrl = ctrl; learn_parm.ctx = agent_ctx; learn_parm.data = &data; rc = assuan_transact (agent_ctx, "LEARN --send", diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index a4b6fbca7..83b001b52 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -1,5 +1,5 @@ /* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -704,9 +704,10 @@ lookup_status_cb (void *opaque, const char *line) /* Run the Directroy Managers lookup command using the pattern compiled from the strings given in NAMES. The caller must provide the callback CB which will be passed cert by cert. Note that CTRL - is optional. */ + is optional. With CACHE_ONLY the dirmngr will search only its own + key cache. */ int -gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, +gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only, void (*cb)(void*, ksba_cert_t), void *cb_value) { int rc; @@ -722,7 +723,8 @@ gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, pattern = pattern_from_strlist (names); if (!pattern) return out_of_core (); - snprintf (line, DIM(line)-1, "LOOKUP %s", pattern); + snprintf (line, DIM(line)-1, "LOOKUP%s %s", + cache_only? " --cache-only":"", pattern); line[DIM(line)-1] = 0; xfree (pattern); diff --git a/sm/certchain.c b/sm/certchain.c index a21a38a07..04b7e05ff 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -60,7 +60,7 @@ struct chain_item_s typedef struct chain_item_s *chain_item_t; -static int get_regtp_ca_info (ksba_cert_t cert, int *chainlen); +static int get_regtp_ca_info (ctrl_t ctrl, ksba_cert_t cert, int *chainlen); /* This function returns true if we already asked during this session @@ -259,7 +259,8 @@ unknown_criticals (ksba_cert_t cert, int listmode, estream_t fp) BasicConstraints extension. The function returns 0 on success and the awlloed length of the chain at CHAINLEN. */ static int -allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, estream_t fp) +allowed_ca (ctrl_t ctrl, + ksba_cert_t cert, int *chainlen, int listmode, estream_t fp) { gpg_error_t err; int flag; @@ -269,7 +270,7 @@ allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, estream_t fp) return err; if (!flag) { - if (get_regtp_ca_info (cert, chainlen)) + if (get_regtp_ca_info (ctrl, cert, chainlen)) { /* Note that dirmngr takes a different way to cope with such certs. */ @@ -417,7 +418,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist) /* Helper function for find_up. This resets the key handle and search for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns - 0 obn success or -1 when not found. */ + 0 on success or -1 when not found. */ static int find_up_search_by_keyid (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) @@ -464,9 +465,10 @@ find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) external lookup. KH is the keydb context we are currently using. On success 0 is returned and the certificate may be retrieved from the keydb using keydb_get_cert(). KEYID is the keyIdentifier from - the AKI or NULL. */ + the AKI or NULL. */ static int -find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) +find_up_external (ctrl_t ctrl, KEYDB_HANDLE kh, + const char *issuer, ksba_sexp_t keyid) { int rc; strlist_t names = NULL; @@ -476,14 +478,13 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) if (opt.verbose) log_info (_("looking up issuer at external location\n")); - /* The DIRMNGR process is confused about unknown attributes. As a + /* The Dirmngr process is confused about unknown attributes. As a quick and ugly hack we locate the CN and use the issuer string starting at this attribite. Fixme: we should have far better - parsing in the dirmngr. */ + parsing for external lookups in the Dirmngr. */ s = strstr (issuer, "CN="); if (!s || s == issuer || s[-1] != ',') s = issuer; - pattern = xtrymalloc (strlen (s)+2); if (!pattern) return gpg_error_from_syserror (); @@ -491,7 +492,7 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) add_to_strlist (&names, pattern); xfree (pattern); - rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count); + rc = gpgsm_dirmngr_lookup (ctrl, names, 0, find_up_store_certs_cb, &count); free_strlist (names); if (opt.verbose) @@ -522,6 +523,54 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) } +/* Helper for find_up(). Ask the dirmngr for the certificate for + ISSUER with optional SERIALNO. KH is the keydb context we are + currently using. With SUBJECT_MODE set, ISSUER is searched as the + subject. On success 0 is returned and the certificate is available + in the ephemeral DB. */ +static int +find_up_dirmngr (ctrl_t ctrl, KEYDB_HANDLE kh, + ksba_sexp_t serialno, const char *issuer, int subject_mode) +{ + int rc; + strlist_t names = NULL; + int count = 0; + char *pattern; + + if (opt.verbose) + log_info (_("looking up issuer from the Dirmngr cache\n")); + if (subject_mode) + { + pattern = xtrymalloc (strlen (issuer)+2); + if (pattern) + strcpy (stpcpy (pattern, "/"), issuer); + } + else if (serialno) + pattern = gpgsm_format_sn_issuer (serialno, issuer); + else + { + pattern = xtrymalloc (strlen (issuer)+3); + if (pattern) + strcpy (stpcpy (pattern, "#/"), issuer); + } + if (!pattern) + return gpg_error_from_syserror (); + add_to_strlist (&names, pattern); + xfree (pattern); + + rc = gpgsm_dirmngr_lookup (ctrl, names, 1, find_up_store_certs_cb, &count); + free_strlist (names); + + if (opt.verbose) + log_info (_("number of matching certificates: %d\n"), count); + if (rc) + log_info (_("dirmngr cache-only key lookup failed: %s\n"), + gpg_strerror (rc)); + return (!rc && count)? 0 : -1; +} + + + /* Locate issuing certificate for CERT. ISSUER is the name of the issuer used as a fallback if the other methods don't work. If FIND_NEXT is true, the function shall return the next possible @@ -529,7 +578,8 @@ find_up_external (KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) keydb_get_cert on the keyDb context KH will return it. Returns 0 on success, -1 if not found or an error code. */ static int -find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) +find_up (ctrl_t ctrl, KEYDB_HANDLE kh, + ksba_cert_t cert, const char *issuer, int find_next) { ksba_name_t authid; ksba_sexp_t authidno; @@ -545,6 +595,14 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) if (rc) keydb_search_reset (kh); + /* In case of an error, try to get the certifcate from the + dirmngr. That is done by trying to put that certifcate + into the ephemeral DB and let the code below do the + actual retrieve. Thus there is no error checking. + Skipped in find_next mode as usual. */ + if (rc == -1 && !find_next) + find_up_dirmngr (ctrl, kh, authidno, s, 0); + /* In case of an error try the ephemeral DB. We can't do that in find_next mode because we can't keep the search state then. */ @@ -559,7 +617,8 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) } keydb_set_ephemeral (kh, old); } - + if (rc) + rc = -1; /* Need to make sure to have this error code. */ } if (rc == -1 && keyid && !find_next) @@ -568,6 +627,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) instead. Loop over all certificates with that issuer as subject and stop for the one with a matching subjectKeyIdentifier. */ + /* Fixme: Should we also search in the dirmngr? */ rc = find_up_search_by_keyid (kh, issuer, keyid); if (rc) { @@ -580,9 +640,29 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) rc = -1; /* Need to make sure to have this error code. */ } + /* If we still didn't found it, try to find it via the subject + from the dirmngr-cache. */ + if (rc == -1 && !find_next) + { + if (!find_up_dirmngr (ctrl, kh, NULL, issuer, 1)) + { + int old = keydb_set_ephemeral (kh, 1); + if (keyid) + rc = find_up_search_by_keyid (kh, issuer, keyid); + else + { + keydb_search_reset (kh); + rc = keydb_search_subject (kh, issuer); + } + keydb_set_ephemeral (kh, old); + } + if (rc) + rc = -1; /* Need to make sure to have this error code. */ + } + /* If we still didn't found it, try an external lookup. */ if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer, keyid); + rc = find_up_external (ctrl, kh, issuer, keyid); /* Print a note so that the user does not feel too helpless when an issuer certificate was found and gpgsm prints BAD @@ -617,6 +697,10 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) rc = keydb_search_subject (kh, issuer); if (rc == -1 && !find_next) { + /* Also try to get it from the Dirmngr cache. The function + merely puts it into the ephemeral database. */ + find_up_dirmngr (ctrl, kh, NULL, issuer, 0); + /* Not found, let us see whether we have one in the ephemeral key DB. */ int old = keydb_set_ephemeral (kh, 1); if (!old) @@ -629,7 +713,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) /* Still not found. If enabled, try an external lookup. */ if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next) - rc = find_up_external (kh, issuer, NULL); + rc = find_up_external (ctrl, kh, issuer, NULL); return rc; } @@ -638,7 +722,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) /* Return the next certificate up in the chain starting at START. Returns -1 when there are no more certificates. */ int -gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) +gpgsm_walk_cert_chain (ctrl_t ctrl, ksba_cert_t start, ksba_cert_t *r_next) { int rc = 0; char *issuer = NULL; @@ -674,7 +758,7 @@ gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next) goto leave; } - rc = find_up (kh, start, issuer, 0); + rc = find_up (ctrl, kh, start, issuer, 0); if (rc) { /* It is quite common not to have a certificate, so better don't @@ -1194,7 +1278,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, } if (!rootca_flags->relax) { - rc = allowed_ca (subject_cert, NULL, listmode, listfp); + rc = allowed_ca (ctrl, subject_cert, NULL, listmode, listfp); if (rc) goto leave; } @@ -1301,7 +1385,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, /* Find the next cert up the tree. */ keydb_search_reset (kh); - rc = find_up (kh, subject_cert, issuer, 0); + rc = find_up (ctrl, kh, subject_cert, issuer, 0); if (rc) { if (rc == -1) @@ -1353,7 +1437,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, root certificates. */ /* FIXME: Do this only if we don't have an AKI.keyIdentifier */ - rc = find_up (kh, subject_cert, issuer, 1); + rc = find_up (ctrl, kh, subject_cert, issuer, 1); if (!rc) { ksba_cert_t tmp_cert; @@ -1393,7 +1477,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, { int chainlen; - rc = allowed_ca (issuer_cert, &chainlen, listmode, listfp); + rc = allowed_ca (ctrl, issuer_cert, &chainlen, listmode, listfp); if (rc) { /* Not allowed. Check whether this is a trusted root @@ -1656,7 +1740,7 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, the DB and that this one is valid; which it should be because it has been checked using this function. */ int -gpgsm_basic_cert_check (ksba_cert_t cert) +gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert) { int rc = 0; char *issuer = NULL; @@ -1706,7 +1790,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert) { /* Find the next cert up the tree. */ keydb_search_reset (kh); - rc = find_up (kh, cert, issuer, 0); + rc = find_up (ctrl, kh, cert, issuer, 0); if (rc) { if (rc == -1) @@ -1771,7 +1855,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert) receive the length of the chain which is either 0 or 1. */ static int -get_regtp_ca_info (ksba_cert_t cert, int *chainlen) +get_regtp_ca_info (ctrl_t ctrl, ksba_cert_t cert, int *chainlen) { gpg_error_t err; ksba_cert_t next; @@ -1816,7 +1900,7 @@ get_regtp_ca_info (ksba_cert_t cert, int *chainlen) ksba_cert_ref (cert); array[depth++] = cert; ksba_cert_ref (cert); - while (depth < DIM(array) && !(rc=gpgsm_walk_cert_chain (cert, &next))) + while (depth < DIM(array) && !(rc=gpgsm_walk_cert_chain (ctrl, cert, &next))) { ksba_cert_release (cert); ksba_cert_ref (next); diff --git a/sm/certlist.c b/sm/certlist.c index d4a351b6e..9574b8bdc 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -455,7 +455,7 @@ gpgsm_release_certlist (certlist_t list) /* Like gpgsm_add_to_certlist, but look only for one certificate. No - chain validation is done. If KEYID is not NULL it is take as an + chain validation is done. If KEYID is not NULL it is taken as an additional filter value which must match the subjectKeyIdentifier. */ int diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 8b03995e8..5e7f3f33d 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -285,14 +285,15 @@ int gpgsm_create_cms_signature (ctrl_t ctrl, #define VALIDATE_FLAG_CHAIN_MODEL 2 -int gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next); +int gpgsm_walk_cert_chain (ctrl_t ctrl, + ksba_cert_t start, ksba_cert_t *r_next); int gpgsm_is_root_cert (ksba_cert_t cert); int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, ksba_isotime_t r_exptime, int listmode, estream_t listfp, unsigned int flags, unsigned int *retflags); -int gpgsm_basic_cert_check (ksba_cert_t cert); +int gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert); /*-- certlist.c --*/ int gpgsm_cert_use_sign_p (ksba_cert_t cert); @@ -380,7 +381,7 @@ gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc); int gpgsm_dirmngr_isvalid (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp); -int gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, +int gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, int cache_only, void (*cb)(void*, ksba_cert_t), void *cb_value); int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, int argc, char **argv); diff --git a/sm/import.c b/sm/import.c index 7c825daf3..ba49da5dd 100644 --- a/sm/import.c +++ b/sm/import.c @@ -172,7 +172,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats, Optionally we do a full validation in addition to the basic test. */ - rc = gpgsm_basic_cert_check (cert); + rc = gpgsm_basic_cert_check (ctrl, cert); if (!rc && ctrl->with_validation) rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL); if (!rc || (!ctrl->with_validation @@ -216,7 +216,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats, the chain. This is required in case we already stored parent certificates in the ephemeral keybox. Do not update the statistics, though. */ - if (!gpgsm_walk_cert_chain (cert, &next)) + if (!gpgsm_walk_cert_chain (ctrl, cert, &next)) { check_and_store (ctrl, NULL, next, depth+1); ksba_cert_release (next); diff --git a/sm/keylist.c b/sm/keylist.c index e9ca9b809..4716a2bc2 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -361,7 +361,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, { ksba_cert_t next; - rc = gpgsm_walk_cert_chain (cert, &next); + rc = gpgsm_walk_cert_chain (ctrl, cert, &next); if (!rc) /* We known the issuer's certificate. */ { p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1); @@ -1141,7 +1141,7 @@ list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd, else list_cert_std (ctrl, cert, fp, 0, with_validation); ksba_cert_ref (cert); - while (!gpgsm_walk_cert_chain (cert, &next)) + while (!gpgsm_walk_cert_chain (ctrl, cert, &next)) { ksba_cert_release (cert); es_fputs ("Certified by\n", fp); @@ -1382,7 +1382,7 @@ list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode) parm.with_chain = ctrl->with_chain; parm.raw_mode = raw_mode; - rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm); + rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm); if (rc) log_error ("listing external keys failed: %s\n", gpg_strerror (rc)); return rc; diff --git a/sm/server.c b/sm/server.c index b9fe2a25e..fbff003f8 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1,6 +1,6 @@ /* server.c - Server mode and main entry point * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1007,6 +1007,36 @@ cmd_getauditlog (assuan_context_t ctx, char *line) } +/* GETINFO + + Multipurpose function to return a variety of information. + Supported values for WHAT are: + + version - Return the version of the program. + pid - Return the process id of the server. + + */ +static int +cmd_getinfo (assuan_context_t ctx, char *line) +{ + int rc; + + if (!strcmp (line, "version")) + { + const char *s = VERSION; + rc = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "pid")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else + rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + return rc; +} @@ -1036,6 +1066,7 @@ register_commands (assuan_context_t ctx) { "GENKEY", cmd_genkey }, { "DELKEYS", cmd_delkeys }, { "GETAUDITLOG", cmd_getauditlog }, + { "GETINFO", cmd_getinfo }, { NULL } }; int i, rc; diff --git a/sm/sign.c b/sm/sign.c index d8e8451bf..a6d02e929 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -272,7 +272,7 @@ add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert) /* Walk the chain to include all other certificates. Note that a -1 used for N makes sure that there is no limit and all certs get included. */ - while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) ) + while ( n-- && !(rc = gpgsm_walk_cert_chain (ctrl, cert, &next)) ) { if (not_root && gpgsm_is_root_cert (next)) err = 0;