diff options
Diffstat (limited to 'agent')
-rw-r--r-- | agent/ChangeLog | 9 | ||||
-rw-r--r-- | agent/agent.h | 3 | ||||
-rw-r--r-- | agent/command.c | 35 | ||||
-rw-r--r-- | agent/trustlist.c | 75 |
4 files changed, 106 insertions, 16 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog index 79cd7f734..46205861d 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2006-09-25 Werner Koch <[email protected]> + + * trustlist.c (read_one_trustfile): Allow extra flags. + (struct trustitem_s): Replaced KEYFLAGS by a FLAGS struct. + Changed all code to use this. + (agent_istrusted): New arg CTRL. Changed all callers. Send back + flags. + * command.c (agent_write_status): New. + 2006-09-20 Werner Koch <[email protected]> * Makefile.am: Changes to allow parallel make runs. diff --git a/agent/agent.h b/agent/agent.h index 7559a3e63..3667e8149 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -174,6 +174,7 @@ void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ void agent_init_default_ctrl (struct server_control_s *ctrl); /*-- command.c --*/ +gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...); void start_command_handler (int, int); /*-- command-ssh.c --*/ @@ -252,7 +253,7 @@ int agent_get_shadow_info (const unsigned char *shadowkey, /*-- trustlist.c --*/ -gpg_error_t agent_istrusted (const char *fpr); +gpg_error_t agent_istrusted (ctrl_t ctrl, const char *fpr); gpg_error_t agent_listtrusted (void *assuan_context); gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag); diff --git a/agent/command.c b/agent/command.c index 94d770a3c..ba2bfe8b8 100644 --- a/agent/command.c +++ b/agent/command.c @@ -227,8 +227,40 @@ parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) } +/* Write an assuan status line. */ +gpg_error_t +agent_write_status (ctrl_t ctrl, const char *keyword, ...) +{ + gpg_error_t err = 0; + va_list arg_ptr; + const char *text; + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + char buf[950], *p; + size_t n; + + va_start (arg_ptr, keyword); + + p = buf; + n = 0; + while ( (text = va_arg (arg_ptr, const char *)) ) + { + if (n) + { + *p++ = ' '; + n++; + } + for ( ; *text && n < DIM (buf)-2; n++) + *p++ = *text++; + } + *p = 0; + err = assuan_write_status (ctx, keyword, buf); + va_end (arg_ptr); + return err; +} + + /* ISTRUSTED <hexstring_with_fingerprint> Return OK when we have an entry with this fingerprint in our @@ -236,6 +268,7 @@ parse_keygrip (assuan_context_t ctx, const char *string, unsigned char *buf) static int cmd_istrusted (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc, n, i; char *p; char fpr[41]; @@ -254,7 +287,7 @@ cmd_istrusted (assuan_context_t ctx, char *line) for (p=line; i < 40; p++, i++) fpr[i] = *p >= 'a'? (*p & 0xdf): *p; fpr[i] = 0; - rc = agent_istrusted (fpr); + rc = agent_istrusted (ctrl, fpr); if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED) return rc; else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF ) diff --git a/agent/trustlist.c b/agent/trustlist.c index 58a9467f5..1f0427b65 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -38,7 +38,13 @@ /* A structure to store the information from the trust file. */ struct trustitem_s { - int keyflag; /* The keyflag: '*', 'P' or 'S'. */ + struct + { + int for_pgp:1; /* Set by '*' or 'P' as first flag. */ + int for_smime:1; /* Set by '*' or 'S' as first flag. */ + int relax:1; /* Relax checking of root certificate + constraints. */ + } flags; unsigned char fpr[20]; /* The binary fingerprint. */ }; typedef struct trustitem_s trustitem_t; @@ -198,14 +204,22 @@ read_one_trustfile (const char *fname, int allow_include, for (; spacep (p); p++) ; - if (!*p) - ti->keyflag = '*'; + memset (&ti->flags, 0, sizeof ti->flags); + /* Process the first flag which needs to be the first for + backward compatibility. */ + if (!*p || *p == '*' ) + { + ti->flags.for_smime = 1; + ti->flags.for_pgp = 1; + } else if ( *p == 'P' || *p == 'p') - ti->keyflag = 'P'; + { + ti->flags.for_pgp = 1; + } else if ( *p == 'S' || *p == 's') - ti->keyflag = 'S'; - else if ( *p == '*') - ti->keyflag = '*'; + { + ti->flags.for_smime = 1; + } else { log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr); @@ -219,7 +233,29 @@ read_one_trustfile (const char *fname, int allow_include, err = gpg_error (GPG_ERR_BAD_DATA); continue; } - /* Fixme: need to check for trailing garbage. */ + + /* Now check for more key-value pairs of the form NAME[=VALUE]. */ + while (*p) + { + for (; spacep (p); p++) + ; + if (!*p) + break; + n = strcspn (p, "= \t"); + if (p[n] == '=') + { + log_error ("assigning a value to a flag is not yet supported; " + "in `%s', line %d\n", fname, lnr); + err = gpg_error (GPG_ERR_BAD_DATA); + p++; + } + else if (n == 5 && !memcmp (p, "relax", 5)) + ti->flags.relax = 1; + else + log_error ("flag `%.*s' in `%s', line %d ignored\n", + n, p, fname, lnr); + p += n; + } tableidx++; } if ( !err && !feof (fp) ) @@ -250,7 +286,7 @@ read_trustfiles (void) char *fname; int allow_include = 1; - tablesize = 10; + tablesize = 20; table = xtrycalloc (tablesize, sizeof *table); if (!table) return gpg_error_from_syserror (); @@ -302,7 +338,7 @@ read_trustfiles (void) /* Check whether the given fpr is in our trustdb. We expect FPR to be an all uppercase hexstring of 40 characters. */ gpg_error_t -agent_istrusted (const char *fpr) +agent_istrusted (ctrl_t ctrl, const char *fpr) { gpg_error_t err; trustitem_t *ti; @@ -326,7 +362,17 @@ agent_istrusted (const char *fpr) { for (ti=trusttable, len = trusttablesize; len; ti++, len--) if (!memcmp (ti->fpr, fprbin, 20)) - return 0; /* Trusted. */ + { + if (ti->flags.relax) + { + err = agent_write_status (ctrl, + "TRUSTLISTFLAG", "relax", + NULL); + if (err) + return err; + } + return 0; /* Trusted. */ + } } return gpg_error (GPG_ERR_NOT_TRUSTED); } @@ -360,7 +406,8 @@ agent_listtrusted (void *assuan_context) { bin2hex (ti->fpr, 20, key); key[40] = ' '; - key[41] = ti->keyflag; + key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*' + : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' '); key[42] = '\n'; assuan_send_data (assuan_context, key, 43); assuan_send_data (assuan_context, NULL, 0); /* flush */ @@ -400,7 +447,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) } xfree (fname); - if (!agent_istrusted (fpr)) + if (!agent_istrusted (ctrl, fpr)) { return 0; /* We already got this fingerprint. Silently return success. */ @@ -460,7 +507,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) with the trusttable but using this lock is just fine for our purpose. */ lock_trusttable (); - if (!agent_istrusted (fpr)) + if (!agent_istrusted (ctrl, fpr)) { unlock_trusttable (); return 0; |