diff options
| -rw-r--r-- | gpgme/ChangeLog | 9 | ||||
| -rw-r--r-- | gpgme/engine-gpgsm.c | 96 | ||||
| -rw-r--r-- | tests/ChangeLog | 5 | ||||
| -rw-r--r-- | tests/gpgsm/Makefile.am | 2 | ||||
| -rw-r--r-- | tests/gpgsm/t-keylist.c | 160 | 
5 files changed, 243 insertions, 29 deletions
diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 569005f5..00449dc5 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,10 @@ +2001-12-14  Marcus Brinkmann  <[email protected]> + +	* engine-gpgsm.c (struct gpgsm_object_s): New member colon.attic. +	(_gpgme_gpgsm_new): Initialize some more members. +	(_gpgme_gpgsm_release): Free the colon line handler's attic line. +	(gpgsm_status_handler): Rework the inline-data processing. +  2001-12-13  Marcus Brinkmann  <[email protected]>  	* rungpg.c (_gpgme_gpg_spawn): Do not add the fds to the child @@ -130,7 +137,7 @@  	* engine-gpgsm.c (_gpgme_gpgsm_op_decrypt): New function.  	(_gpgme_gpgsm_op_import): Likewise. -2001-11-22  Marcus Brinkmann  <[email protected]> +2001-11-22  Marcus Brinkmann  <[email protected]>  	* engine-gpgsm.c: Shuffle around header inclusion a bit, to still  	keep them seperate. diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 887e9ef9..456de4f9 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -83,8 +83,13 @@ struct gpgsm_object_s    {      GpgColonLineHandler fnc;      void *fnc_value; -  } colon; -   +    struct +    { +      unsigned char *line; +      int linesize; +      int linelen; +    } attic; +  } colon;   };  const char * @@ -144,6 +149,12 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)    gpgsm->message_fd = -1;    gpgsm->message_fd_server = -1; +  gpgsm->status.fnc = 0; +  gpgsm->colon.fnc = 0; +  gpgsm->colon.attic.line = 0; +  gpgsm->colon.attic.linesize = 0; +  gpgsm->colon.attic.linelen = 0; +    if (_gpgme_io_pipe (fds, 0) < 0)      {        err = mk_error (General_Error); @@ -222,6 +233,7 @@ _gpgme_gpgsm_release (GpgsmObject gpgsm)    assuan_pipe_disconnect (gpgsm->assuan_ctx); +  xfree (gpgsm->colon.attic.line);    xfree (gpgsm->command);    xfree (gpgsm);  } @@ -529,36 +541,66 @@ gpgsm_status_handler (void *opaque, int pid, int fd)        if (linelen > 2  	  && line[0] == 'D' && line[1] == ' ' -          && gpgsm->colon.fnc ) +          && gpgsm->colon.fnc)          { -          unsigned char *s, *d; - -          line += 2; -          linelen -= 2; -          /* Hmmm, we are using the colon handler even for plain -             inline data - strange name for that fucntion but for -             historic reasons we keep it */ -          for (s=d=line; linelen; linelen--) +	  /* We are using the colon handler even for plain inline data +             - strange name for that function but for historic reasons +             we keep it.  */ +          /* FIXME We can't use this for binary data because we +             assume this is a string.  For the current usage of colon +             output it is correct.  */ +          unsigned char *src = line + 2; +	  unsigned char *end = line + linelen; +	  unsigned char *dst; +          unsigned char **aline = &gpgsm->colon.attic.line; +	  int *alinelen = &gpgsm->colon.attic.linelen; + +	  if (gpgsm->colon.attic.linesize +	      < *alinelen + linelen + 1) +	    { +	      unsigned char *newline = xtryrealloc (*aline, +						    *alinelen + linelen + 1); +	      if (!newline) +		return mk_error (Out_Of_Core); +	      *aline = newline; +	      gpgsm->colon.attic.linesize += linelen + 1; +	    } + +	  dst = *aline + *alinelen; + +          while (src < end)              { -              if (*s == '%' && linelen > 2) -                { /* handle escaping */ -                  s++; -                  *d++ = xtoi_2 (s); -                  s += 2; -                  linelen -= 2; +              if (*src == '%' && src + 2 < end) +                { +		  /* Handle escaped characters.  */ +		  ++src; +                  *dst = xtoi_2 (src); +		  (*alinelen)++; +                  src += 2;                  }                else -                *d++ = *s++; +		{ +		  *dst = *src++; +		  (*alinelen)++; +		} + +	      if (*dst == '\n') +		{ +		  /* Terminate the pending line, pass it to the colon +		     handler and reset it.  */ + +		  if (*alinelen > 1 && *(dst - 1) == '\r') +		    dst--; +		  *dst = '\0'; + +		  /* FIXME How should we handle the return code? */ +		  gpgsm->colon.fnc (gpgsm->colon.fnc_value, *aline); +		  dst = *aline; +		  *alinelen = 0; +		} +	      else +		dst++;              } -          *d = 0; /* add a hidden string terminator */ - -          /* fixme: should we handle the return code? */ -          /* fixme: Hmmm: we can't use this for binary data because we -             assume this is a string.  For the current usage of colon -             output it is correct */ -          /* FIXME: we need extra bufferring to pass colon lines line -             by line */ -          gpgsm->colon.fnc (gpgsm->colon.fnc_value, line);          }        else if (linelen > 2  	  && line[0] == 'S' && line[1] == ' ') diff --git a/tests/ChangeLog b/tests/ChangeLog index 897885ac..fa8712ad 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2001-12-14  Marcus Brinkmann  <[email protected]> + +	* gpgsm/t-keylist.c: New file. +	* gpgsm/Makefile.am (TESTS): Add t-keylist. +  2001-12-13  Marcus Brinkmann  <[email protected]>  	* gpgsm/cert_dfn_pca01.der: New file. diff --git a/tests/gpgsm/Makefile.am b/tests/gpgsm/Makefile.am index 89d54672..bf724fb4 100644 --- a/tests/gpgsm/Makefile.am +++ b/tests/gpgsm/Makefile.am @@ -22,7 +22,7 @@  TESTS_ENVIRONMENT = GNUPGHOME=. -TESTS = t-import +TESTS = t-import t-keylist  EXTRA_DIST = cert_dfn_pca01.der cert_dfn_pca15.der cert_g10code_test1.der diff --git a/tests/gpgsm/t-keylist.c b/tests/gpgsm/t-keylist.c new file mode 100644 index 00000000..9ead110e --- /dev/null +++ b/tests/gpgsm/t-keylist.c @@ -0,0 +1,160 @@ +/* t-keylist.c  - regression test + *	Copyright (C) 2000 Werner Koch (dd9jn) + *      Copyright (C) 2001 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include <gpgme.h> + +#define fail_if_err(a) do { if(a) {                                       \ +                               fprintf (stderr, "%s:%d: GpgmeError %s\n", \ +                                __FILE__, __LINE__, gpgme_strerror(a));   \ +                                exit (1); }                               \ +                             } while(0) + +static void +doit ( GpgmeCtx ctx, const char *pattern ) +{ +    GpgmeError err; +    GpgmeKey key; + +    err = gpgme_op_keylist_start (ctx, pattern, 0 ); +    fail_if_err (err); +     +    while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) { +        char *p; +        const char *s; +        int i; + +        printf ("<!-- Begin key object (%p) -->\n", key ); +        p = gpgme_key_get_as_xml ( key ); +        if ( p ) { +            fputs ( p, stdout ); +            free (p); +        } +        else +            fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout ); + +         +        for (i=0; ; i++ ) { +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, i ); +            if (!s) +                break; +            printf ("<!-- keyid.%d=%s -->\n", i, s ); +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, i ); +            printf ("<!-- algo.%d=%s -->\n", i, s ); +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEY_CAPS, NULL, i ); +            printf ("<!-- caps.%d=%s -->\n", i, s ); +        } +        for (i=0; ; i++ ) { +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, i ); +            if (!s) +                break; +            printf ("<!-- name.%d=%s -->\n", i, s ); +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, i ); +            printf ("<!-- email.%d=%s -->\n", i, s ); +            s = gpgme_key_get_string_attr (key, GPGME_ATTR_COMMENT, NULL, i ); +            printf ("<!-- comment.%d=%s -->\n", i, s ); +        } +         +        fputs ("<!-- usable for:", stdout ); +        if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_ENCRYPT, NULL, 0 )) +            fputs (" encryption", stdout); +        if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_SIGN, NULL, 0 )) +            fputs (" signing", stdout); +        if ( gpgme_key_get_ulong_attr (key, GPGME_ATTR_CAN_CERTIFY, NULL, 0 )) +            fputs (" certification", stdout); +        fputs (" -->\n", stdout ); + +        printf ("<!-- End key object (%p) -->\n", key ); +        gpgme_key_release (key); +    } +    if ( err != GPGME_EOF ) +        fail_if_err (err); +} + + +/*  + * Check that there are no problems when we are using two context for + * listing keys.  + */ +static void +check_two_contexts (void) +{ +    GpgmeError err; +    GpgmeCtx ctx1, ctx2; +    GpgmeKey key; +	 +    err = gpgme_new(&ctx1); fail_if_err (err); +    err = gpgme_op_keylist_start(ctx1, "", 1); fail_if_err (err); +    err = gpgme_new(&ctx2); fail_if_err (err); +    err = gpgme_op_keylist_start(ctx2, "", 1); fail_if_err (err); + +    while ( (err=gpgme_op_keylist_next(ctx2, &key)) != GPGME_EOF) { +        gpgme_key_release (key); +    } +    if (err != GPGME_EOF) +        fail_if_err (err); +    while ( (err=gpgme_op_keylist_next(ctx1, &key)) != GPGME_EOF) { +        gpgme_key_release (key); +    } +    if (err != GPGME_EOF) +        fail_if_err (err); +} + +int  +main (int argc, char **argv ) +{ +    GpgmeCtx ctx; +    GpgmeError err; +    int loop = 0; +    const char *pattern; +     +    if( argc ) { +        argc--; argv++; +    } +     +    if (argc && !strcmp( *argv, "--loop" ) ) { +        loop = 1; +        argc--; argv++; +    } +    pattern = argc? *argv : NULL; + +    err = gpgme_check_engine(); +    fail_if_err (err); + +    err = gpgme_new (&ctx); +    fail_if_err (err); +    gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS); + +    gpgme_set_keylist_mode (ctx, 1); /* no validity calculation */ +    do { +        fprintf (stderr, "** pattern=`%s'\n", pattern ); +        doit ( ctx, pattern ); +    } while ( loop ); +    gpgme_release (ctx); + +    check_two_contexts (); + +    return 0; +}  | 
