aboutsummaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
Diffstat (limited to 'sm')
-rw-r--r--sm/ChangeLog14
-rw-r--r--sm/certdump.c54
-rw-r--r--sm/gpgsm.h2
-rw-r--r--sm/server.c136
-rw-r--r--sm/verify.c25
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);