diff options
author | Werner Koch <[email protected]> | 2007-12-12 10:28:30 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2007-12-12 10:28:30 +0000 |
commit | bae4b256c79c24e5306c692adf9bb5891433c7d5 (patch) | |
tree | c0aae4de008d75964074146240257f81b8ded0b1 /sm | |
parent | Allow decryption using type 20 Elgamal keys. (diff) | |
download | gnupg-bae4b256c79c24e5306c692adf9bb5891433c7d5.tar.gz gnupg-bae4b256c79c24e5306c692adf9bb5891433c7d5.zip |
Support DSA2.
Support Camellia for testing.
More audit stuff.
Diffstat (limited to 'sm')
-rw-r--r-- | sm/ChangeLog | 17 | ||||
-rw-r--r-- | sm/call-agent.c | 22 | ||||
-rw-r--r-- | sm/call-dirmngr.c | 44 | ||||
-rw-r--r-- | sm/certchain.c | 2 | ||||
-rw-r--r-- | sm/encrypt.c | 20 | ||||
-rw-r--r-- | sm/gpgsm.c | 47 | ||||
-rw-r--r-- | sm/gpgsm.h | 4 | ||||
-rw-r--r-- | sm/server.c | 23 |
8 files changed, 140 insertions, 39 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog index 5f03b86c5..49ed50669 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,20 @@ +2007-12-11 Werner Koch <[email protected]> + + * certchain.c (do_validate_chain): Log AUDIT_ROOT_TRUSTED. + + * server.c (cmd_sign, cmd_decrypt, cmd_encrypt): Start audit log. + (cmd_recipient): Start audit session. + + * gpgsm.c (main): Revamp creation of the audit log. + + * gpgsm.h (struct server_control_s): Add AGENT_SEEN and DIRMNGR_SEEN. + * call-agent.c (start_agent): Record an audit event. + * call-dirmngr.c (start_dirmngr): Ditto. Add new arg CTRL and pass + it from all callers. + (prepare_dirmngr): New helper for start_dirmngr. + + * encrypt.c (gpgsm_encrypt): Add calls to audit_log. + 2007-12-03 Werner Koch <[email protected]> * gpgsm.c (main): All gnupg_reopen_std. diff --git a/sm/call-agent.c b/sm/call-agent.c index 3f4e11ec2..af35ac53a 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -1,5 +1,6 @@ /* call-agent.c - divert operations to the agent - * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2005, + * 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -69,13 +70,14 @@ struct learn_parm_s static int start_agent (ctrl_t ctrl) { - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the agent (which is suitable given that - the agent is not MT. */ - + int rc; - return start_new_gpg_agent (&agent_ctx, + if (agent_ctx) + rc = 0; /* fixme: We need a context for each thread or + serialize the access to the agent (which is + suitable given that the agent is not MT. */ + else + rc = start_new_gpg_agent (&agent_ctx, GPG_ERR_SOURCE_DEFAULT, opt.homedir, opt.agent_program, @@ -84,7 +86,13 @@ start_agent (ctrl_t ctrl) opt.xauthority, opt.pinentry_user_data, opt.verbose, DBG_ASSUAN, gpgsm_status2, ctrl); + if (!ctrl->agent_seen) + { + ctrl->agent_seen = 1; + audit_log_ok (ctrl->audit, AUDIT_AGENT_READY, rc); + } + return rc; } diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index a35e93cde..a4b6fbca7 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 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -134,13 +134,32 @@ get_membuf (struct membuf *mb, size_t *len) } +/* This fucntion prepares the dirmngr for a new session. The + audit-events option is used so that other dirmngr clients won't get + disturbed by such events. */ +static void +prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) +{ + if (!ctrl->dirmngr_seen) + { + ctrl->dirmngr_seen = 1; + if (!err) + { + err = assuan_transact (ctx, "OPTION audit-events=1", + NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* Allow the use of old dirmngr versions. */ + } + audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); + } +} /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting */ static int -start_dirmngr (void) +start_dirmngr (ctrl_t ctrl) { int rc; char *infostr, *p; @@ -148,8 +167,11 @@ start_dirmngr (void) int try_default = 0; if (dirmngr_ctx) - return 0; /* fixme: We need a context for each thread or serialize - the access to the dirmngr */ + { + prepare_dirmngr (ctrl, dirmngr_ctx, 0); + return 0; /* fixme: We need a context for each thread or serialize + the access to the dirmngr */ + } /* Note: if you change this to multiple connections, you also need to take care of the implicit option sending caching. */ @@ -220,7 +242,7 @@ start_dirmngr (void) log_error (_("malformed DIRMNGR_INFO environment variable\n")); xfree (infostr); force_pipe_server = 1; - return start_dirmngr (); + return start_dirmngr (ctrl); } *p++ = 0; pid = atoi (p); @@ -233,7 +255,7 @@ start_dirmngr (void) prot); xfree (infostr); force_pipe_server = 1; - return start_dirmngr (); + return start_dirmngr (ctrl); } } else @@ -251,11 +273,13 @@ start_dirmngr (void) { log_error (_("can't connect to the dirmngr - trying fall back\n")); force_pipe_server = 1; - return start_dirmngr (); + return start_dirmngr (ctrl); } #endif /*!HAVE_W32_SYSTEM*/ } + prepare_dirmngr (ctrl, ctx, rc); + if (rc) { log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc)); @@ -424,7 +448,7 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl, struct isvalid_status_parm_s stparm; - rc = start_dirmngr (); + rc = start_dirmngr (ctrl); if (rc) return rc; @@ -691,7 +715,7 @@ gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, struct lookup_parm_s parm; size_t len; - rc = start_dirmngr (); + rc = start_dirmngr (ctrl); if (rc) return rc; @@ -821,7 +845,7 @@ gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, size_t len; struct run_command_parm_s parm; - rc = start_dirmngr (); + rc = start_dirmngr (ctrl); if (rc) return rc; diff --git a/sm/certchain.c b/sm/certchain.c index f30c0c0ae..a21a38a07 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -1127,6 +1127,8 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, associated with that specific root certificate. */ istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, rootca_flags); + audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED, + subject_cert, istrusted_rc); /* If the chain model extended attribute is used, make sure that our chain model flag is set. */ if (has_validation_model_chain (subject_cert, listmode, listfp)) diff --git a/sm/encrypt.c b/sm/encrypt.c index 1e36e960c..5f79be1bf 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -1,5 +1,5 @@ /* encrypt.c - Encrypt a message - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -318,9 +318,12 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) int recpno; FILE *data_fp = NULL; certlist_t cl; + int count; memset (&encparm, 0, sizeof encparm); + audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT); + /* Check that the certificate list is not empty and that at least one certificate is not flagged as encrypt_to; i.e. is a real recipient. */ @@ -331,10 +334,15 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) { log_error(_("no valid recipients given\n")); gpgsm_status (ctrl, STATUS_NO_RECP, "0"); + audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0); rc = gpg_error (GPG_ERR_NO_PUBKEY); goto leave; } + for (count = 0, cl = recplist; cl; cl = cl->next) + count++; + audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count); + kh = keydb_new (0); if (!kh) { @@ -385,6 +393,8 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) goto leave; } + audit_log (ctrl->audit, AUDIT_GOT_DATA); + /* We are going to create enveloped data with uninterpreted data as inner content */ err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA); @@ -432,6 +442,8 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) rc = out_of_core (); goto leave; } + + audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid); /* Gather certificates of recipients, encrypt the session key for each and store them in the CMS object */ @@ -442,6 +454,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) rc = encrypt_dek (dek, cl->cert, &encval); if (rc) { + audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc); log_error ("encryption failed for recipient no. %d: %s\n", recpno, gpg_strerror (rc)); goto leave; @@ -450,6 +463,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) err = ksba_cms_add_recipient (cms, cl->cert); if (err) { + audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err); log_error ("ksba_cms_add_recipient failed: %s\n", gpg_strerror (err)); rc = err; @@ -459,6 +473,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) err = ksba_cms_set_enc_val (cms, recpno, encval); xfree (encval); + audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err); if (err) { log_error ("ksba_cms_set_enc_val failed: %s\n", @@ -466,7 +481,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) rc = err; goto leave; } - } + } /* Main control loop for encryption. */ recpno = 0; @@ -496,6 +511,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp) log_error ("write failed: %s\n", gpg_strerror (rc)); goto leave; } + audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE); log_info ("encrypted data created\n"); leave: diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 10e39159d..93474b37a 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -848,6 +848,7 @@ main ( int argc, char **argv) certlist_t signerlist = NULL; int do_not_setup_keys = 0; int recp_required = 0; + estream_t auditfp = NULL; /*mtrace();*/ @@ -1482,6 +1483,26 @@ main ( int argc, char **argv) keydb_add_resource (sl->d, 0, 0, NULL); FREE_STRLIST(nrings); + + /* Prepare the audit log feature for certain commands. */ + if (auditlog) + { + switch (cmd) + { + case aEncr: + case aSign: + case aDecrypt: + case aVerify: + audit_release (ctrl.audit); + ctrl.audit = audit_new (); + auditfp = open_es_fwrite (auditlog); + break; + default: + break; + } + } + + if (!do_not_setup_keys) { for (sl = locusr; sl ; sl = sl->next) @@ -1528,6 +1549,7 @@ main ( int argc, char **argv) fname = argc? *argv : NULL; + /* Dispatch command. */ switch (cmd) { case aGPGConfList: @@ -1650,7 +1672,6 @@ main ( int argc, char **argv) case aVerify: { FILE *fp = NULL; - estream_t auditfp = NULL; set_binary (stdin); if (argc == 2 && opt.outfile) @@ -1658,13 +1679,6 @@ main ( int argc, char **argv) else if (opt.outfile) fp = open_fwrite (opt.outfile); - if (auditlog) - { - audit_release (ctrl.audit); - ctrl.audit = audit_new (); - auditfp = open_es_fwrite (auditlog); - } - if (!argc) gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */ else if (argc == 1) @@ -1674,16 +1688,8 @@ main ( int argc, char **argv) else wrong_args ("--verify [signature [detached_data]]"); - if (auditlog) - { - audit_print_result (ctrl.audit, auditfp, 0); - audit_release (ctrl.audit); - ctrl.audit = NULL; - } - if (fp && fp != stdout) fclose (fp); - es_fclose (auditfp); } break; @@ -1846,6 +1852,15 @@ main ( int argc, char **argv) log_error ("invalid command (there is no implicit command)\n"); break; } + + /* Print the audit result if needed. */ + if (auditlog && auditfp) + { + audit_print_result (ctrl.audit, auditfp, 0); + audit_release (ctrl.audit); + ctrl.audit = NULL; + es_fclose (auditfp); + } /* cleanup */ gpgsm_release_certlist (recplist); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 8f9692a73..5232ce427 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -152,6 +152,10 @@ struct server_control_s struct server_local_s *server_local; audit_ctx_t audit; /* NULL or a context for the audit subsystem. */ + int agent_seen; /* Flag indicating that the gpg-agent has been + accessed. */ + int dirmngr_seen; /* Flag indicating that the dirmngr has been + accessed. */ int with_colons; /* Use column delimited output format */ int with_chain; /* Include the certifying certs in a listing */ diff --git a/sm/server.c b/sm/server.c index e61f9d600..b9fe2a25e 100644 --- a/sm/server.c +++ b/sm/server.c @@ -366,7 +366,14 @@ cmd_recipient (assuan_context_t ctx, char *line) ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - rc = gpgsm_add_to_certlist (ctrl, line, 0, &ctrl->server_local->recplist, 0); + if (!ctrl->audit) + rc = start_audit_session (ctrl); + else + rc = 0; + + if (!rc) + rc = gpgsm_add_to_certlist (ctrl, line, 0, + &ctrl->server_local->recplist, 0); if (rc) { gpg_err_code_t r = gpg_err_code (rc); @@ -478,6 +485,8 @@ cmd_encrypt (assuan_context_t ctx, char *line) &ctrl->server_local->recplist, 1); } if (!rc) + rc = ctrl->audit? 0 : start_audit_session (ctrl); + if (!rc) rc = gpgsm_encrypt (assuan_get_pointer (ctx), ctrl->server_local->recplist, inp_fd, out_fp); @@ -492,6 +501,7 @@ cmd_encrypt (assuan_context_t ctx, char *line) return rc; } + /* DECRYPT This performs the decrypt operation after doing some check on the @@ -517,7 +527,10 @@ cmd_decrypt (assuan_context_t ctx, char *line) out_fp = fdopen (dup(out_fd), "w"); if (!out_fp) return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); - rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); + + rc = start_audit_session (ctrl); + if (!rc) + rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); fclose (out_fp); /* close and reset the fd */ @@ -600,8 +613,10 @@ cmd_sign (assuan_context_t ctx, char *line) if (!out_fp) return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); - rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, - inp_fd, detached, out_fp); + rc = start_audit_session (ctrl); + if (!rc) + rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, + inp_fd, detached, out_fp); fclose (out_fp); /* close and reset the fd */ |