* gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP.

(start_connection_thread): Hack to simulate a ticker.
* trustlist.c (agent_trustlist_housekeeping)
(agent_reload_trustlist): New.  Protected all global functions
here with a simple counter which is sufficient for Pth.

* fingerprint.c (gpgsm_get_key_algo_info): New.
* sign.c (gpgsm_sign): Don't assume RSA in the status line.
* keylist.c (list_cert_colon): Really print the algorithm and key
length.
(list_cert_raw, list_cert_std): Ditto.
(list_cert_colon): Reorganized to be able to tell whether a root
certificate is trusted.
This commit is contained in:
Werner Koch 2004-05-11 19:11:53 +00:00
parent fdb1933917
commit 2cce42c23f
6 changed files with 153 additions and 42 deletions

View File

@ -1,3 +1,11 @@
2004-05-11 Werner Koch <wk@gnupg.org>
* gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP.
(start_connection_thread): Hack to simulate a ticker.
* trustlist.c (agent_trustlist_housekeeping)
(agent_reload_trustlist): New. Protected all global functions
here with a simple counter which is sufficient for Pth.
2004-05-03 Werner Koch <wk@gnupg.org> 2004-05-03 Werner Koch <wk@gnupg.org>
* gpg-agent.c: Remove help texts for options lile --lc-ctype. * gpg-agent.c: Remove help texts for options lile --lc-ctype.

View File

@ -189,6 +189,8 @@ int agent_istrusted (const char *fpr);
int agent_listtrusted (void *assuan_context); int agent_listtrusted (void *assuan_context);
int agent_marktrusted (ctrl_t ctrl, const char *name, int agent_marktrusted (ctrl_t ctrl, const char *name,
const char *fpr, int flag); const char *fpr, int flag);
void agent_trustlist_housekeeping (void);
void agent_reload_trustlist (void);
/*-- divert-scd.c --*/ /*-- divert-scd.c --*/

View File

@ -1083,6 +1083,7 @@ handle_signal (int signo)
"re-reading configuration and flushing cache\n"); "re-reading configuration and flushing cache\n");
agent_flush_cache (); agent_flush_cache ();
reread_configuration (); reread_configuration ();
agent_reload_trustlist ();
break; break;
case SIGUSR1: case SIGUSR1:
@ -1129,6 +1130,12 @@ start_connection_thread (void *arg)
if (opt.verbose) if (opt.verbose)
log_info ("handler for fd %d started\n", fd); log_info ("handler for fd %d started\n", fd);
/* FIXME: Move this housekeeping into a ticker function. Calling it
for each connection should work but won't work anymore if our
cleints start to keep connections. */
agent_trustlist_housekeeping ();
start_command_handler (-1, fd); start_command_handler (-1, fd);
if (opt.verbose) if (opt.verbose)
log_info ("handler for fd %d terminated\n", fd); log_info ("handler for fd %d terminated\n", fd);

View File

@ -1,5 +1,5 @@
/* trustlist.c - Maintain the list of trusted keys /* trustlist.c - Maintain the list of trusted keys
* Copyright (C) 2002 Free Software Foundation, Inc. * Copyright (C) 2002, 2004 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -41,10 +41,13 @@ static const char headerblurb[] =
"# with optional white spaces, followed by exactly 40 hex character,\n" "# with optional white spaces, followed by exactly 40 hex character,\n"
"# optioanlly followed by a flag character which my either be 'P', 'S'\n" "# optioanlly followed by a flag character which my either be 'P', 'S'\n"
"# or '*'. Additional data delimited with by a white space is ignored.\n" "# or '*'. Additional data delimited with by a white space is ignored.\n"
"# NOTE: You should give the gpg-agent a HUP after editing this file.\n"
"\n"; "\n";
static FILE *trustfp; static FILE *trustfp;
static int trustfp_used; /* Counter to track usage of TRUSTFP. */
static int reload_trustlist_pending;
static int static int
@ -164,7 +167,7 @@ read_list (char *key, int *keyflag)
return 0; return 0;
} }
/* check whether the given fpr is in our trustdb. We expect FPR to be /* Check whether the given fpr is in our trustdb. We expect FPR to be
an all uppercase hexstring of 40 characters. */ an all uppercase hexstring of 40 characters. */
int int
agent_istrusted (const char *fpr) agent_istrusted (const char *fpr)
@ -173,25 +176,31 @@ agent_istrusted (const char *fpr)
static char key[41]; static char key[41];
int keyflag; int keyflag;
trustfp_used++;
if (trustfp) if (trustfp)
rewind (trustfp); rewind (trustfp);
while (!(rc=read_list (key, &keyflag))) while (!(rc=read_list (key, &keyflag)))
{ {
if (!strcmp (key, fpr)) if (!strcmp (key, fpr))
return 0; {
trustfp_used--;
return 0;
}
} }
if (rc != -1) if (rc != -1)
{ {
/* error in the trustdb - close it to give the user a chance for /* Error in the trustdb - close it to give the user a chance for
correction */ correction */
fclose (trustfp); if (trustfp)
fclose (trustfp);
trustfp = NULL; trustfp = NULL;
} }
trustfp_used--;
return rc; return rc;
} }
/* write all trust entries to FP */ /* Write all trust entries to FP. */
int int
agent_listtrusted (void *assuan_context) agent_listtrusted (void *assuan_context)
{ {
@ -199,6 +208,7 @@ agent_listtrusted (void *assuan_context)
static char key[51]; static char key[51];
int keyflag; int keyflag;
trustfp_used++;
if (trustfp) if (trustfp)
rewind (trustfp); rewind (trustfp);
while (!(rc=read_list (key, &keyflag))) while (!(rc=read_list (key, &keyflag)))
@ -213,11 +223,13 @@ agent_listtrusted (void *assuan_context)
rc = 0; rc = 0;
if (rc) if (rc)
{ {
/* error in the trustdb - close it to give the user a chance for /* Error in the trustdb - close it to give the user a chance for
correction */ correction */
fclose (trustfp); if (trustfp)
fclose (trustfp);
trustfp = NULL; trustfp = NULL;
} }
trustfp_used--;
return rc; return rc;
} }
@ -252,7 +264,7 @@ agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
} }
xfree (fname); xfree (fname);
trustfp_used++;
if (trustfp) if (trustfp)
rewind (trustfp); rewind (trustfp);
while (!(rc=read_list (key, &keyflag))) while (!(rc=read_list (key, &keyflag)))
@ -260,14 +272,21 @@ agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
if (!strcmp (key, fpr)) if (!strcmp (key, fpr))
return 0; return 0;
} }
fclose (trustfp); if (trustfp)
fclose (trustfp);
trustfp = NULL; trustfp = NULL;
if (rc != -1) if (rc != -1)
return rc; /* error in the trustdb */ {
trustfp_used--;
return rc; /* Error in the trustlist. */
}
/* This feature must explicitly been enabled. */ /* This feature must explicitly been enabled. */
if (!opt.allow_mark_trusted) if (!opt.allow_mark_trusted)
return gpg_error (GPG_ERR_NOT_SUPPORTED); {
trustfp_used--;
return gpg_error (GPG_ERR_NOT_SUPPORTED);
}
/* insert a new one */ /* insert a new one */
if (asprintf (&desc, if (asprintf (&desc,
@ -275,42 +294,62 @@ agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
" \"%s\"%%0A" " \"%s\"%%0A"
"has the fingerprint:%%0A" "has the fingerprint:%%0A"
" %s", name, fpr) < 0 ) " %s", name, fpr) < 0 )
return out_of_core (); {
trustfp_used--;
return out_of_core ();
}
rc = agent_get_confirmation (ctrl, desc, "Correct", "No"); rc = agent_get_confirmation (ctrl, desc, "Correct", "No");
free (desc); free (desc);
if (rc) if (rc)
return rc; {
trustfp_used--;
return rc;
}
if (asprintf (&desc, if (asprintf (&desc,
"Do you ultimately trust%%0A" "Do you ultimately trust%%0A"
" \"%s\"%%0A" " \"%s\"%%0A"
"to correctly certify user certificates?", "to correctly certify user certificates?",
name) < 0 ) name) < 0 )
return out_of_core (); {
trustfp_used--;
return out_of_core ();
}
rc = agent_get_confirmation (ctrl, desc, "Yes", "No"); rc = agent_get_confirmation (ctrl, desc, "Yes", "No");
free (desc); free (desc);
if (rc) if (rc)
return rc; {
trustfp_used--;
return rc;
}
/* now check again to avoid duplicates. Also open in append mode now */ /* Now check again to avoid duplicates. Also open in append mode now. */
rc = open_list (1); rc = open_list (1);
if (rc) if (rc)
return rc; {
trustfp_used--;
return rc;
}
rewind (trustfp); rewind (trustfp);
while (!(rc=read_list (key, &keyflag))) while (!(rc=read_list (key, &keyflag)))
{ {
if (!strcmp (key, fpr)) if (!strcmp (key, fpr))
return 0; {
trustfp_used--;
return 0;
}
} }
if (rc != -1) if (rc != -1)
{ {
fclose (trustfp); if (trustfp)
fclose (trustfp);
trustfp = NULL; trustfp = NULL;
return rc; /* error in the trustdb */ trustfp_used--;
return rc; /* Error in the trustlist. */
} }
rc = 0; rc = 0;
/* append the key */ /* Append the key. */
fflush (trustfp); fflush (trustfp);
fputs ("\n# ", trustfp); fputs ("\n# ", trustfp);
print_sanitized_string (trustfp, name, 0); print_sanitized_string (trustfp, name, 0);
@ -322,5 +361,33 @@ agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
if (fclose (trustfp)) if (fclose (trustfp))
rc = gpg_error (gpg_err_code_from_errno (errno)); rc = gpg_error (gpg_err_code_from_errno (errno));
trustfp = NULL; trustfp = NULL;
trustfp_used--;
return rc; return rc;
} }
void
agent_trustlist_housekeeping (void)
{
if (reload_trustlist_pending && !trustfp_used)
{
if (trustfp)
{
fclose (trustfp);
trustfp = NULL;
}
reload_trustlist_pending = 0;
}
}
/* Not all editors are editing files in place, thus a changes
trustlist.txt won't be recognozed if we keep the file descriptor
open. This function may be used to explicitly close that file
descriptor, which will force a reopen in turn. */
void
agent_reload_trustlist (void)
{
reload_trustlist_pending = 1;
agent_trustlist_housekeeping ();
}

View File

@ -9,6 +9,8 @@
* keylist.c (list_cert_colon): Really print the algorithm and key * keylist.c (list_cert_colon): Really print the algorithm and key
length. length.
(list_cert_raw, list_cert_std): Ditto. (list_cert_raw, list_cert_std): Ditto.
(list_cert_colon): Reorganized to be able to tell whether a root
certificate is trusted.
* gpgsm.c: New option --debug-allow-core-dump. * gpgsm.c: New option --debug-allow-core-dump.

View File

@ -289,6 +289,7 @@ static void
list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
FILE *fp, int have_secret) FILE *fp, int have_secret)
{ {
int rc;
int idx; int idx;
char truststring[2]; char truststring[2];
char *p; char *p;
@ -298,12 +299,39 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
gpg_error_t valerr; gpg_error_t valerr;
int algo; int algo;
unsigned int nbits; unsigned int nbits;
const char *chain_id;
char *chain_id_buffer = NULL;
int is_root = 0;
if (ctrl->with_validation) if (ctrl->with_validation)
valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0); valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
else else
valerr = 0; valerr = 0;
/* We need to get the fingerprint and the chaining ID in advance. */
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
{
ksba_cert_t next;
rc = gpgsm_walk_cert_chain (cert, &next);
if (!rc) /* We known the issuer's certificate. */
{
p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
chain_id_buffer = p;
chain_id = chain_id_buffer;
ksba_cert_release (next);
}
else if (rc == -1) /* We have reached the root certificate. */
{
chain_id = fpr;
is_root = 1;
}
else
chain_id = NULL;
}
fputs (have_secret? "crs:":"crt:", fp); fputs (have_secret? "crs:":"crt:", fp);
truststring[0] = 0; truststring[0] = 0;
truststring[1] = 0; truststring[1] = 0;
@ -327,11 +355,23 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
&& *not_after && strcmp (current_time, not_after) > 0 ) && *not_after && strcmp (current_time, not_after) > 0 )
*truststring = 'e'; *truststring = 'e';
} }
/* Is we have no truststring yet (i.e. the certificate might be
good) and this is a root certificate, we ask the agent whether
this is a trusted root certificate. */
if (!*truststring && is_root)
{
rc = gpgsm_agent_istrusted (ctrl, cert);
if (!rc)
*truststring = 'u'; /* Yes, we trust this one (ultimately). */
else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
*truststring = 'n'; /* No, we do not trust this one. */
/* (in case of an error we can't tell anything.) */
}
if (*truststring) if (*truststring)
fputs (truststring, fp); fputs (truststring, fp);
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
algo = gpgsm_get_key_algo_info (cert, &nbits); algo = gpgsm_get_key_algo_info (cert, &nbits);
fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24); fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
@ -379,27 +419,12 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
/* FPR record */ /* FPR record */
fprintf (fp, "fpr:::::::::%s:::", fpr); fprintf (fp, "fpr:::::::::%s:::", fpr);
/* Print chaining ID (field 13)*/ /* Print chaining ID (field 13)*/
{ if (chain_id)
ksba_cert_t next; fputs (chain_id, fp);
int rc;
rc = gpgsm_walk_cert_chain (cert, &next);
if (!rc) /* We known the issuer's certificate. */
{
p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
fputs (p, fp);
xfree (p);
ksba_cert_release (next);
}
else if (rc == -1) /* We reached the root certificate. */
{
fputs (fpr, fp);
}
}
putc (':', fp); putc (':', fp);
putc ('\n', fp); putc ('\n', fp);
xfree (fpr); fpr = NULL; xfree (fpr); fpr = NULL; chain_id = NULL;
xfree (chain_id_buffer); chain_id_buffer = NULL;
if (opt.with_key_data) if (opt.with_key_data)
{ {