diff options
Diffstat (limited to 'common/audit.c')
-rw-r--r-- | common/audit.c | 313 |
1 files changed, 236 insertions, 77 deletions
diff --git a/common/audit.c b/common/audit.c index 40cbb8274..59f881cd5 100644 --- a/common/audit.c +++ b/common/audit.c @@ -449,9 +449,9 @@ writeout_li (audit_ctx_t ctx, const char *oktext, const char *format, ...) if (ctx->use_html && format && oktext) { - if (!strcmp (oktext, "OK") || !strcmp (oktext, "Yes")) + if (!strcmp (oktext, "Yes")) color = "green"; - else if (!strcmp (oktext, "FAIL") || !strcmp (oktext, "No")) + else if (!strcmp (oktext, "No")) color = "red"; } @@ -648,53 +648,165 @@ get_cert_subject (ksba_cert_t cert, int idx) } +/* List the given certificiate. If CERT is NULL, this is a NOP. */ +static void +list_cert (audit_ctx_t ctx, ksba_cert_t cert, int with_subj) +{ + char *name; + int idx; + + name = get_cert_name (cert); + writeout_rem (ctx, "%s", name); + xfree (name); + if (with_subj) + { + enter_li (ctx); + for (idx=0; (name = get_cert_subject (cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); + } +} + + /* List the chain of certificates from STARTITEM up to STOPEVENT. The certifcates are written out as comments. */ static void list_certchain (audit_ctx_t ctx, log_item_t startitem, audit_event_t stopevent) { log_item_t item; - char *name; - int idx; startitem = find_next_log_item (ctx, startitem, AUDIT_CHAIN_BEGIN,stopevent); + writeout_li (ctx, startitem? "Yes":"No", _("Certificate chain available")); if (!startitem) - { - writeout_li (ctx, gpg_strerror (GPG_ERR_MISSING_CERT) - , _("Certificate chain")); - return; - } - writeout_li (ctx, "OK", _("Certificate chain")); + return; + item = find_next_log_item (ctx, startitem, AUDIT_CHAIN_ROOTCERT, AUDIT_CHAIN_END); if (!item) writeout_rem (ctx, "%s", _("root certificate missing")); else { - name = get_cert_name (item->cert); - writeout_rem (ctx, "%s", name); - xfree (name); + list_cert (ctx, item->cert, 0); } item = startitem; while ( ((item = find_next_log_item (ctx, item, AUDIT_CHAIN_CERT, AUDIT_CHAIN_END)))) { - name = get_cert_name (item->cert); - writeout_rem (ctx, "%s", name); - xfree (name); - enter_li (ctx); - for (idx=0; (name = get_cert_subject (item->cert, idx)); idx++) + list_cert (ctx, item->cert, 1); + } +} + + + +/* Process an encrypt operation's log. */ +static void +proc_type_encrypt (audit_ctx_t ctx) +{ + log_item_t loopitem, item; + int recp_no, idx; + char numbuf[35]; + int algo; + char *name; + + item = find_log_item (ctx, AUDIT_ENCRYPTION_DONE, 0); + writeout_li (ctx, item?"Yes":"No", "%s", _("Data encryption succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + + item = find_log_item (ctx, AUDIT_SESSION_KEY, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Session key created")); + if (item) + { + algo = gcry_cipher_map_name (item->string); + if (algo) + writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo)); + else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2")) + writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2"); + else if (item->string) + writeout_rem (ctx, _("unsupported algorithm: %s"), item->string); + else + writeout_rem (ctx, _("seems to be not encrypted")); + } + + item = find_log_item (ctx, AUDIT_GOT_RECIPIENTS, 0); + snprintf (numbuf, sizeof numbuf, "%d", + item && item->have_intvalue? item->intvalue : 0); + writeout_li (ctx, numbuf, "%s", _("Number of recipients")); + + /* Loop over all recipients. */ + loopitem = NULL; + recp_no = 0; + while ((loopitem=find_next_log_item (ctx, loopitem, AUDIT_ENCRYPTED_TO, 0))) + { + recp_no++; + writeout_li (ctx, NULL, _("Recipient %d"), recp_no); + if (loopitem->cert) { + name = get_cert_name (loopitem->cert); writeout_rem (ctx, "%s", name); xfree (name); + enter_li (ctx); + for (idx=0; (name = get_cert_subject (loopitem->cert, idx)); idx++) + { + writeout_rem (ctx, "%s", name); + xfree (name); + } + leave_li (ctx); } - leave_li (ctx); } + + leave_li (ctx); +} + + + +/* Process a sign operation's log. */ +static void +proc_type_sign (audit_ctx_t ctx) +{ + log_item_t item; + + item = NULL; + writeout_li (ctx, item?"Yes":"No", "%s", _("Data signing succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + + + leave_li (ctx); } -/* Process a verification operation. */ +/* Process a decrypt operation's log. */ +static void +proc_type_decrypt (audit_ctx_t ctx) +{ + log_item_t item; + + item = NULL; + writeout_li (ctx, item?"Yes":"No", "%s", _("Data decryption succeeded")); + + enter_li (ctx); + + item = find_log_item (ctx, AUDIT_GOT_DATA, 0); + writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); + + + leave_li (ctx); +} + + + +/* Process a verification operation's log. */ static void proc_type_verify (audit_ctx_t ctx) { @@ -702,14 +814,13 @@ proc_type_verify (audit_ctx_t ctx) int signo, count, idx; char numbuf[35]; - enter_li (ctx); - - writeout_li (ctx, "fixme", "%s", _("Signature verification")); + /* If there is at least one signature status we claim that the + verifciation succeeded. This does not mean that the data has + verified okay. */ + item = find_log_item (ctx, AUDIT_SIG_STATUS, 0); + writeout_li (ctx, item?"Yes":"No", "%s", _("Data verification succeeded")); enter_li (ctx); - writeout_li (ctx, "fixme", "%s", _("Gpg-Agent ready")); - writeout_li (ctx, "fixme", "%s", _("Dirmngr ready")); - item = find_log_item (ctx, AUDIT_GOT_DATA, AUDIT_NEW_SIG); writeout_li (ctx, item? "Yes":"No", "%s", _("Data available")); if (!item) @@ -721,19 +832,14 @@ proc_type_verify (audit_ctx_t ctx) goto leave; item = find_log_item (ctx, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG); - if (item) - writeout_li (ctx, "OK", "%s", _("Parsing signature")); - else + writeout_li (ctx, item?"Yes":"No", "%s", _("Parsing signature succeeded")); + if (!item) { item = find_log_item (ctx, AUDIT_BAD_DATA_HASH_ALGO, AUDIT_NEW_SIG); if (item) - { - writeout_li (ctx,"FAIL", "%s", _("Parsing signature")); - writeout_rem (ctx, _("Bad hash algorithm: %s"), - item->string? item->string:"?"); - } - else - writeout_li (ctx, "FAIL", "%s", _("Parsing signature") ); + writeout_rem (ctx, _("Bad hash algorithm: %s"), + item->string? item->string:"?"); + goto leave; } @@ -761,19 +867,30 @@ proc_type_verify (audit_ctx_t ctx) AUDIT_CHAIN_STATUS, AUDIT_NEW_SIG); if (item && item->have_err) { - writeout_li (ctx, item->err? "FAIL":"OK", - _("Validation of certificate chain")); + writeout_li (ctx, item->err? "No":"Yes", + _("Certificate chain valid")); if (item->err) writeout_rem (ctx, "%s", gpg_strerror (item->err)); } /* Show whether the root certificate is fine. */ - writeout_li (ctx, "No", "%s", _("Root certificate trustworthy")); - add_helptag (ctx, "gpgsm.root-cert-not-trusted"); + item = find_next_log_item (ctx, loopitem, + AUDIT_ROOT_TRUSTED, AUDIT_CHAIN_STATUS); + if (item) + { + writeout_li (ctx, item->err?"No":"Yes", "%s", + _("Root certificate trustworthy")); + if (item->err) + { + add_helptag (ctx, "gpgsm.root-cert-not-trusted"); + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + list_cert (ctx, item->cert, 0); + } + } /* Show result of the CRL/OCSP check. */ writeout_li (ctx, "-", "%s", _("CRL/OCSP check of certificates")); - add_helptag (ctx, "gpgsm.ocsp-problem"); + /* add_helptag (ctx, "gpgsm.ocsp-problem"); */ leave_li (ctx); @@ -805,8 +922,6 @@ proc_type_verify (audit_ctx_t ctx) } leave_li (ctx); } - - leave_li (ctx); leave_li (ctx); } @@ -818,16 +933,24 @@ void audit_print_result (audit_ctx_t ctx, estream_t out, int use_html) { int idx; - int maxlen; size_t n; + log_item_t item; helptag_t helptag; - - if (getenv ("use_html")) - use_html = 1; - + const char *s; + int show_raw = 0; + if (!ctx) return; + /* We use an environment variable to include some debug info in the + log. */ + if ((s = getenv ("gnupg_debug_audit"))) + { + show_raw = 1; + if (!strcmp (s, "html")) + use_html = 1; + } + assert (!ctx->outstream); ctx->outstream = out; ctx->use_html = use_html; @@ -843,51 +966,87 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html) goto leave; } - for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++) + if (show_raw) { - n = strlen (eventstr_msgstr + eventstr_msgidx[idx]); - if (n > maxlen) - maxlen = n; - } + int maxlen; - if (use_html) - es_fputs ("<pre>\n", out); - for (idx=0; idx < ctx->logused; idx++) - { - es_fprintf (out, "log: %-*s", - maxlen, event2str (ctx->log[idx].event)); - if (ctx->log[idx].have_intvalue) - es_fprintf (out, " i=%d", ctx->log[idx].intvalue); - if (ctx->log[idx].string) + for (idx=0,maxlen=0; idx < DIM (eventstr_msgidx); idx++) { - es_fputs (" s=`", out); - writeout (ctx, ctx->log[idx].string); - es_fputs ("'", out); + n = strlen (eventstr_msgstr + eventstr_msgidx[idx]); + if (n > maxlen) + maxlen = n; } - if (ctx->log[idx].cert) - es_fprintf (out, " has_cert"); - if (ctx->log[idx].have_err) + + if (use_html) + es_fputs ("<pre>\n", out); + for (idx=0; idx < ctx->logused; idx++) { - es_fputs (" err=`", out); - writeout (ctx, gpg_strerror (ctx->log[idx].err)); - es_fputs ("'", out); + es_fprintf (out, "log: %-*s", + maxlen, event2str (ctx->log[idx].event)); + if (ctx->log[idx].have_intvalue) + es_fprintf (out, " i=%d", ctx->log[idx].intvalue); + if (ctx->log[idx].string) + { + es_fputs (" s=`", out); + writeout (ctx, ctx->log[idx].string); + es_fputs ("'", out); + } + if (ctx->log[idx].cert) + es_fprintf (out, " has_cert"); + if (ctx->log[idx].have_err) + { + es_fputs (" err=`", out); + writeout (ctx, gpg_strerror (ctx->log[idx].err)); + es_fputs ("'", out); + } + es_fputs ("\n", out); } - es_fputs ("\n", out); + if (use_html) + es_fputs ("</pre>\n", out); + else + es_fputs ("\n", out); } - if (use_html) - es_fputs ("</pre>\n", out); - else - es_fputs ("\n", out); + enter_li (ctx); switch (ctx->type) { case AUDIT_TYPE_NONE: - writeout_para (ctx, _("Audit of this operation is not supported.")); + writeout_li (ctx, NULL, _("Unknown operation")); + break; + case AUDIT_TYPE_ENCRYPT: + proc_type_encrypt (ctx); + break; + case AUDIT_TYPE_SIGN: + proc_type_sign (ctx); + break; + case AUDIT_TYPE_DECRYPT: + proc_type_decrypt (ctx); break; case AUDIT_TYPE_VERIFY: proc_type_verify (ctx); break; } + item = find_log_item (ctx, AUDIT_AGENT_READY, 0); + if (item && item->have_err) + { + writeout_li (ctx, item->err? "No":"Yes", "%s", _("Gpg-Agent usable")); + if (item->err) + { + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + add_helptag (ctx, "gnupg.agent-problem"); + } + } + item = find_log_item (ctx, AUDIT_DIRMNGR_READY, 0); + if (item && item->have_err) + { + writeout_li (ctx, item->err? "No":"Yes", "%s", _("Dirmngr usable")); + if (item->err) + { + writeout_rem (ctx, "%s", gpg_strerror (item->err)); + add_helptag (ctx, "gnupg.dirmngr-problem"); + } + } + leave_li (ctx); /* Show the help from the collected help tags. */ |