diff options
Diffstat (limited to 'sm')
-rw-r--r-- | sm/ChangeLog | 14 | ||||
-rw-r--r-- | sm/certdump.c | 54 | ||||
-rw-r--r-- | sm/gpgsm.h | 2 | ||||
-rw-r--r-- | sm/server.c | 136 | ||||
-rw-r--r-- | sm/verify.c | 25 |
5 files changed, 145 insertions, 86 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog index d371d1da0..6e445822f 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,17 @@ +2006-11-14 Werner Koch <[email protected]> + + * server.c (skip_options): Skip leading spaces. + (has_option): Honor "--". + (cmd_export): Add option --data to do an inline export. Skip all + options. + + * certdump.c (gpgsm_fpr_and_name_for_status): New. + * verify.c (gpgsm_verify): Use it to print correct status messages. + +2006-11-11 Werner Koch <[email protected]> + + * server.c (skip_options): New. + 2006-10-24 Marcus Brinkmann <[email protected]> * Makefile.am (AM_CFLAGS): Add $(LIBASSUAN_CFLAGS). diff --git a/sm/certdump.c b/sm/certdump.c index 2f7c1fd54..032a00ad2 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -705,6 +705,59 @@ gpgsm_format_name (const char *name) } +/* Return fingerprint and a percent escaped name in a human readable + format suitable for status messages like GOODSIG. May return NULL + on error (out of core). */ +char * +gpgsm_fpr_and_name_for_status (ksba_cert_t cert) +{ + char *fpr, *name, *p; + char *buffer; + + fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); + if (!fpr) + return NULL; + + name = ksba_cert_get_subject (cert, 0); + if (!name) + { + xfree (fpr); + return NULL; + } + + p = gpgsm_format_name2 (name, 0); + ksba_free (name); + name = p; + if (!name) + { + xfree (fpr); + return NULL; + } + + buffer = xtrymalloc (strlen (fpr) + 1 + 3*strlen (name) + 1); + if (buffer) + { + const unsigned char *s; + + p = stpcpy (stpcpy (buffer, fpr), " "); + for (s = name; *s; s++) + { + if (*s < ' ') + { + sprintf (p, "%%%02X", *s); + p += 3; + } + else + *p++ = *s; + } + *p = 0; + } + xfree (fpr); + xfree (name); + return buffer; +} + + /* Create a key description for the CERT, this may be passed to the pinentry. The caller must free the returned string. NULL may be returned on error. */ @@ -800,3 +853,4 @@ gpgsm_format_keydesc (ksba_cert_t cert) return buffer; } + diff --git a/sm/gpgsm.h b/sm/gpgsm.h index d92bf5923..280653070 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -241,6 +241,8 @@ char *gpgsm_format_serial (ksba_const_sexp_t p); char *gpgsm_format_name2 (const char *name, int translate); char *gpgsm_format_name (const char *name); +char *gpgsm_fpr_and_name_for_status (ksba_cert_t cert); + char *gpgsm_format_keydesc (ksba_cert_t cert); diff --git a/sm/server.c b/sm/server.c index 4b6fe390b..0bf85e095 100644 --- a/sm/server.c +++ b/sm/server.c @@ -74,6 +74,22 @@ strcpy_escaped_plus (char *d, const char *s) } +/* Skip over options. + Blanks after the options are also removed. */ +static char * +skip_options (const char *line) +{ + while (spacep (line)) + line++; + while ( *line == '-' && line[1] == '-' ) + { + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + } + return (char*)line; +} /* Check whether the option NAME appears in LINE */ @@ -84,6 +100,8 @@ has_option (const char *line, const char *name) int n = strlen (name); s = strstr (line, name); + if (s && s >= skip_options (line)) + return 0; return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); } @@ -530,6 +548,10 @@ cmd_import (assuan_context_t ctx, char *line) } +/* EXPORT [--data [--armor|--base64]] [--] pattern + + */ + static int cmd_export (assuan_context_t ctx, char *line) { @@ -538,11 +560,20 @@ cmd_export (assuan_context_t ctx, char *line) FILE *out_fp; char *p; strlist_t list, sl; - - if (fd == -1) - return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); + int use_data; - /* break the line down into an strlist_t */ + use_data = has_option (line, "--data"); + + if (use_data) + { + /* We need to override any possible setting done by an OUTPUT command. */ + ctrl->create_pem = has_option (line, "--armor"); + ctrl->create_base64 = has_option (line, "--base64"); + } + + line = skip_options (line); + + /* Break the line down into an strlist_t. */ list = NULL; for (p=line; *p; line = p) { @@ -565,17 +596,36 @@ cmd_export (assuan_context_t ctx, char *line) } } - out_fp = fdopen ( dup(fd), "w"); - if (!out_fp) + if (use_data) { - free_strlist (list); - return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); + out_fp = assuan_get_data_fp (ctx); + if (!out_fp) + { + free_strlist (list); + return set_error (GPG_ERR_ASS_GENERAL, "no data stream"); + } + gpgsm_export (ctrl, list, out_fp); + } + else + { + if (fd == -1) + { + free_strlist (list); + return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); + } + out_fp = fdopen ( dup(fd), "w"); + if (!out_fp) + { + free_strlist (list); + return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); + } + + gpgsm_export (ctrl, list, out_fp); + fclose (out_fp); } - gpgsm_export (ctrl, list, out_fp); - fclose (out_fp); free_strlist (list); - /* close and reset the fd */ + /* Close and reset the fds. */ close_message_fd (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -1097,67 +1147,3 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, return gpgsm_status2 (ctrl, no, buf, NULL); } -#if 0 -/* - * Write a status line with a buffer using %XX escapes. If WRAP is > - * 0 wrap the line after this length. If STRING is not NULL it will - * be prepended to the buffer, no escaping is done for string. - * A wrap of -1 forces spaces not to be encoded as %20. - */ -void -write_status_text_and_buffer ( int no, const char *string, - const char *buffer, size_t len, int wrap ) -{ - const char *s, *text; - int esc, first; - int lower_limit = ' '; - size_t n, count, dowrap; - - if( !statusfp ) - return; /* not enabled */ - - if (wrap == -1) { - lower_limit--; - wrap = 0; - } - - text = get_status_string (no); - count = dowrap = first = 1; - do { - if (dowrap) { - fprintf (statusfp, "[GNUPG:] %s ", text ); - count = dowrap = 0; - if (first && string) { - fputs (string, statusfp); - count += strlen (string); - } - first = 0; - } - for (esc=0, s=buffer, n=len; n && !esc; s++, n-- ) { - if ( *s == '%' || *(const byte*)s <= lower_limit - || *(const byte*)s == 127 ) - esc = 1; - if ( wrap && ++count > wrap ) { - dowrap=1; - break; - } - } - if (esc) { - s--; n++; - } - if (s != buffer) - fwrite (buffer, s-buffer, 1, statusfp ); - if ( esc ) { - fprintf (statusfp, "%%%02X", *(const unsigned char*)s ); - s++; n--; - } - buffer = s; - len = n; - if ( dowrap && len ) - putc ( '\n', statusfp ); - } while ( len ); - - putc ('\n',statusfp); - fflush (statusfp); -} -#endif diff --git a/sm/verify.c b/sm/verify.c index b94f2ce5a..a34b5b05c 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -410,7 +410,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp) log_error ("invalid signature: message digest attribute " "does not match calculated one\n"); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); + fpr = gpgsm_fpr_and_name_for_status (cert); gpgsm_status (ctrl, STATUS_BADSIG, fpr); xfree (fpr); goto next_signer; @@ -447,7 +447,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp) char *fpr; log_error ("invalid signature: %s\n", gpg_strerror (rc)); - fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); + fpr = gpgsm_fpr_and_name_for_status (cert); gpgsm_status (ctrl, STATUS_BADSIG, fpr); xfree (fpr); goto next_signer; @@ -463,16 +463,19 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp) if (DBG_X509) log_debug ("signature okay - checking certs\n"); rc = gpgsm_validate_chain (ctrl, cert, keyexptime, 0, NULL, 0); - if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED) - { - gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL); - rc = 0; - } - else - gpgsm_status (ctrl, STATUS_GOODSIG, NULL); - { - char *buf, *fpr, *tstr; + char *fpr, *buf, *tstr; + + fpr = gpgsm_fpr_and_name_for_status (cert); + if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED) + { + gpgsm_status (ctrl, STATUS_EXPKEYSIG, fpr); + rc = 0; + } + else + gpgsm_status (ctrl, STATUS_GOODSIG, fpr); + + xfree (fpr); fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); tstr = strtimestamp_r (sigtime); |