From cvs at cvs.gnupg.org Thu Oct 1 11:56:51 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 01 Oct 2009 11:56:51 +0200 Subject: [svn] GnuPG - r5169 - trunk/g10 Message-ID: Author: wk Date: 2009-10-01 11:56:51 +0200 (Thu, 01 Oct 2009) New Revision: 5169 Modified: trunk/g10/plaintext.c Log: Re-indented. Modified: trunk/g10/plaintext.c =================================================================== --- trunk/g10/plaintext.c 2009-09-30 18:47:11 UTC (rev 5168) +++ trunk/g10/plaintext.c 2009-10-01 09:56:51 UTC (rev 5169) @@ -1,6 +1,6 @@ /* plaintext.c - process plaintext packets * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * 2006, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -26,7 +26,7 @@ #include #include #ifdef HAVE_DOSISH_SYSTEM -#include /* for setmode() */ +# include /* for setmode() */ #endif #include "gpg.h" @@ -40,412 +40,450 @@ #include "i18n.h" -/**************** - * Handle a plaintext packet. If MFX is not NULL, update the MDs - * Note: we should use the filter stuff here, but we have to add some - * easy mimic to set a read limit, so we calculate only the - * bytes from the plaintext. - */ +/* Handle a plaintext packet. If MFX is not NULL, update the MDs + * Note: We should have used the filter stuff here, but we have to add + * some easy mimic to set a read limit, so we calculate only the bytes + * from the plaintext. */ int -handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, - int nooutput, int clearsig ) +handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx, + int nooutput, int clearsig) { - char *fname = NULL; - FILE *fp = NULL; - static off_t count=0; - int rc = 0; - int c; - int convert = (pt->mode == 't' || pt->mode == 'u'); + char *fname = NULL; + FILE *fp = NULL; + static off_t count = 0; + int rc = 0; + int c; + int convert = (pt->mode == 't' || pt->mode == 'u'); #ifdef __riscos__ - int filetype = 0xfff; + int filetype = 0xfff; #endif - /* Let people know what the plaintext info is. This allows the - receiving program to try and do something different based on - the format code (say, recode UTF-8 to local). */ - if(!nooutput && is_status_enabled()) - { - char status[50]; + /* Let people know what the plaintext info is. This allows the + receiving program to try and do something different based on the + format code (say, recode UTF-8 to local). */ + if (!nooutput && is_status_enabled ()) + { + char status[50]; - /* Better make sure that stdout has been flushed in case the - output will be written to it. This is to make sure that no - not-yet-flushed stuff will be written after the plaintext - status message. */ - fflush (stdout); + /* Better make sure that stdout has been flushed in case the + output will be written to it. This is to make sure that no + not-yet-flushed stuff will be written after the plaintext + status message. */ + fflush (stdout); - sprintf(status,"%X %lu ",(byte)pt->mode,(ulong)pt->timestamp); - write_status_text_and_buffer(STATUS_PLAINTEXT, - status,pt->name,pt->namelen,0); - - if(!pt->is_partial) - { - sprintf(status,"%lu",(ulong)pt->len); - write_status_text(STATUS_PLAINTEXT_LENGTH,status); - } - } - - /* create the filename as C string */ - if( nooutput ) - ; - else if( opt.outfile ) { - fname = xmalloc( strlen( opt.outfile ) + 1); - strcpy(fname, opt.outfile ); + snprintf (status, sizeof status, + "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp); + write_status_text_and_buffer (STATUS_PLAINTEXT, + status, pt->name, pt->namelen, 0); + + if (!pt->is_partial) + { + sprintf (status, "%lu", (ulong) pt->len); + write_status_text (STATUS_PLAINTEXT_LENGTH, status); + } } - else if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) ) { - log_info(_("data not saved; use option \"--output\" to save it\n")); - nooutput = 1; + + /* Create the filename as C string. */ + if (nooutput) + ; + else if (opt.outfile) + { + fname = xmalloc (strlen (opt.outfile) + 1); + strcpy (fname, opt.outfile); } - else if( !opt.flags.use_embedded_filename ) { - fname = make_outfile_name( iobuf_get_real_fname(pt->buf) ); - if( !fname ) - fname = ask_outfile_name( pt->name, pt->namelen ); - if( !fname ) { - rc = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */ - goto leave; + else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8)) + { + log_info (_("data not saved; use option \"--output\" to save it\n")); + nooutput = 1; + } + else if (!opt.flags.use_embedded_filename) + { + fname = make_outfile_name (iobuf_get_real_fname (pt->buf)); + if (!fname) + fname = ask_outfile_name (pt->name, pt->namelen); + if (!fname) + { + rc = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */ + goto leave; } } - else - fname=utf8_to_native(pt->name,pt->namelen,0); + else + fname = utf8_to_native (pt->name, pt->namelen, 0); - if( nooutput ) - ; - else if ( iobuf_is_pipe_filename (fname) || !*fname) - { - /* No filename or "-" given; write to stdout. */ - fp = stdout; + if (nooutput) + ; + else if (iobuf_is_pipe_filename (fname) || !*fname) + { + /* No filename or "-" given; write to stdout. */ + fp = stdout; #ifdef HAVE_DOSISH_SYSTEM - setmode ( fileno(fp) , O_BINARY ); + setmode (fileno (fp), O_BINARY); #endif - } - else { - while( !overwrite_filep (fname) ) { - char *tmp = ask_outfile_name (NULL, 0); - if ( !tmp || !*tmp ) { - xfree (tmp); - rc = gpg_error (GPG_ERR_GENERAL); /* G10ERR_CREATE_FILE*/ - goto leave; - } - xfree (fname); - fname = tmp; - } } - + else + { + while (!overwrite_filep (fname)) + { + char *tmp = ask_outfile_name (NULL, 0); + if (!tmp || !*tmp) + { + xfree (tmp); + /* FIXME: Below used to be G10ERR_CREATE_FILE */ + rc = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + xfree (fname); + fname = tmp; + } + } + #ifndef __riscos__ - if( fp || nooutput ) - ; - else if (is_secured_filename (fname)) - { - errno = EPERM; - rc = gpg_error_from_syserror (); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - goto leave; - } - else if( !(fp = fopen(fname,"wb")) ) { - rc = gpg_error_from_syserror (); - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - goto leave; + if (fp || nooutput) + ; + else if (is_secured_filename (fname)) + { + errno = EPERM; + rc = gpg_error_from_syserror (); + log_error (_("error creating `%s': %s\n"), fname, strerror (errno)); + goto leave; } + else if (!(fp = fopen (fname, "wb"))) + { + rc = gpg_error_from_syserror (); + log_error (_("error creating `%s': %s\n"), fname, strerror (errno)); + goto leave; + } #else /* __riscos__ */ - /* If no output filename was given, i.e. we constructed it, - convert all '.' in fname to '/' but not vice versa as - we don't create directories! */ - if( !opt.outfile ) - for( c=0; fname[c]; ++c ) - if( fname[c] == '.' ) - fname[c] = '/'; + /* If no output filename was given, i.e. we constructed it, + convert all '.' in fname to '/' but not vice versa as + we don't create directories! */ + if (!opt.outfile) + for (c = 0; fname[c]; ++c) + if (fname[c] == '.') + fname[c] = '/'; - if( fp || nooutput ) - ; - else { - fp = fopen(fname,"wb"); - if( !fp ) { - log_error(_("error creating `%s': %s\n"), fname, strerror(errno) ); - rc = G10ERR_CREATE_FILE; - if (errno == 106) - log_info("Do output file and input file have the same name?\n"); - goto leave; + if (fp || nooutput) + ; + else + { + fp = fopen (fname, "wb"); + if (!fp) + { + log_error (_("error creating `%s': %s\n"), fname, strerror (errno)); + rc = G10ERR_CREATE_FILE; + if (errno == 106) + log_info ("Do output file and input file have the same name?\n"); + goto leave; } - /* If there's a ,xxx extension in the embedded filename, - use that, else check whether the user input (in fname) - has a ,xxx appended, then use that in preference */ - if( (c = riscos_get_filetype_from_string( pt->name, - pt->namelen )) != -1 ) - filetype = c; - if( (c = riscos_get_filetype_from_string( fname, - strlen(fname) )) != -1 ) - filetype = c; - riscos_set_filetype_by_number(fname, filetype); + /* If there's a ,xxx extension in the embedded filename, + use that, else check whether the user input (in fname) + has a ,xxx appended, then use that in preference */ + if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1) + filetype = c; + if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1) + filetype = c; + riscos_set_filetype_by_number (fname, filetype); } #endif /* __riscos__ */ - if( !pt->is_partial ) { - /* We have an actual length (which might be zero). */ + if (!pt->is_partial) + { + /* We have an actual length (which might be zero). */ - if (clearsig) { - log_error ("clearsig encountered while not expected\n"); - rc = G10ERR_UNEXPECTED; - goto leave; - } + if (clearsig) + { + log_error ("clearsig encountered while not expected\n"); + rc = G10ERR_UNEXPECTED; + goto leave; + } - if( convert ) { /* text mode */ - for( ; pt->len; pt->len-- ) { - if( (c = iobuf_get(pt->buf)) == -1 ) { - rc = gpg_error_from_syserror (); - log_error ("problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - goto leave; + if (convert) /* Text mode. */ + { + for (; pt->len; pt->len--) + { + if ((c = iobuf_get (pt->buf)) == -1) + { + rc = gpg_error_from_syserror (); + log_error ("problem reading source (%u bytes remaining)\n", + (unsigned) pt->len); + goto leave; } - if( mfx->md ) - gcry_md_putc (mfx->md, c ); + if (mfx->md) + gcry_md_putc (mfx->md, c); #ifndef HAVE_DOSISH_SYSTEM - if( c == '\r' ) /* convert to native line ending */ - continue; /* fixme: this hack might be too simple */ + if (c == '\r') /* convert to native line ending */ + continue; /* fixme: this hack might be too simple */ #endif - if( fp ) - { - if(opt.max_output && (++count)>opt.max_output) - { - log_error ("error writing to `%s': %s\n", - fname,"exceeded --max-output limit\n"); - rc = gpg_error (GPG_ERR_TOO_LARGE); - goto leave; - } - else if( putc( c, fp ) == EOF ) - { - if (ferror (fp)) - rc = gpg_error_from_syserror (); - else - rc = gpg_error (GPG_ERR_EOF); - log_error ("error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } + if (fp) + { + if (opt.max_output && (++count) > opt.max_output) + { + log_error ("error writing to `%s': %s\n", + fname, "exceeded --max-output limit\n"); + rc = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + else if (putc (c, fp) == EOF) + { + if (ferror (fp)) + rc = gpg_error_from_syserror (); + else + rc = gpg_error (GPG_ERR_EOF); + log_error ("error writing to `%s': %s\n", + fname, strerror (errno)); + goto leave; + } + } } } - else { /* binary mode */ - byte *buffer = xmalloc( 32768 ); - while( pt->len ) { - int len = pt->len > 32768 ? 32768 : pt->len; - len = iobuf_read( pt->buf, buffer, len ); - if( len == -1 ) { - rc = gpg_error_from_syserror (); - log_error ("problem reading source (%u bytes remaining)\n", - (unsigned)pt->len); - xfree( buffer ); - goto leave; + else /* Binary mode. */ + { + byte *buffer = xmalloc (32768); + while (pt->len) + { + int len = pt->len > 32768 ? 32768 : pt->len; + len = iobuf_read (pt->buf, buffer, len); + if (len == -1) + { + rc = gpg_error_from_syserror (); + log_error ("problem reading source (%u bytes remaining)\n", + (unsigned) pt->len); + xfree (buffer); + goto leave; } - if( mfx->md ) - gcry_md_write ( mfx->md, buffer, len ); - if( fp ) - { - if(opt.max_output && (count+=len)>opt.max_output) - { - log_error ("error writing to `%s': %s\n", - fname,"exceeded --max-output limit\n"); - rc = gpg_error (GPG_ERR_TOO_LARGE); - xfree( buffer ); - goto leave; - } - else if( fwrite( buffer, 1, len, fp ) != len ) - { - rc = gpg_error_from_syserror (); - log_error ("error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree( buffer ); - goto leave; - } - } - pt->len -= len; + if (mfx->md) + gcry_md_write (mfx->md, buffer, len); + if (fp) + { + if (opt.max_output && (count += len) > opt.max_output) + { + log_error ("error writing to `%s': %s\n", + fname, "exceeded --max-output limit\n"); + rc = gpg_error (GPG_ERR_TOO_LARGE); + xfree (buffer); + goto leave; + } + else if (fwrite (buffer, 1, len, fp) != len) + { + rc = gpg_error_from_syserror (); + log_error ("error writing to `%s': %s\n", + fname, strerror (errno)); + xfree (buffer); + goto leave; + } + } + pt->len -= len; } - xfree( buffer ); + xfree (buffer); } } - else if( !clearsig ) { - if( convert ) { /* text mode */ - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( mfx->md ) - gcry_md_putc (mfx->md, c ); + else if (!clearsig) + { + if (convert) + { /* text mode */ + while ((c = iobuf_get (pt->buf)) != -1) + { + if (mfx->md) + gcry_md_putc (mfx->md, c); #ifndef HAVE_DOSISH_SYSTEM - if( convert && c == '\r' ) - continue; /* fixme: this hack might be too simple */ + if (convert && c == '\r') + continue; /* fixme: this hack might be too simple */ #endif - if( fp ) - { - if(opt.max_output && (++count)>opt.max_output) - { - log_error("Error writing to `%s': %s\n", - fname,"exceeded --max-output limit\n"); - rc = gpg_error (GPG_ERR_TOO_LARGE); - goto leave; - } - else if( putc( c, fp ) == EOF ) - { - if ( ferror (fp ) ) - rc = gpg_error_from_syserror (); - else - rc = gpg_error (GPG_ERR_EOF); - log_error("error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } + if (fp) + { + if (opt.max_output && (++count) > opt.max_output) + { + log_error ("Error writing to `%s': %s\n", + fname, "exceeded --max-output limit\n"); + rc = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + else if (putc (c, fp) == EOF) + { + if (ferror (fp)) + rc = gpg_error_from_syserror (); + else + rc = gpg_error (GPG_ERR_EOF); + log_error ("error writing to `%s': %s\n", + fname, strerror (errno)); + goto leave; + } + } } } - else { /* binary mode */ - byte *buffer = xmalloc( 32768 ); - int eof_seen = 0; + else + { /* binary mode */ + byte *buffer = xmalloc (32768); + int eof_seen = 0; - while ( !eof_seen ) { - /* Why do we check for len < 32768: - * If we won't, we would practically read 2 EOFs but - * the first one has already popped the block_filter - * off and therefore we don't catch the boundary. - * So, always assume EOF if iobuf_read returns less bytes - * then requested */ - int len = iobuf_read( pt->buf, buffer, 32768 ); - if( len == -1 ) - break; - if( len < 32768 ) - eof_seen = 1; - if( mfx->md ) - gcry_md_write ( mfx->md, buffer, len ); - if( fp ) - { - if(opt.max_output && (count+=len)>opt.max_output) - { - log_error("error writing to `%s': %s\n", - fname,"exceeded --max-output limit\n"); - rc = gpg_error (GPG_ERR_TOO_LARGE); - xfree( buffer ); - goto leave; - } - else if( fwrite( buffer, 1, len, fp ) != len ) { - rc = (errno? gpg_error_from_syserror () - : gpg_error (GPG_ERR_INTERNAL)); + while (!eof_seen) + { + /* Why do we check for len < 32768: + * If we won't, we would practically read 2 EOFs but + * the first one has already popped the block_filter + * off and therefore we don't catch the boundary. + * So, always assume EOF if iobuf_read returns less bytes + * then requested */ + int len = iobuf_read (pt->buf, buffer, 32768); + if (len == -1) + break; + if (len < 32768) + eof_seen = 1; + if (mfx->md) + gcry_md_write (mfx->md, buffer, len); + if (fp) + { + if (opt.max_output && (count += len) > opt.max_output) + { log_error ("error writing to `%s': %s\n", - fname, strerror(errno) ); - xfree( buffer ); + fname, "exceeded --max-output limit\n"); + rc = gpg_error (GPG_ERR_TOO_LARGE); + xfree (buffer); goto leave; } - } + else if (fwrite (buffer, 1, len, fp) != len) + { + rc = (errno ? gpg_error_from_syserror () + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error writing to `%s': %s\n", + fname, strerror (errno)); + xfree (buffer); + goto leave; + } + } } - xfree( buffer ); + xfree (buffer); } - pt->buf = NULL; + pt->buf = NULL; } - else { /* clear text signature - don't hash the last cr,lf */ - int state = 0; + else /* Clear text signature - don't hash the last CR,LF. */ + { + int state = 0; - while( (c = iobuf_get(pt->buf)) != -1 ) { - if( fp ) - { - if(opt.max_output && (++count)>opt.max_output) - { - log_error ("error writing to `%s': %s\n", - fname,"exceeded --max-output limit\n"); - rc = gpg_error (GPG_ERR_TOO_LARGE); - goto leave; - } - else if( putc( c, fp ) == EOF ) - { - rc = (errno? gpg_error_from_syserror () - : gpg_error (GPG_ERR_INTERNAL)); - log_error ("error writing to `%s': %s\n", - fname, strerror(errno) ); - goto leave; - } - } - if( !mfx->md ) - continue; - if( state == 2 ) { - gcry_md_putc (mfx->md, '\r' ); - gcry_md_putc (mfx->md, '\n' ); - state = 0; + while ((c = iobuf_get (pt->buf)) != -1) + { + if (fp) + { + if (opt.max_output && (++count) > opt.max_output) + { + log_error ("error writing to `%s': %s\n", + fname, "exceeded --max-output limit\n"); + rc = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + else if (putc (c, fp) == EOF) + { + rc = (errno ? gpg_error_from_syserror () + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error writing to `%s': %s\n", + fname, strerror (errno)); + goto leave; + } } - if( !state ) { - if( c == '\r' ) + if (!mfx->md) + continue; + if (state == 2) + { + gcry_md_putc (mfx->md, '\r'); + gcry_md_putc (mfx->md, '\n'); + state = 0; + } + if (!state) + { + if (c == '\r') + state = 1; + else if (c == '\n') + state = 2; + else + gcry_md_putc (mfx->md, c); + } + else if (state == 1) + { + if (c == '\n') + state = 2; + else + { + gcry_md_putc (mfx->md, '\r'); + if (c == '\r') state = 1; - else if( c == '\n' ) - state = 2; - else - gcry_md_putc(mfx->md, c ); - } - else if( state == 1 ) { - if( c == '\n' ) - state = 2; - else { - gcry_md_putc(mfx->md, '\r' ); - if( c == '\r' ) - state = 1; - else { - state = 0; - gcry_md_putc(mfx->md, c ); + else + { + state = 0; + gcry_md_putc (mfx->md, c); } } } } - pt->buf = NULL; + pt->buf = NULL; } - if( fp && fp != stdout && fclose(fp) ) { - rc = (errno? gpg_error_from_syserror () - : gpg_error (GPG_ERR_INTERNAL)); - log_error ("error closing `%s': %s\n", fname, strerror(errno) ); - fp = NULL; - goto leave; + if (fp && fp != stdout && fclose (fp)) + { + rc = (errno ? gpg_error_from_syserror () + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error closing `%s': %s\n", fname, strerror (errno)); + fp = NULL; + goto leave; } - fp = NULL; + fp = NULL; - leave: - /* Make sure that stdout gets flushed after the plaintext has - been handled. This is for extra security as we do a - flush anyway before checking the signature. */ - fflush (stdout); + leave: + /* Make sure that stdout gets flushed after the plaintext has been + handled. This is for extra security as we do a flush anyway + before checking the signature. */ + fflush (stdout); - if( fp && fp != stdout ) - fclose (fp); - xfree(fname); - return rc; + if (fp && fp != stdout) + fclose (fp); + xfree (fname); + return rc; } + static void -do_hash( gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode ) +do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode) { - text_filter_context_t tfx; - int c; + text_filter_context_t tfx; + int c; - if( textmode ) { - memset( &tfx, 0, sizeof tfx); - iobuf_push_filter( fp, text_filter, &tfx ); + if (textmode) + { + memset (&tfx, 0, sizeof tfx); + iobuf_push_filter (fp, text_filter, &tfx); } - if( md2 ) { /* work around a strange behaviour in pgp2 */ - /* It seems that at least PGP5 converts a single CR to a CR,LF too */ - int lc = -1; - while( (c = iobuf_get(fp)) != -1 ) { - if( c == '\n' && lc == '\r' ) - gcry_md_putc (md2, c); - else if( c == '\n' ) { - gcry_md_putc (md2, '\r'); - gcry_md_putc (md2, c); + if (md2) + { /* work around a strange behaviour in pgp2 */ + /* It seems that at least PGP5 converts a single CR to a CR,LF too */ + int lc = -1; + while ((c = iobuf_get (fp)) != -1) + { + if (c == '\n' && lc == '\r') + gcry_md_putc (md2, c); + else if (c == '\n') + { + gcry_md_putc (md2, '\r'); + gcry_md_putc (md2, c); } - else if( c != '\n' && lc == '\r' ) { - gcry_md_putc (md2, '\n'); - gcry_md_putc (md2, c); + else if (c != '\n' && lc == '\r') + { + gcry_md_putc (md2, '\n'); + gcry_md_putc (md2, c); } - else - gcry_md_putc (md2, c); + else + gcry_md_putc (md2, c); - if( md ) - gcry_md_putc (md, c ); - lc = c; + if (md) + gcry_md_putc (md, c); + lc = c; } } - else { - while( (c = iobuf_get(fp)) != -1 ) { - if( md ) - gcry_md_putc (md, c ); + else + { + while ((c = iobuf_get (fp)) != -1) + { + if (md) + gcry_md_putc (md, c); } } } @@ -457,68 +495,75 @@ */ int ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2, - const char *inname, int textmode ) + const char *inname, int textmode) { - progress_filter_context_t *pfx; - char *answer = NULL; - IOBUF fp; - int rc = 0; + progress_filter_context_t *pfx; + char *answer = NULL; + IOBUF fp; + int rc = 0; - pfx = new_progress_context (); - fp = open_sigfile ( inname, pfx ); /* Open default file. */ + pfx = new_progress_context (); + fp = open_sigfile (inname, pfx); /* Open default file. */ - if( !fp && !opt.batch ) { - int any=0; - tty_printf(_("Detached signature.\n")); - do { - char *name; + if (!fp && !opt.batch) + { + int any = 0; + tty_printf (_("Detached signature.\n")); + do + { + char *name; - xfree(answer); - tty_enable_completion(NULL); - name = cpr_get("detached_signature.filename", - _("Please enter name of data file: ")); - tty_disable_completion(); - cpr_kill_prompt(); - answer=make_filename(name,(void *)NULL); - xfree(name); + xfree (answer); + tty_enable_completion (NULL); + name = cpr_get ("detached_signature.filename", + _("Please enter name of data file: ")); + tty_disable_completion (); + cpr_kill_prompt (); + answer = make_filename (name, (void *) NULL); + xfree (name); - if( any && !*answer ) { - rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE*/ - goto leave; + if (any && !*answer) + { + rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE */ + goto leave; } - fp = iobuf_open(answer); - if (fp && is_secured_file (iobuf_get_fd (fp))) - { - iobuf_close (fp); - fp = NULL; - errno = EPERM; - } - if( !fp && errno == ENOENT ) { - tty_printf("No such file, try again or hit enter to quit.\n"); - any++; + fp = iobuf_open (answer); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; } - else if( !fp ) - { - rc = gpg_error_from_syserror (); - log_error(_("can't open `%s': %s\n"), answer, strerror(errno)); - goto leave; - } - } while( !fp ); + if (!fp && errno == ENOENT) + { + tty_printf ("No such file, try again or hit enter to quit.\n"); + any++; + } + else if (!fp) + { + rc = gpg_error_from_syserror (); + log_error (_("can't open `%s': %s\n"), answer, + strerror (errno)); + goto leave; + } + } + while (!fp); } - if( !fp ) { - if( opt.verbose ) - log_info(_("reading stdin ...\n")); - fp = iobuf_open( NULL ); - assert(fp); + if (!fp) + { + if (opt.verbose) + log_info (_("reading stdin ...\n")); + fp = iobuf_open (NULL); + assert (fp); } - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); + do_hash (md, md2, fp, textmode); + iobuf_close (fp); - leave: - xfree(answer); - release_progress_context (pfx); - return rc; +leave: + xfree (answer); + release_progress_context (pfx); + return rc; } @@ -528,60 +573,64 @@ * If FILES is NULL, hash stdin. */ int -hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files, - const char *sigfilename, int textmode ) +hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files, + const char *sigfilename, int textmode) { - progress_filter_context_t *pfx; - IOBUF fp; - strlist_t sl; + progress_filter_context_t *pfx; + IOBUF fp; + strlist_t sl; - pfx = new_progress_context (); + pfx = new_progress_context (); - if( !files ) { - /* check whether we can open the signed material */ - fp = open_sigfile( sigfilename, pfx ); - if( fp ) { - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); - release_progress_context (pfx); - return 0; + if (!files) + { + /* check whether we can open the signed material */ + fp = open_sigfile (sigfilename, pfx); + if (fp) + { + do_hash (md, md2, fp, textmode); + iobuf_close (fp); + release_progress_context (pfx); + return 0; } - log_error (_("no signed data\n")); - release_progress_context (pfx); - return gpg_error (GPG_ERR_NO_DATA); + log_error (_("no signed data\n")); + release_progress_context (pfx); + return gpg_error (GPG_ERR_NO_DATA); } - for (sl=files; sl; sl = sl->next ) { - fp = iobuf_open( sl->d ); - if (fp && is_secured_file (iobuf_get_fd (fp))) - { - iobuf_close (fp); - fp = NULL; - errno = EPERM; - } - if( !fp ) { - int rc = gpg_error_from_syserror (); - log_error(_("can't open signed data `%s'\n"), - print_fname_stdin(sl->d)); - release_progress_context (pfx); - return rc; + for (sl = files; sl; sl = sl->next) + { + fp = iobuf_open (sl->d); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; } - handle_progress (pfx, fp, sl->d); - do_hash( md, md2, fp, textmode ); - iobuf_close(fp); + if (!fp) + { + int rc = gpg_error_from_syserror (); + log_error (_("can't open signed data `%s'\n"), + print_fname_stdin (sl->d)); + release_progress_context (pfx); + return rc; + } + handle_progress (pfx, fp, sl->d); + do_hash (md, md2, fp, textmode); + iobuf_close (fp); } - release_progress_context (pfx); - return 0; + release_progress_context (pfx); + return 0; } /* Hash the data from file descriptor DATA_FD and append the hash to hash contexts MD and MD2. */ int -hash_datafile_by_fd ( gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd, - int textmode ) +hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd, + int textmode) { progress_filter_context_t *pfx = new_progress_context (); iobuf_t fp; @@ -593,21 +642,21 @@ fp = NULL; errno = EPERM; } - if ( !fp ) + if (!fp) { int rc = gpg_error_from_syserror (); - log_error ( _("can't open signed data fd=%d: %s\n"), - data_fd, strerror (errno)); + log_error (_("can't open signed data fd=%d: %s\n"), + data_fd, strerror (errno)); release_progress_context (pfx); return rc; } handle_progress (pfx, fp, NULL); - do_hash ( md, md2, fp, textmode); + do_hash (md, md2, fp, textmode); - iobuf_close(fp); - + iobuf_close (fp); + release_progress_context (pfx); return 0; } @@ -619,26 +668,26 @@ filenames at all, set the field empty. */ PKT_plaintext * -setup_plaintext_name(const char *filename,IOBUF iobuf) +setup_plaintext_name (const char *filename, IOBUF iobuf) { PKT_plaintext *pt; - if(filename || opt.set_filename) + if (filename || opt.set_filename) { char *s; - if(opt.set_filename) - s=make_basename(opt.set_filename,iobuf_get_real_fname(iobuf)); - else if(filename && !opt.flags.utf8_filename) + if (opt.set_filename) + s = make_basename (opt.set_filename, iobuf_get_real_fname (iobuf)); + else if (filename && !opt.flags.utf8_filename) { - char *tmp=native_to_utf8(filename); - s=make_basename(tmp,iobuf_get_real_fname(iobuf)); - xfree(tmp); + char *tmp = native_to_utf8 (filename); + s = make_basename (tmp, iobuf_get_real_fname (iobuf)); + xfree (tmp); } else - s=make_basename(filename,iobuf_get_real_fname(iobuf)); + s = make_basename (filename, iobuf_get_real_fname (iobuf)); - pt = xmalloc (sizeof *pt + strlen(s) - 1); + pt = xmalloc (sizeof *pt + strlen (s) - 1); pt->namelen = strlen (s); memcpy (pt->name, s, pt->namelen); xfree (s); From cvs at cvs.gnupg.org Fri Oct 2 11:15:11 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 02 Oct 2009 11:15:11 +0200 Subject: [svn] GnuPG - r5170 - trunk/g10 Message-ID: Author: wk Date: 2009-10-02 11:15:10 +0200 (Fri, 02 Oct 2009) New Revision: 5170 Modified: trunk/g10/parse-packet.c Log: Re-indented [The diff below has been truncated] Modified: trunk/g10/parse-packet.c =================================================================== --- trunk/g10/parse-packet.c 2009-10-01 09:56:51 UTC (rev 5169) +++ trunk/g10/parse-packet.c 2009-10-02 09:15:10 UTC (rev 5170) @@ -1,6 +1,6 @@ /* parse-packet.c - read packets * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * 2007, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -15,7 +15,7 @@ * 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, see . + * along with this program; if not, see . */ #include @@ -39,63 +39,64 @@ static int list_mode; static FILE *listfp; -static int parse( IOBUF inp, PACKET *pkt, int onlykeypkts, - off_t *retpos, int *skip, IOBUF out, int do_skip +static int parse (IOBUF inp, PACKET * pkt, int onlykeypkts, + off_t * retpos, int *skip, IOBUF out, int do_skip #ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l + , const char *dbg_w, const char *dbg_f, int dbg_l #endif - ); -static int copy_packet( IOBUF inp, IOBUF out, int pkttype, - unsigned long pktlen, int partial ); -static void skip_packet( IOBUF inp, int pkttype, - unsigned long pktlen, int partial ); -static void *read_rest( IOBUF inp, size_t pktlen, int partial ); -static int parse_marker( IOBUF inp, int pkttype, unsigned long pktlen ); -static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen, - PKT_onepass_sig *ops ); -static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen, - byte *hdr, int hdrlen, PACKET *packet ); -static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet ); -static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb, int partial); -static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb ); -static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb, int partial); -static int parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet, int new_ctb); -static int parse_gpg_control( IOBUF inp, int pkttype, unsigned long pktlen, - PACKET *packet, int partial ); + ); +static int copy_packet (IOBUF inp, IOBUF out, int pkttype, + unsigned long pktlen, int partial); +static void skip_packet (IOBUF inp, int pkttype, + unsigned long pktlen, int partial); +static void *read_rest (IOBUF inp, size_t pktlen, int partial); +static int parse_marker (IOBUF inp, int pkttype, unsigned long pktlen); +static int parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static int parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static int parse_onepass_sig (IOBUF inp, int pkttype, unsigned long pktlen, + PKT_onepass_sig * ops); +static int parse_key (IOBUF inp, int pkttype, unsigned long pktlen, + byte * hdr, int hdrlen, PACKET * packet); +static int parse_user_id (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static int parse_attribute (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static int parse_comment (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static void parse_trust (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet); +static int parse_plaintext (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet, int new_ctb, int partial); +static int parse_compressed (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet, int new_ctb); +static int parse_encrypted (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet, int new_ctb, int partial); +static int parse_mdc (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet, int new_ctb); +static int parse_gpg_control (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet, int partial); static unsigned short -read_16(IOBUF inp) +read_16 (IOBUF inp) { - unsigned short a; - a = iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; + unsigned short a; + a = iobuf_get_noeof (inp) << 8; + a |= iobuf_get_noeof (inp); + return a; } + static unsigned long -read_32(IOBUF inp) +read_32 (IOBUF inp) { - unsigned long a; - a = iobuf_get_noeof(inp) << 24; - a |= iobuf_get_noeof(inp) << 16; - a |= iobuf_get_noeof(inp) << 8; - a |= iobuf_get_noeof(inp); - return a; + unsigned long a; + a = iobuf_get_noeof (inp) << 24; + a |= iobuf_get_noeof (inp) << 16; + a |= iobuf_get_noeof (inp) << 8; + a |= iobuf_get_noeof (inp); + return a; } @@ -103,12 +104,11 @@ * external format is a 16 bit unsigned value stored in network byte * order, giving the number of bits for the following integer. The * integer is stored with MSB first (left padded with zeroes to align - * on a byte boundary). - */ + * on a byte boundary). */ static gcry_mpi_t mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) { - /*FIXME: Needs to be synced with gnupg14/mpi/mpicoder.c*/ + /*FIXME: Needs to be synced with gnupg14/mpi/mpicoder.c */ int c, c1, c2, i; unsigned int nbits, nbytes; @@ -116,27 +116,27 @@ gcry_mpi_t a = NULL; byte *buf = NULL; byte *p; - - if ( (c = c1 = iobuf_get (inp)) == -1 ) + + if ((c = c1 = iobuf_get (inp)) == -1) goto leave; nbits = c << 8; - if ( (c = c2 = iobuf_get (inp)) == -1 ) + if ((c = c2 = iobuf_get (inp)) == -1) goto leave; nbits |= c; - if ( nbits > MAX_EXTERN_MPI_BITS ) + if (nbits > MAX_EXTERN_MPI_BITS) { - log_error("mpi too large (%u bits)\n", nbits); + log_error ("mpi too large (%u bits)\n", nbits); goto leave; } nread = 2; - nbytes = (nbits+7) / 8; + nbytes = (nbits + 7) / 8; buf = secure ? gcry_xmalloc_secure (nbytes + 2) : gcry_xmalloc (nbytes + 2); p = buf; p[0] = c1; p[1] = c2; - for ( i=0 ; i < nbytes; i++ ) + for (i = 0; i < nbytes; i++) { - p[i+2] = iobuf_get(inp) & 0xff; + p[i + 2] = iobuf_get (inp) & 0xff; nread++; } @@ -148,13 +148,13 @@ } else { - if ( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) ) - a = NULL; + if (gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buf, nread, &nread)) + a = NULL; } leave: - gcry_free(buf); - if ( nread > *ret_nread ) + gcry_free (buf); + if (nread > *ret_nread) log_bug ("mpi larger than packet"); else *ret_nread = nread; @@ -162,963 +162,1036 @@ } - - int -set_packet_list_mode( int mode ) +set_packet_list_mode (int mode) { - int old = list_mode; - list_mode = mode; - /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */ - /* We use stdout print only if invoked by the --list-packets - command but switch to stderr in all otehr cases. This breaks - the previous behaviour but that seems to be more of a bug than - intentional. I don't believe that any application makes use of - this long standing annoying way of printing to stdout except - when doing a --list-packets. If this assumption fails, it will - be easy to add an option for the listing stream. Note that we - initialize it only once; mainly because some code may switch - the option value later back to 1 and we want to have all output - to the same stream. + int old = list_mode; + list_mode = mode; + /* FIXME(gcrypt) mpi_print_mode = DBG_MPI; */ + /* We use stdout print only if invoked by the --list-packets command + but switch to stderr in all otehr cases. This breaks the + previous behaviour but that seems to be more of a bug than + intentional. I don't believe that any application makes use of + this long standing annoying way of printing to stdout except when + doing a --list-packets. If this assumption fails, it will be easy + to add an option for the listing stream. Note that we initialize + it only once; mainly because some code may switch the option + value later back to 1 and we want to have all output to the same + stream. - Using stderr is not actually very clean because it bypasses the - logging code but it is a special thing anyay. I am not sure - whether using log_stream() would be better. Perhaps we should - enable the list mdoe only with a special option. */ - if (!listfp) - listfp = opt.list_packets == 2 ? stdout : stderr; - return old; + Using stderr is not actually very clean because it bypasses the + logging code but it is a special thing anyay. I am not sure + whether using log_stream() would be better. Perhaps we should + enable the list mdoe only with a special option. */ + if (!listfp) + listfp = opt.list_packets == 2 ? stdout : stderr; + return old; } + static void -unknown_pubkey_warning( int algo ) +unknown_pubkey_warning (int algo) { - static byte unknown_pubkey_algos[256]; + static byte unknown_pubkey_algos[256]; - algo &= 0xff; - if( !unknown_pubkey_algos[algo] ) { - if( opt.verbose ) - log_info(_("can't handle public key algorithm %d\n"), algo ); - unknown_pubkey_algos[algo] = 1; + algo &= 0xff; + if (!unknown_pubkey_algos[algo]) + { + if (opt.verbose) + log_info (_("can't handle public key algorithm %d\n"), algo); + unknown_pubkey_algos[algo] = 1; } } -/**************** - * Parse a Packet and return it in packet + +/* Parse a packet and return it in packet structure. * Returns: 0 := valid packet in pkt * -1 := no more packets * >0 := error * Note: The function may return an error and a partly valid packet; - * caller must free this packet. - */ + * caller must free this packet. */ #ifdef DEBUG_PARSE_PACKET int -dbg_parse_packet( IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l ) +dbg_parse_packet (IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l) { - int skip, rc; + int skip, rc; - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l ); - } while( skip ); - return rc; + do + { + rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l); + } + while (skip); + return rc; } -#else +#else /*!DEBUG_PARSE_PACKET*/ int -parse_packet( IOBUF inp, PACKET *pkt ) +parse_packet (IOBUF inp, PACKET * pkt) { - int skip, rc; + int skip, rc; - do { - rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 ); - } while( skip ); - return rc; + do + { + rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0); + } + while (skip); + return rc; } -#endif +#endif /*!DEBUG_PARSE_PACKET*/ -/**************** - * Like parse packet, but only return secret or public (sub)key packets. + +/* + * Like parse packet, but only return secret or public (sub)key + * packets. */ #ifdef DEBUG_PARSE_PACKET int -dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid, - const char *dbg_f, int dbg_l ) +dbg_search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid, + const char *dbg_f, int dbg_l) { - int skip, rc; + int skip, rc; - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l ); - } while( skip ); - return rc; + do + { + rc = + parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search", + dbg_f, dbg_l); + } + while (skip); + return rc; } -#else +#else /*!DEBUG_PARSE_PACKET*/ int -search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid ) +search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid) { - int skip, rc; + int skip, rc; - do { - rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 ); - } while( skip ); - return rc; + do + { + rc = parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0); + } + while (skip); + return rc; } -#endif +#endif /*!DEBUG_PARSE_PACKET*/ -/**************** + +/* * Copy all packets from INP to OUT, thereby removing unused spaces. */ #ifdef DEBUG_PARSE_PACKET int -dbg_copy_all_packets( IOBUF inp, IOBUF out, - const char *dbg_f, int dbg_l ) +dbg_copy_all_packets (IOBUF inp, IOBUF out, const char *dbg_f, int dbg_l) { - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l ))); - return rc; + PACKET pkt; + int skip, rc = 0; + do + { + init_packet (&pkt); + } + while (! + (rc = + parse (inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l))); + return rc; } -#else +#else /*!DEBUG_PARSE_PACKET*/ int -copy_all_packets( IOBUF inp, IOBUF out ) +copy_all_packets (IOBUF inp, IOBUF out) { - PACKET pkt; - int skip, rc=0; - do { - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 ))); - return rc; + PACKET pkt; + int skip, rc = 0; + do + { + init_packet (&pkt); + } + while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0))); + return rc; } -#endif +#endif /*!DEBUG_PARSE_PACKET*/ -/**************** + +/* * Copy some packets from INP to OUT, thereby removing unused spaces. - * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets) + * Stop at offset STOPoff (i.e. don't copy packets at this or later + * offsets) */ #ifdef DEBUG_PARSE_PACKET int -dbg_copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff, - const char *dbg_f, int dbg_l ) +dbg_copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff, + const char *dbg_f, int dbg_l) { - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0, - "some", dbg_f, dbg_l )) ); - return rc; + PACKET pkt; + int skip, rc = 0; + do + { + if (iobuf_tell (inp) >= stopoff) + return 0; + init_packet (&pkt); + } + while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0, + "some", dbg_f, dbg_l))); + return rc; } -#else +#else /*!DEBUG_PARSE_PACKET*/ int -copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff ) +copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff) { - PACKET pkt; - int skip, rc=0; - do { - if( iobuf_tell(inp) >= stopoff ) - return 0; - init_packet(&pkt); - } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) ); - return rc; + PACKET pkt; + int skip, rc = 0; + do + { + if (iobuf_tell (inp) >= stopoff) + return 0; + init_packet (&pkt); + } + while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0))); + return rc; } -#endif +#endif /*!DEBUG_PARSE_PACKET*/ -/**************** + +/* * Skip over N packets */ #ifdef DEBUG_PARSE_PACKET int -dbg_skip_some_packets( IOBUF inp, unsigned n, - const char *dbg_f, int dbg_l ) +dbg_skip_some_packets (IOBUF inp, unsigned n, const char *dbg_f, int dbg_l) { - int skip, rc=0; - PACKET pkt; + int skip, rc = 0; + PACKET pkt; - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l ); + for (; n && !rc; n--) + { + init_packet (&pkt); + rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l); } - return rc; + return rc; } -#else +#else /*!DEBUG_PARSE_PACKET*/ int -skip_some_packets( IOBUF inp, unsigned n ) +skip_some_packets (IOBUF inp, unsigned n) { - int skip, rc=0; - PACKET pkt; + int skip, rc = 0; + PACKET pkt; - for( ;n && !rc; n--) { - init_packet(&pkt); - rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 ); + for (; n && !rc; n--) + { + init_packet (&pkt); + rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1); } - return rc; + return rc; } -#endif +#endif /*!DEBUG_PARSE_PACKET*/ -/**************** - * Parse packet. Set the variable skip points to 1 if the packet - * should be skipped; this is the case if either ONLYKEYPKTS is set - * and the parsed packet isn't one or the - * packet-type is 0, indicating deleted stuff. - * if OUT is not NULL, a special copymode is used. +/* + * Parse packet. Stores 1 at SKIP 1 if the packet should be skipped; + * this is the case if either ONLYKEYPKTS is set and the parsed packet + * isn't a key packet or the packet-type is 0, indicating deleted + * stuff. If OUT is not NULL, a special copymode is used. */ static int -parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos, +parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos, int *skip, IOBUF out, int do_skip #ifdef DEBUG_PARSE_PACKET - ,const char *dbg_w, const char *dbg_f, int dbg_l + , const char *dbg_w, const char *dbg_f, int dbg_l #endif - ) + ) { - int rc=0, c, ctb, pkttype, lenbytes; - unsigned long pktlen; - byte hdr[8]; - int hdrlen; - int new_ctb = 0, partial=0; - int with_uid = (onlykeypkts == 2); + int rc = 0, c, ctb, pkttype, lenbytes; + unsigned long pktlen; + byte hdr[8]; + int hdrlen; + int new_ctb = 0, partial = 0; + int with_uid = (onlykeypkts == 2); - *skip = 0; - assert( !pkt->pkt.generic ); - if( retpos ) - *retpos = iobuf_tell(inp); + *skip = 0; + assert (!pkt->pkt.generic); + if (retpos) + *retpos = iobuf_tell (inp); - if( (ctb = iobuf_get(inp)) == -1 ) { - rc = -1; - goto leave; + if ((ctb = iobuf_get (inp)) == -1) + { + rc = -1; + goto leave; } - hdrlen=0; - hdr[hdrlen++] = ctb; - if( !(ctb & 0x80) ) { - log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + hdrlen = 0; + hdr[hdrlen++] = ctb; + if (!(ctb & 0x80)) + { + log_error ("%s: invalid packet (ctb=%02x)\n", iobuf_where (inp), ctb); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - pktlen = 0; - new_ctb = !!(ctb & 0x40); - if( new_ctb ) { - pkttype = ctb & 0x3f; - if( (c = iobuf_get(inp)) == -1 ) { - log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + pktlen = 0; + new_ctb = !!(ctb & 0x40); + if (new_ctb) + { + pkttype = ctb & 0x3f; + if ((c = iobuf_get (inp)) == -1) + { + log_error ("%s: 1st length byte missing\n", iobuf_where (inp)); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } -/* The follwing code has been here for ages (2002-08-30) but it is - clearly wrong: For example passing a 0 as second argument to - iobuf_set_partial_block_mode stops the partial block mode which we - definitely do not want. Also all values < 224 or 255 are not - valid. Let's disable it and put PKT_COMPRESSED into the list of - allowed packets with partial header until someone complains. */ -/* if (pkttype == PKT_COMPRESSED) { */ -/* iobuf_set_partial_block_mode(inp, c & 0xff); */ -/* pktlen = 0; /\* to indicate partial length *\/ */ -/* partial=1; */ -/* } */ -/* else */ + + hdr[hdrlen++] = c; + if (c < 192) + pktlen = c; + else if (c < 224) { - hdr[hdrlen++] = c; - if( c < 192 ) - pktlen = c; - else if( c < 224 ) - { - pktlen = (c - 192) * 256; - if( (c = iobuf_get(inp)) == -1 ) - { - log_error("%s: 2nd length byte missing\n", - iobuf_where(inp) ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - hdr[hdrlen++] = c; - pktlen += c + 192; - } - else if( c == 255 ) - { - pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; - pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; - if( (c = iobuf_get(inp)) == -1 ) - { - log_error("%s: 4 byte length invalid\n", - iobuf_where(inp) ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - pktlen |= (hdr[hdrlen++] = c ); - } - else - { - /* Partial body length. */ - switch (pkttype) - { - case PKT_PLAINTEXT: - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - case PKT_COMPRESSED: - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* To indicate partial length. */ - partial=1; - break; + pktlen = (c - 192) * 256; + if ((c = iobuf_get (inp)) == -1) + { + log_error ("%s: 2nd length byte missing\n", + iobuf_where (inp)); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + hdr[hdrlen++] = c; + pktlen += c + 192; + } + else if (c == 255) + { + pktlen = (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 24; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 16; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof (inp)) << 8; + if ((c = iobuf_get (inp)) == -1) + { + log_error ("%s: 4 byte length invalid\n", iobuf_where (inp)); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + pktlen |= (hdr[hdrlen++] = c); + } + else /* Partial body length. */ + { + switch (pkttype) + { + case PKT_PLAINTEXT: + case PKT_ENCRYPTED: + case PKT_ENCRYPTED_MDC: + case PKT_COMPRESSED: + iobuf_set_partial_block_mode (inp, c & 0xff); + pktlen = 0; /* To indicate partial length. */ + partial = 1; + break; - default: - log_error("%s: partial length for invalid" - " packet type %d\n", iobuf_where(inp),pkttype); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - } + default: + log_error ("%s: partial length for invalid" + " packet type %d\n", iobuf_where (inp), pkttype); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + } + + } + else + { + pkttype = (ctb >> 2) & 0xf; + lenbytes = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3)); + if (!lenbytes) + { + pktlen = 0; /* Don't know the value. */ + /* This isn't really partial, but we can treat it the same + in a "read until the end" sort of way. */ + partial = 1; + if (pkttype != PKT_ENCRYPTED && pkttype != PKT_PLAINTEXT + && pkttype != PKT_COMPRESSED) + { + log_error ("%s: indeterminate length for invalid" + " packet type %d\n", iobuf_where (inp), pkttype); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } } + else + { + for (; lenbytes; lenbytes--) + { + pktlen <<= 8; + pktlen |= hdr[hdrlen++] = iobuf_get_noeof (inp); + } + } } - else - { - pkttype = (ctb>>2)&0xf; - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - if( !lenbytes ) - { - pktlen = 0; /* don't know the value */ - /* This isn't really partial, but we can treat it the same - in a "read until the end" sort of way. */ - partial=1; - if(pkttype!=PKT_ENCRYPTED && pkttype!=PKT_PLAINTEXT - && pkttype!=PKT_COMPRESSED) - { - log_error ("%s: indeterminate length for invalid" - " packet type %d\n", iobuf_where(inp), pkttype ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - } - else - { - for( ; lenbytes; lenbytes-- ) - { - pktlen <<= 8; - pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp); - } - } - } - if (pktlen == (unsigned long)(-1)) { - /* With some probability this is caused by a problem in the - * the uncompressing layer - in some error cases it just loops - * and spits out 0xff bytes. */ - log_error ("%s: garbled packet detected\n", iobuf_where(inp) ); - g10_exit (2); + if (pktlen == (unsigned long) (-1)) + { + /* With some probability this is caused by a problem in the + * the uncompressing layer - in some error cases it just loops + * and spits out 0xff bytes. */ + log_error ("%s: garbled packet detected\n", iobuf_where (inp)); + g10_exit (2); } - if( out && pkttype ) { + if (out && pkttype) + { rc = iobuf_write (out, hdr, hdrlen); if (!rc) - rc = copy_packet(inp, out, pkttype, pktlen, partial ); + rc = copy_packet (inp, out, pkttype, pktlen, partial); goto leave; } - if (with_uid && pkttype == PKT_USER_ID) - ; - else if( do_skip - || !pkttype - || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY - && pkttype != PKT_PUBLIC_KEY - && pkttype != PKT_SECRET_SUBKEY - && pkttype != PKT_SECRET_KEY ) ) { - iobuf_skip_rest(inp, pktlen, partial); - *skip = 1; - rc = 0; - goto leave; + if (with_uid && pkttype == PKT_USER_ID) + ; + else if (do_skip + || !pkttype + || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY + && pkttype != PKT_PUBLIC_KEY + && pkttype != PKT_SECRET_SUBKEY && pkttype != PKT_SECRET_KEY)) + { + iobuf_skip_rest (inp, pktlen, partial); + *skip = 1; + rc = 0; + goto leave; } - if( DBG_PACKET ) { + if (DBG_PACKET) + { #ifdef DEBUG_PARSE_PACKET - log_debug("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"", - dbg_w, dbg_f, dbg_l ); + log_debug ("parse_packet(iob=%d): type=%d length=%lu%s (%s.%s.%d)\n", + iobuf_id (inp), pkttype, pktlen, new_ctb ? " (new_ctb)" : "", + dbg_w, dbg_f, dbg_l); #else - log_debug("parse_packet(iob=%d): type=%d length=%lu%s\n", - iobuf_id(inp), pkttype, pktlen, new_ctb?" (new_ctb)":"" ); + log_debug ("parse_packet(iob=%d): type=%d length=%lu%s\n", + iobuf_id (inp), pkttype, pktlen, + new_ctb ? " (new_ctb)" : ""); #endif } - pkt->pkttype = pkttype; - rc = G10ERR_UNKNOWN_PACKET; /* default error */ - switch( pkttype ) { - case PKT_PUBLIC_KEY: - case PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = xmalloc_clear(sizeof *pkt->pkt.public_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SECRET_KEY: - case PKT_SECRET_SUBKEY: - pkt->pkt.secret_key = xmalloc_clear(sizeof *pkt->pkt.secret_key ); - rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt ); - break; - case PKT_SYMKEY_ENC: - rc = parse_symkeyenc( inp, pkttype, pktlen, pkt ); - break; - case PKT_PUBKEY_ENC: - rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt ); - break; - case PKT_SIGNATURE: - pkt->pkt.signature = xmalloc_clear(sizeof *pkt->pkt.signature ); - rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature ); - break; - case PKT_ONEPASS_SIG: - pkt->pkt.onepass_sig = xmalloc_clear(sizeof *pkt->pkt.onepass_sig ); - rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig ); - break; - case PKT_USER_ID: - rc = parse_user_id(inp, pkttype, pktlen, pkt ); - break; - case PKT_ATTRIBUTE: - pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */ - rc = parse_attribute(inp, pkttype, pktlen, pkt); - break; - case PKT_OLD_COMMENT: - case PKT_COMMENT: - rc = parse_comment(inp, pkttype, pktlen, pkt); - break; - case PKT_RING_TRUST: - parse_trust(inp, pkttype, pktlen, pkt); - rc = 0; - break; - case PKT_PLAINTEXT: - rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb, partial ); - break; - case PKT_COMPRESSED: - rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_ENCRYPTED: - case PKT_ENCRYPTED_MDC: - rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb, partial ); - break; - case PKT_MDC: - rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb ); - break; - case PKT_GPG_CONTROL: - rc = parse_gpg_control(inp, pkttype, pktlen, pkt, partial ); - break; + + pkt->pkttype = pkttype; + rc = G10ERR_UNKNOWN_PACKET; /* default error */ + switch (pkttype) + { + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key); + rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt); + break; + case PKT_SECRET_KEY: + case PKT_SECRET_SUBKEY: + pkt->pkt.secret_key = xmalloc_clear (sizeof *pkt->pkt.secret_key); + rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt); + break; + case PKT_SYMKEY_ENC: + rc = parse_symkeyenc (inp, pkttype, pktlen, pkt); + break; + case PKT_PUBKEY_ENC: + rc = parse_pubkeyenc (inp, pkttype, pktlen, pkt); + break; + case PKT_SIGNATURE: + pkt->pkt.signature = xmalloc_clear (sizeof *pkt->pkt.signature); + rc = parse_signature (inp, pkttype, pktlen, pkt->pkt.signature); + break; + case PKT_ONEPASS_SIG: + pkt->pkt.onepass_sig = xmalloc_clear (sizeof *pkt->pkt.onepass_sig); + rc = parse_onepass_sig (inp, pkttype, pktlen, pkt->pkt.onepass_sig); + break; + case PKT_USER_ID: + rc = parse_user_id (inp, pkttype, pktlen, pkt); + break; + case PKT_ATTRIBUTE: + pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */ + rc = parse_attribute (inp, pkttype, pktlen, pkt); + break; + case PKT_OLD_COMMENT: + case PKT_COMMENT: + rc = parse_comment (inp, pkttype, pktlen, pkt); + break; + case PKT_RING_TRUST: + parse_trust (inp, pkttype, pktlen, pkt); + rc = 0; + break; + case PKT_PLAINTEXT: + rc = parse_plaintext (inp, pkttype, pktlen, pkt, new_ctb, partial); + break; + case PKT_COMPRESSED: + rc = parse_compressed (inp, pkttype, pktlen, pkt, new_ctb); + break; + case PKT_ENCRYPTED: + case PKT_ENCRYPTED_MDC: + rc = parse_encrypted (inp, pkttype, pktlen, pkt, new_ctb, partial); + break; + case PKT_MDC: + rc = parse_mdc (inp, pkttype, pktlen, pkt, new_ctb); + break; + case PKT_GPG_CONTROL: + rc = parse_gpg_control (inp, pkttype, pktlen, pkt, partial); + break; case PKT_MARKER: - rc = parse_marker(inp,pkttype,pktlen); - break; - default: - skip_packet(inp, pkttype, pktlen, partial); - break; + rc = parse_marker (inp, pkttype, pktlen); + break; + default: + skip_packet (inp, pkttype, pktlen, partial); + break; } - leave: - if( !rc && iobuf_error(inp) ) - rc = G10ERR_INV_KEYRING; - return rc; + leave: + if (!rc && iobuf_error (inp)) + rc = G10ERR_INV_KEYRING; + return rc; } + static void -dump_hex_line( int c, int *i ) +dump_hex_line (int c, int *i) { - if( *i && !(*i%8) ) { - if( *i && !(*i%24) ) - fprintf (listfp, "\n%4d:", *i ); - else - putc (' ', listfp); + if (*i && !(*i % 8)) + { + if (*i && !(*i % 24)) + fprintf (listfp, "\n%4d:", *i); + else + putc (' ', listfp); } - if( c == -1 ) - fprintf (listfp, " EOF" ); - else - fprintf (listfp, " %02x", c ); - ++*i; + if (c == -1) + fprintf (listfp, " EOF"); + else + fprintf (listfp, " %02x", c); + ++*i; } static int -copy_packet( IOBUF inp, IOBUF out, int pkttype, - unsigned long pktlen, int partial ) +copy_packet (IOBUF inp, IOBUF out, int pkttype, + unsigned long pktlen, int partial) { - int rc; - int n; - char buf[100]; + int rc; + int n; + char buf[100]; - if( partial ) { - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc=iobuf_write(out, buf, n )) ) - return rc; /* write error */ + if (partial) + { + while ((n = iobuf_read (inp, buf, 100)) != -1) + if ((rc = iobuf_write (out, buf, n))) + return rc; /* write error */ } - else if( !pktlen && pkttype == PKT_COMPRESSED ) { - log_debug("copy_packet: compressed!\n"); - /* compressed packet, copy till EOF */ - while( (n = iobuf_read( inp, buf, 100 )) != -1 ) - if( (rc=iobuf_write(out, buf, n )) ) - return rc; /* write error */ + else if (!pktlen && pkttype == PKT_COMPRESSED) + { + log_debug ("copy_packet: compressed!\n"); + /* compressed packet, copy till EOF */ + while ((n = iobuf_read (inp, buf, 100)) != -1) + if ((rc = iobuf_write (out, buf, n))) + return rc; /* write error */ } - else { - for( ; pktlen; pktlen -= n ) { - n = pktlen > 100 ? 100 : pktlen; - n = iobuf_read( inp, buf, n ); - if( n == -1 ) - return gpg_error (GPG_ERR_EOF); - if( (rc=iobuf_write(out, buf, n )) ) - return rc; /* write error */ + else + { + for (; pktlen; pktlen -= n) + { + n = pktlen > 100 ? 100 : pktlen; + n = iobuf_read (inp, buf, n); + if (n == -1) + return gpg_error (GPG_ERR_EOF); + if ((rc = iobuf_write (out, buf, n))) + return rc; /* write error */ } } - return 0; + return 0; } static void -skip_packet( IOBUF inp, int pkttype, unsigned long pktlen, int partial ) +skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial) { - if( list_mode ) + if (list_mode) { fprintf (listfp, ":unknown packet: type %2d, length %lu\n", pkttype, pktlen); - if( pkttype ) + if (pkttype) { - int c, i=0 ; - fputs("dump:", listfp ); - if( partial ) + int c, i = 0; + fputs ("dump:", listfp); + if (partial) { - while( (c=iobuf_get(inp)) != -1 ) - dump_hex_line(c, &i); + while ((c = iobuf_get (inp)) != -1) + dump_hex_line (c, &i); } else { - for( ; pktlen; pktlen-- ) - { - dump_hex_line( (c=iobuf_get(inp)), &i); - if (c == -1) - break; - } + for (; pktlen; pktlen--) + { + dump_hex_line ((c = iobuf_get (inp)), &i); + if (c == -1) + break; + } } putc ('\n', listfp); return; } } - iobuf_skip_rest(inp,pktlen,partial); + iobuf_skip_rest (inp, pktlen, partial); } + static void * -read_rest( IOBUF inp, size_t pktlen, int partial ) +read_rest (IOBUF inp, size_t pktlen, int partial) { - byte *p; - int i; + byte *p; + int i; - if( partial ) { - log_error("read_rest: can't store stream data\n"); - p = NULL; + if (partial) + { + log_error ("read_rest: can't store stream data\n"); + p = NULL; } - else { - p = xmalloc( pktlen ); - for(i=0; pktlen; pktlen--, i++ ) - p[i] = iobuf_get(inp); + else + { + p = xmalloc (pktlen); + for (i = 0; pktlen; pktlen--, i++) + p[i] = iobuf_get (inp); } - return p; + return p; } + static int -parse_marker( IOBUF inp, int pkttype, unsigned long pktlen ) +parse_marker (IOBUF inp, int pkttype, unsigned long pktlen) { - (void)pkttype; + (void) pkttype; - if(pktlen!=3) + if (pktlen != 3) goto fail; - if(iobuf_get(inp)!='P') + if (iobuf_get (inp) != 'P') { pktlen--; goto fail; } - if(iobuf_get(inp)!='G') + if (iobuf_get (inp) != 'G') { pktlen--; goto fail; } - if(iobuf_get(inp)!='P') + if (iobuf_get (inp) != 'P') { pktlen--; goto fail; } - if(list_mode) - fputs(":marker packet: PGP\n", listfp ); + if (list_mode) + fputs (":marker packet: PGP\n", listfp); return 0; fail: - log_error("invalid marker packet\n"); - iobuf_skip_rest(inp,pktlen,0); + log_error ("invalid marker packet\n"); + iobuf_skip_rest (inp, pktlen, 0); return G10ERR_INVALID_PACKET; } + static int -parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) +parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet) { - PKT_symkey_enc *k; - int rc = 0; - int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; + PKT_symkey_enc *k; + int rc = 0; + int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; - if( pktlen < 4 ) { - log_error("packet(%d) too short\n", pkttype); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + if (pktlen < 4) + { + log_error ("packet(%d) too short\n", pkttype); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - version = iobuf_get_noeof(inp); pktlen--; - if( version != 4 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, version); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + version = iobuf_get_noeof (inp); + pktlen--; + if (version != 4) + { + log_error ("packet(%d) with unknown version %d\n", pkttype, version); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */ - log_error("packet(%d) too large\n", pkttype); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + if (pktlen > 200) + { /* (we encode the seskeylen in a byte) */ + log_error ("packet(%d) too large\n", pkttype); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - cipher_algo = iobuf_get_noeof(inp); pktlen--; - s2kmode = iobuf_get_noeof(inp); pktlen--; - hash_algo = iobuf_get_noeof(inp); pktlen--; - switch( s2kmode ) { - case 0: /* simple s2k */ - minlen = 0; - break; - case 1: /* salted s2k */ - minlen = 8; - break; - case 3: /* iterated+salted s2k */ - minlen = 9; - break; - default: - log_error("unknown S2K %d\n", s2kmode ); - goto leave; + cipher_algo = iobuf_get_noeof (inp); + pktlen--; + s2kmode = iobuf_get_noeof (inp); + pktlen--; + hash_algo = iobuf_get_noeof (inp); + pktlen--; + switch (s2kmode) + { + case 0: /* Simple S2K. */ + minlen = 0; + break; + case 1: /* Salted S2K. */ + minlen = 8; + break; + case 3: /* Iterated+salted S2K. */ + minlen = 9; + break; + default: + log_error ("unknown S2K mode %d\n", s2kmode); + goto leave; } - if( minlen > pktlen ) { - log_error("packet with S2K %d too short\n", s2kmode ); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + if (minlen > pktlen) + { + log_error ("packet with S2K %d too short\n", s2kmode); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - seskeylen = pktlen - minlen; - k = packet->pkt.symkey_enc = xmalloc_clear( sizeof *packet->pkt.symkey_enc - + seskeylen - 1 ); - k->version = version; - k->cipher_algo = cipher_algo; - k->s2k.mode = s2kmode; - k->s2k.hash_algo = hash_algo; - if( s2kmode == 1 || s2kmode == 3 ) { - for(i=0; i < 8 && pktlen; i++, pktlen-- ) - k->s2k.salt[i] = iobuf_get_noeof(inp); + seskeylen = pktlen - minlen; + k = packet->pkt.symkey_enc = xmalloc_clear (sizeof *packet->pkt.symkey_enc + + seskeylen - 1); + k->version = version; + k->cipher_algo = cipher_algo; + k->s2k.mode = s2kmode; + k->s2k.hash_algo = hash_algo; + if (s2kmode == 1 || s2kmode == 3) + { + for (i = 0; i < 8 && pktlen; i++, pktlen--) + k->s2k.salt[i] = iobuf_get_noeof (inp); } - if( s2kmode == 3 ) { - k->s2k.count = iobuf_get(inp); pktlen--; + if (s2kmode == 3) + { + k->s2k.count = iobuf_get (inp); + pktlen--; } - k->seskeylen = seskeylen; - if(k->seskeylen) - { - for(i=0; i < seskeylen && pktlen; i++, pktlen-- ) - k->seskey[i] = iobuf_get_noeof(inp); + k->seskeylen = seskeylen; + if (k->seskeylen) + { + for (i = 0; i < seskeylen && pktlen; i++, pktlen--) + k->seskey[i] = iobuf_get_noeof (inp); - /* What we're watching out for here is a session key decryptor - with no salt. The RFC says that using salt for this is a - MUST. */ - if(s2kmode!=1 && s2kmode!=3) - log_info(_("WARNING: potentially insecure symmetrically" - " encrypted session key\n")); - } - assert( !pktlen ); + /* What we're watching out for here is a session key decryptor + with no salt. The RFC says that using salt for this is a + MUST. */ + if (s2kmode != 1 && s2kmode != 3) + log_info (_("WARNING: potentially insecure symmetrically" + " encrypted session key\n")); + } + assert (!pktlen); - if( list_mode ) { - fprintf (listfp, ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d", + if (list_mode) + { + fprintf (listfp, + ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d", version, cipher_algo, s2kmode, hash_algo); - if(seskeylen) - fprintf (listfp, ", seskey %d bits",(seskeylen-1)*8); - fprintf (listfp, "\n"); - if( s2kmode == 1 || s2kmode == 3 ) { - fprintf (listfp, "\tsalt "); - for(i=0; i < 8; i++ ) - fprintf (listfp, "%02x", k->s2k.salt[i]); - if( s2kmode == 3 ) - fprintf (listfp, ", count %lu (%lu)", - S2K_DECODE_COUNT((ulong)k->s2k.count), - (ulong)k->s2k.count ); - fprintf (listfp, "\n"); + if (seskeylen) + fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8); + fprintf (listfp, "\n"); + if (s2kmode == 1 || s2kmode == 3) + { + fprintf (listfp, "\tsalt "); + for (i = 0; i < 8; i++) + fprintf (listfp, "%02x", k->s2k.salt[i]); + if (s2kmode == 3) + fprintf (listfp, ", count %lu (%lu)", + S2K_DECODE_COUNT ((ulong) k->s2k.count), + (ulong) k->s2k.count); + fprintf (listfp, "\n"); } } - leave: - iobuf_skip_rest(inp, pktlen, 0); - return rc; + leave: + iobuf_skip_rest (inp, pktlen, 0); + return rc; } + static int -parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) +parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, + PACKET * packet) { - unsigned int n; - int rc = 0; - int i, ndata; - PKT_pubkey_enc *k; + unsigned int n; + int rc = 0; + int i, ndata; + PKT_pubkey_enc *k; - k = packet->pkt.pubkey_enc = xmalloc_clear(sizeof *packet->pkt.pubkey_enc); - if( pktlen < 12 ) { - log_error("packet(%d) too short\n", pkttype); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + k = packet->pkt.pubkey_enc = xmalloc_clear (sizeof *packet->pkt.pubkey_enc); + if (pktlen < 12) + { + log_error ("packet(%d) too short\n", pkttype); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - k->version = iobuf_get_noeof(inp); pktlen--; - if( k->version != 2 && k->version != 3 ) { - log_error("packet(%d) with unknown version %d\n", pkttype, k->version); - rc = gpg_error (GPG_ERR_INV_PACKET); - goto leave; + k->version = iobuf_get_noeof (inp); + pktlen--; + if (k->version != 2 && k->version != 3) + { + log_error ("packet(%d) with unknown version %d\n", pkttype, k->version); + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; } - k->keyid[0] = read_32(inp); pktlen -= 4; - k->keyid[1] = read_32(inp); pktlen -= 4; - k->pubkey_algo = iobuf_get_noeof(inp); pktlen--; - k->throw_keyid = 0; /* only used as flag for build_packet */ - if( list_mode ) - fprintf (listfp, ":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n", - k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]); + k->keyid[0] = read_32 (inp); + pktlen -= 4; + k->keyid[1] = read_32 (inp); + pktlen -= 4; + k->pubkey_algo = iobuf_get_noeof (inp); + pktlen--; + k->throw_keyid = 0; /* Only used as flag for build_packet. */ + if (list_mode) + fprintf (listfp, + ":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n", + k->version, k->pubkey_algo, (ulong) k->keyid[0], + (ulong) k->keyid[1]); - ndata = pubkey_get_nenc(k->pubkey_algo); - if( !ndata ) { - if( list_mode ) - fprintf (listfp, "\tunsupported algorithm %d\n", k->pubkey_algo ); - unknown_pubkey_warning( k->pubkey_algo ); - k->data[0] = NULL; /* no need to store the encrypted data */ + ndata = pubkey_get_nenc (k->pubkey_algo); From cvs at cvs.gnupg.org Fri Oct 2 14:31:15 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 02 Oct 2009 14:31:15 +0200 Subject: [svn] GnuPG - r5171 - trunk/g10 Message-ID: Author: wk Date: 2009-10-02 14:31:14 +0200 (Fri, 02 Oct 2009) New Revision: 5171 Modified: trunk/g10/ChangeLog trunk/g10/encr-data.c trunk/g10/parse-packet.c Log: Fixed EOF detection for encrypted packets. The code won't get confused anymore by extra packages following the encrypted one. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-10-02 09:15:10 UTC (rev 5170) +++ trunk/g10/ChangeLog 2009-10-02 12:31:14 UTC (rev 5171) @@ -1,6 +1,16 @@ +2009-10-02 Werner Koch + + * encr-data.c (decode_filter_context_s): Add fields PARTIAL and + LENGTH. + (decrypt_data): Set them. Simplify premature EOF detection. + (mdc_decode_filter): Take fixed length packets in account. + (decode_filter): Ditto. Better EOF detection. + * parse-packet.c (parse_encrypted): Store ed->LEN without the MDC + version byte. + 2009-09-30 Werner Koch - * parse-packet.c (skip_packet, parse_gpg_control) : Take + * parse-packet.c (skip_packet, parse_gpg_control) : Take care of premature EOFs. * gpg.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING. Modified: trunk/g10/encr-data.c =================================================================== --- trunk/g10/encr-data.c 2009-10-02 09:15:10 UTC (rev 5170) +++ trunk/g10/encr-data.c 2009-10-02 12:31:14 UTC (rev 5171) @@ -45,6 +45,8 @@ int defer_filled; int eof_seen; int refcount; + int partial; /* Working on a partial length packet. */ + size_t length; /* If !partial: Remaining bytes in the packet. */ } *decode_filter_ctx_t; @@ -182,6 +184,8 @@ gcry_md_write (dfx->mdc_hash, temp, nprefix+2); dfx->refcount++; + dfx->partial = ed->is_partial; + dfx->length = ed->len; if ( ed->mdc_method ) iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx ); else @@ -189,7 +193,7 @@ proc_packets ( procctx, ed->buf ); ed->buf = NULL; - if ( ed->mdc_method && dfx->eof_seen == 2 ) + if (dfx->eof_seen > 1 ) rc = gpg_error (GPG_ERR_INV_PACKET); else if ( ed->mdc_method ) { @@ -235,7 +239,6 @@ -/* I think we should merge this with cipher_filter */ static int mdc_decode_filter (void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) @@ -244,6 +247,14 @@ size_t n, size = *ret_len; int rc = 0; int c; + + /* Note: We need to distinguish between a partial and a fixed length + packet. The first is the usual case as created by GPG. However + for short messages the format degrades to a fixed length packet + and other implementations might use fixed length as well. Only + looking for the EOF on fixed data works only if the encrypted + packet is not followed by other data. This used to be a long + standing bug which was fixed on 2009-10-02. */ if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) { @@ -253,37 +264,71 @@ else if( control == IOBUFCTRL_UNDERFLOW ) { assert (a); - assert ( size > 44 ); + assert (size > 44); /* Our code requires at least this size. */ - /* Get at least 22 bytes and put it somewhere ahead in the buffer. */ - for (n=22; n < 44 ; n++ ) + /* Get at least 22 bytes and put it ahead in the buffer. */ + if (dfx->partial) { - if( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - if ( n == 44 ) + for (n=22; n < 44; n++) + { + if ( (c = iobuf_get(a)) == -1 ) + break; + buf[n] = c; + } + } + else { + for (n=22; n < 44 && dfx->length; n++, dfx->length--) + { + c = iobuf_get (a); + if (c == -1) + break; /* Premature EOF. */ + buf[n] = c; + } + } + if (n == 44) + { /* We have enough stuff - flush the deferred stuff. */ - /* (we asserted that the buffer is large enough) */ if ( !dfx->defer_filled ) /* First time. */ { - memcpy (buf, buf+22, 22 ); + memcpy (buf, buf+22, 22); n = 22; } else { - memcpy (buf, dfx->defer, 22 ); + memcpy (buf, dfx->defer, 22); } - /* Now fill up. */ - for (; n < size; n++ ) + /* Fill up the buffer. */ + if (dfx->partial) { - if ( (c = iobuf_get(a)) == -1 ) - break; - buf[n] = c; - } - /* Move the last 22 bytes back to the defer buffer. */ - /* (right, we are wasting 22 bytes of the supplied buffer.) */ + for (; n < size; n++ ) + { + if ( (c = iobuf_get(a)) == -1 ) + { + dfx->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[n] = c; + } + } + else + { + for (; n < size && dfx->length; n++, dfx->length--) + { + c = iobuf_get(a); + if (c == -1) + { + dfx->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[n] = c; + } + if (!dfx->length) + dfx->eof_seen = 1; /* Normal EOF. */ + } + + /* Move the trailing 22 bytes back to the defer buffer. We + have at least 44 bytes thus a memmove is not needed. */ n -= 22; memcpy (dfx->defer, buf+n, 22 ); dfx->defer_filled = 1; @@ -313,7 +358,7 @@ else { assert ( dfx->eof_seen ); - rc = -1; /* eof */ + rc = -1; /* Return EOF. */ } *ret_len = n; } @@ -333,22 +378,59 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) { decode_filter_ctx_t fc = opaque; - size_t n, size = *ret_len; - int rc = 0; - - if ( control == IOBUFCTRL_UNDERFLOW ) + size_t size = *ret_len; + size_t n; + int c, rc = 0; + + + if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen ) { + *ret_len = 0; + rc = -1; + } + else if ( control == IOBUFCTRL_UNDERFLOW ) + { assert(a); - n = iobuf_read ( a, buf, size ); - if ( n == -1 ) - n = 0; - if ( n ) + + if (fc->partial) { + for (n=0; n < size; n++ ) + { + c = iobuf_get(a); + if (c == -1) + { + fc->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[n] = c; + } + } + else + { + for (n=0; n < size && fc->length; n++, fc->length--) + { + c = iobuf_get(a); + if (c == -1) + { + fc->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[n] = c; + } + if (!fc->length) + fc->eof_seen = 1; /* Normal EOF. */ + } + if (n) + { if (fc->cipher_hd) gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0); } else - rc = -1; /* EOF */ + { + if (!fc->eof_seen) + fc->eof_seen = 1; + rc = -1; /* Return EOF. */ + } *ret_len = n; } else if ( control == IOBUFCTRL_FREE ) Modified: trunk/g10/parse-packet.c =================================================================== --- trunk/g10/parse-packet.c 2009-10-02 09:15:10 UTC (rev 5170) +++ trunk/g10/parse-packet.c 2009-10-02 12:31:14 UTC (rev 5171) @@ -2617,16 +2617,11 @@ unsigned long orig_pktlen = pktlen; ed = pkt->pkt.encrypted = xmalloc (sizeof *pkt->pkt.encrypted); - ed->len = pktlen; - /* We don't know the extralen which is (cipher_blocksize+2) because - the algorithm ist not specified in this packet. However, it is - only important to know this for some sanity checks on the packet - length - it doesn't matter that we can't do it. */ - ed->extralen = 0; + /* ed->len is set below. */ + ed->extralen = 0; /* Unknown here; only used in build_packet. */ ed->buf = NULL; ed->new_ctb = new_ctb; ed->is_partial = partial; - ed->mdc_method = 0; if (pkttype == PKT_ENCRYPTED_MDC) { /* Fixme: add some pktlen sanity checks. */ @@ -2645,6 +2640,12 @@ } ed->mdc_method = DIGEST_ALGO_SHA1; } + else + ed->mdc_method = 0; + + /* A basic sanity check. We need at least an 8 byte IV plus the 2 + detection bytes. Note that we don't known the algorithm and thus + we may only check against the minimum blocksize. */ if (orig_pktlen && pktlen < 10) { /* Actually this is blocksize+2. */ @@ -2653,6 +2654,12 @@ iobuf_skip_rest (inp, pktlen, partial); goto leave; } + + /* Store the remaining length of the encrypted data (i.e. without + the MDC version number but with the IV etc.). This value is + required during decryption. */ + ed->len = pktlen; + if (list_mode) { if (orig_pktlen) From cvs at cvs.gnupg.org Fri Oct 2 16:57:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 02 Oct 2009 16:57:56 +0200 Subject: [svn] GnuPG - r5172 - trunk/g10 Message-ID: Author: wk Date: 2009-10-02 16:57:55 +0200 (Fri, 02 Oct 2009) New Revision: 5172 Added: trunk/g10/decrypt-data.c Removed: trunk/g10/encr-data.c Modified: trunk/g10/ChangeLog trunk/g10/Makefile.am trunk/g10/decrypt.c trunk/g10/encrypt.c trunk/g10/gpg.c trunk/g10/main.h trunk/g10/openfile.c trunk/g10/options.h trunk/g10/packet.h trunk/g10/plaintext.c trunk/g10/server.c Log: Implement the server comamnd DECRYPT. Use int instead of gnupg_fd_t in the server. Comment fixes. Rename encr-data.c -> decrypt-data.c Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/ChangeLog 2009-10-02 14:57:55 UTC (rev 5172) @@ -1,5 +1,15 @@ 2009-10-02 Werner Koch + * server.c (cmd_encrypt, cmd_decrypt): Implement. + * decrypt.c (decrypt_message_fd): New. + * options.h (struct opt): Add field OUTFP. + * plaintext.c (handle_plaintext): Support opt.outfp. + + * encr-data.c: Rename to decrypt-data.c to reflect the action and + not the processed packet type. + +2009-10-02 Werner Koch + * encr-data.c (decode_filter_context_s): Add fields PARTIAL and LENGTH. (decrypt_data): Set them. Simplify premature EOF detection. Modified: trunk/g10/Makefile.am =================================================================== --- trunk/g10/Makefile.am 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/Makefile.am 2009-10-02 14:57:55 UTC (rev 5172) @@ -79,13 +79,13 @@ pubkey-enc.c \ passphrase.c \ seckey-cert.c \ - encr-data.c \ + decrypt.c \ + decrypt-data.c \ cipher.c \ encrypt.c \ sign.c \ verify.c \ revoke.c \ - decrypt.c \ keyedit.c \ dearmor.c \ import.c \ Copied: trunk/g10/decrypt-data.c (from rev 5171, trunk/g10/encr-data.c) =================================================================== --- trunk/g10/decrypt-data.c (rev 0) +++ trunk/g10/decrypt-data.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -0,0 +1,446 @@ +/* decrypt-data.c - Decrypt an encrypted data packet + * Copyright (C) 1998, 1999, 2000, 2001, 2005, + * 2006, 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include + +#include "gpg.h" +#include "util.h" +#include "packet.h" +#include "cipher.h" +#include "options.h" +#include "i18n.h" + + +static int mdc_decode_filter ( void *opaque, int control, IOBUF a, + byte *buf, size_t *ret_len); +static int decode_filter ( void *opaque, int control, IOBUF a, + byte *buf, size_t *ret_len); + +typedef struct decode_filter_context_s +{ + gcry_cipher_hd_t cipher_hd; + gcry_md_hd_t mdc_hash; + char defer[22]; + int defer_filled; + int eof_seen; + int refcount; + int partial; /* Working on a partial length packet. */ + size_t length; /* If !partial: Remaining bytes in the packet. */ +} *decode_filter_ctx_t; + + +/* Helper to release the decode context. */ +static void +release_dfx_context (decode_filter_ctx_t dfx) +{ + if (!dfx) + return; + + assert (dfx->refcount); + if ( !--dfx->refcount ) + { + gcry_cipher_close (dfx->cipher_hd); + dfx->cipher_hd = NULL; + gcry_md_close (dfx->mdc_hash); + dfx->mdc_hash = NULL; + xfree (dfx); + } +} + + + +/**************** + * Decrypt the data, specified by ED with the key DEK. + */ +int +decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) +{ + decode_filter_ctx_t dfx; + byte *p; + int rc=0, c, i; + byte temp[32]; + unsigned blocksize; + unsigned nprefix; + + dfx = xtrycalloc (1, sizeof *dfx); + if (!dfx) + return gpg_error_from_syserror (); + dfx->refcount = 1; + + if ( opt.verbose && !dek->algo_info_printed ) + { + if (!openpgp_cipher_test_algo (dek->algo)) + log_info (_("%s encrypted data\n"), + openpgp_cipher_algo_name (dek->algo)); + else + log_info (_("encrypted with unknown algorithm %d\n"), dek->algo ); + dek->algo_info_printed = 1; + } + rc = openpgp_cipher_test_algo (dek->algo); + if (rc) + goto leave; + blocksize = openpgp_cipher_get_algo_blklen (dek->algo); + if ( !blocksize || blocksize > 16 ) + log_fatal ("unsupported blocksize %u\n", blocksize ); + nprefix = blocksize; + if ( ed->len && ed->len < (nprefix+2) ) + BUG(); + + if ( ed->mdc_method ) + { + if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 )) + BUG (); + if ( DBG_HASHING ) + gcry_md_start_debug (dfx->mdc_hash, "checkmdc"); + } + + rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo, + GCRY_CIPHER_MODE_CFB, + (GCRY_CIPHER_SECURE + | ((ed->mdc_method || dek->algo >= 100)? + 0 : GCRY_CIPHER_ENABLE_SYNC))); + if (rc) + { + /* We should never get an error here cause we already checked + * that the algorithm is available. */ + BUG(); + } + + + /* log_hexdump( "thekey", dek->key, dek->keylen );*/ + rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); + if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) + { + log_info(_("WARNING: message was encrypted with" + " a weak key in the symmetric cipher.\n")); + rc=0; + } + else if( rc ) + { + log_error("key setup failed: %s\n", g10_errstr(rc) ); + goto leave; + } + + if (!ed->buf) + { + log_error(_("problem handling encrypted packet\n")); + goto leave; + } + + gcry_cipher_setiv (dfx->cipher_hd, NULL, 0); + + if ( ed->len ) + { + for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) + { + if ( (c=iobuf_get(ed->buf)) == -1 ) + break; + else + temp[i] = c; + } + } + else + { + for (i=0; i < (nprefix+2); i++ ) + if ( (c=iobuf_get(ed->buf)) == -1 ) + break; + else + temp[i] = c; + } + + gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0); + gcry_cipher_sync (dfx->cipher_hd); + p = temp; + /* log_hexdump( "prefix", temp, nprefix+2 ); */ + if (dek->symmetric + && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) + { + rc = gpg_error (GPG_ERR_BAD_KEY); + goto leave; + } + + if ( dfx->mdc_hash ) + gcry_md_write (dfx->mdc_hash, temp, nprefix+2); + + dfx->refcount++; + dfx->partial = ed->is_partial; + dfx->length = ed->len; + if ( ed->mdc_method ) + iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx ); + else + iobuf_push_filter ( ed->buf, decode_filter, dfx ); + + proc_packets ( procctx, ed->buf ); + ed->buf = NULL; + if (dfx->eof_seen > 1 ) + rc = gpg_error (GPG_ERR_INV_PACKET); + else if ( ed->mdc_method ) + { + /* We used to let parse-packet.c handle the MDC packet but this + turned out to be a problem with compressed packets: With old + style packets there is no length information available and + the decompressor uses an implicit end. However we can't know + this implicit end beforehand (:-) and thus may feed the + decompressor with more bytes than actually needed. It would + be possible to unread the extra bytes but due to our weird + iobuf system any unread is non reliable due to filters + already popped off. The easy and sane solution is to care + about the MDC packet only here and never pass it to the + packet parser. Fortunatley the OpenPGP spec requires a + strict format for the MDC packet so that we know that 22 + bytes are appended. */ + int datalen = gcry_md_get_algo_dlen (ed->mdc_method); + + assert (dfx->cipher_hd); + assert (dfx->mdc_hash); + gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0); + gcry_md_write (dfx->mdc_hash, dfx->defer, 2); + gcry_md_final (dfx->mdc_hash); + + if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' ) + { + log_error("mdc_packet with invalid encoding\n"); + rc = gpg_error (GPG_ERR_INV_PACKET); + } + else if (datalen != 20 + || memcmp (gcry_md_read (dfx->mdc_hash, 0), + dfx->defer+2,datalen )) + rc = gpg_error (GPG_ERR_BAD_SIGNATURE); + /* log_printhex("MDC message:", dfx->defer, 22); */ + /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */ + } + + + leave: + release_dfx_context (dfx); + return rc; +} + + + +static int +mdc_decode_filter (void *opaque, int control, IOBUF a, + byte *buf, size_t *ret_len) +{ + decode_filter_ctx_t dfx = opaque; + size_t n, size = *ret_len; + int rc = 0; + int c; + + /* Note: We need to distinguish between a partial and a fixed length + packet. The first is the usual case as created by GPG. However + for short messages the format degrades to a fixed length packet + and other implementations might use fixed length as well. Only + looking for the EOF on fixed data works only if the encrypted + packet is not followed by other data. This used to be a long + standing bug which was fixed on 2009-10-02. */ + + if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) + { + *ret_len = 0; + rc = -1; + } + else if( control == IOBUFCTRL_UNDERFLOW ) + { + assert (a); + assert (size > 44); /* Our code requires at least this size. */ + + /* Get at least 22 bytes and put it ahead in the buffer. */ + if (dfx->partial) + { + for (n=22; n < 44; n++) + { + if ( (c = iobuf_get(a)) == -1 ) + break; + buf[n] = c; + } + } + else + { + for (n=22; n < 44 && dfx->length; n++, dfx->length--) + { + c = iobuf_get (a); + if (c == -1) + break; /* Premature EOF. */ + buf[n] = c; + } + } + if (n == 44) + { + /* We have enough stuff - flush the deferred stuff. */ + if ( !dfx->defer_filled ) /* First time. */ + { + memcpy (buf, buf+22, 22); + n = 22; + } + else + { + memcpy (buf, dfx->defer, 22); + } + /* Fill up the buffer. */ + if (dfx->partial) + { + for (; n < size; n++ ) + { + if ( (c = iobuf_get(a)) == -1 ) + { + dfx->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[n] = c; + } + } + else + { + for (; n < size && dfx->length; n++, dfx->length--) + { + c = iobuf_get(a); + if (c == -1) + { + dfx->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[n] = c; + } + if (!dfx->length) + dfx->eof_seen = 1; /* Normal EOF. */ + } + + /* Move the trailing 22 bytes back to the defer buffer. We + have at least 44 bytes thus a memmove is not needed. */ + n -= 22; + memcpy (dfx->defer, buf+n, 22 ); + dfx->defer_filled = 1; + } + else if ( !dfx->defer_filled ) /* EOF seen but empty defer buffer. */ + { + /* This is bad because it means an incomplete hash. */ + n -= 22; + memcpy (buf, buf+22, n ); + dfx->eof_seen = 2; /* EOF with incomplete hash. */ + } + else /* EOF seen (i.e. read less than 22 bytes). */ + { + memcpy (buf, dfx->defer, 22 ); + n -= 22; + memcpy (dfx->defer, buf+n, 22 ); + dfx->eof_seen = 1; /* Normal EOF. */ + } + + if ( n ) + { + if ( dfx->cipher_hd ) + gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0); + if ( dfx->mdc_hash ) + gcry_md_write (dfx->mdc_hash, buf, n); + } + else + { + assert ( dfx->eof_seen ); + rc = -1; /* Return EOF. */ + } + *ret_len = n; + } + else if ( control == IOBUFCTRL_FREE ) + { + release_dfx_context (dfx); + } + else if ( control == IOBUFCTRL_DESC ) + { + *(char**)buf = "mdc_decode_filter"; + } + return rc; +} + + +static int +decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) +{ + decode_filter_ctx_t fc = opaque; + size_t size = *ret_len; + size_t n; + int c, rc = 0; + + + if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen ) + { + *ret_len = 0; + rc = -1; + } + else if ( control == IOBUFCTRL_UNDERFLOW ) + { + assert(a); + + if (fc->partial) + { + for (n=0; n < size; n++ ) + { + c = iobuf_get(a); + if (c == -1) + { + fc->eof_seen = 1; /* Normal EOF. */ + break; + } + buf[n] = c; + } + } + else + { + for (n=0; n < size && fc->length; n++, fc->length--) + { + c = iobuf_get(a); + if (c == -1) + { + fc->eof_seen = 3; /* Premature EOF. */ + break; + } + buf[n] = c; + } + if (!fc->length) + fc->eof_seen = 1; /* Normal EOF. */ + } + if (n) + { + if (fc->cipher_hd) + gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0); + } + else + { + if (!fc->eof_seen) + fc->eof_seen = 1; + rc = -1; /* Return EOF. */ + } + *ret_len = n; + } + else if ( control == IOBUFCTRL_FREE ) + { + release_dfx_context (fc); + } + else if ( control == IOBUFCTRL_DESC ) + { + *(char**)buf = "decode_filter"; + } + return rc; +} + Property changes on: trunk/g10/decrypt-data.c ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Modified: trunk/g10/decrypt.c =================================================================== --- trunk/g10/decrypt.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/decrypt.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -97,6 +97,73 @@ } +/* Same as decrypt_message but takes a file descriptor for input and + output. */ +gpg_error_t +decrypt_message_fd (int input_fd, int output_fd) +{ + gpg_error_t err; + IOBUF fp; + armor_filter_context_t *afx = NULL; + progress_filter_context_t *pfx; + + if (opt.outfp) + return gpg_error (GPG_ERR_BUG); + + pfx = new_progress_context (); + + /* Open the message file. */ + fp = iobuf_open_fd_or_name (input_fd, NULL, "rb"); + if (fp && is_secured_file (iobuf_get_fd (fp))) + { + iobuf_close (fp); + fp = NULL; + errno = EPERM; + } + if (!fp) + { + char xname[64]; + + err = gpg_error_from_syserror (); + snprintf (xname, sizeof xname, "[fd %d]", input_fd); + log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err)); + release_progress_context (pfx); + return err; + } + + opt.outfp = fdopen (dup (output_fd), "wb"); + if (!opt.outfp) + { + char xname[64]; + + err = gpg_error_from_syserror (); + snprintf (xname, sizeof xname, "[fd %d]", output_fd); + log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err)); + iobuf_close (fp); + release_progress_context (pfx); + return err; + } + + if (!opt.no_armor) + { + if (use_armor_filter (fp)) + { + afx = new_armor_context (); + push_armor_filter ( afx, fp ); + } + } + + err = proc_encryption_packets ( NULL, fp ); + + iobuf_close (fp); + fclose (opt.outfp); + opt.outfp = NULL; + release_armor_context (afx); + release_progress_context (pfx); + return err; +} + + void decrypt_messages (int nfiles, char *files[]) { Deleted: trunk/g10/encr-data.c Modified: trunk/g10/encrypt.c =================================================================== --- trunk/g10/encrypt.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/encrypt.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -264,8 +264,7 @@ do_compress = 0; } - if ( rc || (rc = open_outfile (GNUPG_INVALID_FD, filename, - opt.armor? 1:0, &out ))) + if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out ))) { iobuf_cancel (inp); xfree (cfx.dek); @@ -462,9 +461,9 @@ * PROVIDED_PKS; if not the function builds a list of keys on its own. */ int -encrypt_crypt (gnupg_fd_t filefd, const char *filename, +encrypt_crypt (int filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, - gnupg_fd_t outputfd) + int outputfd) { iobuf_t inp = NULL; iobuf_t out = NULL; @@ -482,7 +481,7 @@ PK_LIST pk_list, work_list; int do_compress; - if (filefd != GNUPG_INVALID_FD && filename) + if (filefd != -1 && filename) return gpg_error (GPG_ERR_INV_ARG); do_compress = opt.compress_algo && !RFC1991; @@ -539,7 +538,7 @@ char xname[64]; rc = gpg_error_from_syserror (); - if (filefd != GNUPG_INVALID_FD) + if (filefd != -1) snprintf (xname, sizeof xname, "[fd %d]", filefd); else if (!filename) strcpy (xname, "[stdin]"); @@ -652,7 +651,7 @@ if (!opt.no_literal) pt = setup_plaintext_name (filename, inp); - if (filefd != GNUPG_INVALID_FD + if (filefd != -1 && !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) { off_t tmpsize; @@ -964,8 +963,7 @@ } line[strlen(line)-1] = '\0'; print_file_status(STATUS_FILE_START, line, 2); - rc = encrypt_crypt (GNUPG_INVALID_FD, line, remusr, 0, - NULL, GNUPG_INVALID_FD); + rc = encrypt_crypt (-1, line, remusr, 0, NULL, -1); if (rc) log_error ("encryption of `%s' failed: %s\n", print_fname_stdin(line), g10_errstr(rc) ); @@ -977,8 +975,7 @@ while (nfiles--) { print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encrypt_crypt (GNUPG_INVALID_FD, *files, remusr, 0, - NULL, GNUPG_INVALID_FD)) ) + if ( (rc = encrypt_crypt (-1, *files, remusr, 0, NULL, -1)) ) log_error("encryption of `%s' failed: %s\n", print_fname_stdin(*files), g10_errstr(rc) ); write_status( STATUS_FILE_DONE ); Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/gpg.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -3434,8 +3434,7 @@ { if( argc > 1 ) wrong_args(_("--encrypt [filename]")); - if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname, - remusr, 0, NULL, GNUPG_INVALID_FD)) ) + if( (rc = encrypt_crypt (-1, fname, remusr, 0, NULL, -1)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } @@ -3456,8 +3455,7 @@ " while in %s mode\n"),compliance_option_string()); else { - if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname, - remusr, 1, NULL, GNUPG_INVALID_FD)) ) + if( (rc = encrypt_crypt (-1, fname, remusr, 1, NULL, -1)) ) log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); } Modified: trunk/g10/main.h =================================================================== --- trunk/g10/main.h 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/main.h 2009-10-02 14:57:55 UTC (rev 5172) @@ -185,9 +185,9 @@ int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); -int encrypt_crypt (gnupg_fd_t filefd, const char *filename, +int encrypt_crypt (int filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, - gnupg_fd_t outputfd); + int outputfd); void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr); int encrypt_filter (void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); @@ -245,7 +245,7 @@ int overwrite_filep( const char *fname ); char *make_outfile_name( const char *iname ); char *ask_outfile_name( const char *name, size_t namelen ); -int open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a); +int open_outfile (int inp_fd, const char *iname, int mode, iobuf_t *a); iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx ); void try_make_homedir( const char *fname ); @@ -319,6 +319,7 @@ /*-- decrypt.c --*/ int decrypt_message( const char *filename ); +gpg_error_t decrypt_message_fd (int input_fd, int output_fd); void decrypt_messages(int nfiles, char *files[]); /*-- plaintext.c --*/ Modified: trunk/g10/openfile.c =================================================================== --- trunk/g10/openfile.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/openfile.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -178,24 +178,24 @@ * Mode 0 = use ".gpg" * 1 = use ".asc" * 2 = use ".sig" - - * If INP_FD is not GNUPG_INVALID_FD the function will simply create - * an IOBUF for that file descriptor and ignore a INAME and MODE. - * Note that INP_FD won't be closed if the returned IOBUF is closed. + * + * If INP_FD is not -1 the function simply creates an IOBUF for that + * file descriptor and ignorea INAME and MODE. Note that INP_FD won't + * be closed if the returned IOBUF is closed. */ int -open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a) +open_outfile (int inp_fd, const char *iname, int mode, iobuf_t *a) { int rc = 0; *a = NULL; - if (inp_fd != GNUPG_INVALID_FD) + if (inp_fd != -1) { char xname[64]; - gnupg_fd_t fd2; + int fd2; - fd2 = INT2FD (dup (FD2INT (inp_fd))); - if (fd2 == GNUPG_INVALID_FD) + fd2 = dup (inp_fd); + if (fd2 == -1) *a = NULL; else *a = iobuf_fdopen (fd2, "wb"); Modified: trunk/g10/options.h =================================================================== --- trunk/g10/options.h 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/options.h 2009-10-02 14:57:55 UTC (rev 5172) @@ -43,6 +43,7 @@ unsigned debug; int armor; char *outfile; + FILE *outfp; /* Hack, sometimes used in place of outfile. */ off_t max_output; int dry_run; int list_only; Modified: trunk/g10/packet.h =================================================================== --- trunk/g10/packet.h 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/packet.h 2009-10-02 14:57:55 UTC (rev 5172) @@ -289,8 +289,8 @@ } PKT_compressed; typedef struct { - u32 len; /* length of encrypted data */ - int extralen; /* this is (blocksize+2) */ + u32 len; /* Remaining length of encrypted data. */ + int extralen; /* This is (blocksize+2). Used by build_packet. */ byte new_ctb; /* uses a new CTB */ byte is_partial; /* partial length encoded */ byte mdc_method; /* > 0: integrity protected encrypted data packet */ Modified: trunk/g10/plaintext.c =================================================================== --- trunk/g10/plaintext.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/plaintext.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -86,10 +86,13 @@ /* Create the filename as C string. */ if (nooutput) ; + else if (opt.outfp) + { + fname = xstrdup ("[FP]"); + } else if (opt.outfile) { - fname = xmalloc (strlen (opt.outfile) + 1); - strcpy (fname, opt.outfile); + fname = xstrdup (opt.outfile); } else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8)) { @@ -112,6 +115,13 @@ if (nooutput) ; + else if (opt.outfp) + { + fp = opt.outfp; +#ifdef HAVE_DOSISH_SYSTEM + setmode (fileno (fp), O_BINARY); +#endif + } else if (iobuf_is_pipe_filename (fname) || !*fname) { /* No filename or "-" given; write to stdout. */ @@ -138,7 +148,13 @@ } #ifndef __riscos__ - if (fp || nooutput) + if (opt.outfp && is_secured_file (fileno (opt.outfp))) + { + rc = gpg_error (GPG_ERR_EPERM); + log_error (_("error creating `%s': %s\n"), fname, gpg_strerror (rc)); + goto leave; + } + else if (fp || nooutput) ; else if (is_secured_filename (fname)) { @@ -154,9 +170,9 @@ goto leave; } #else /* __riscos__ */ - /* If no output filename was given, i.e. we constructed it, - convert all '.' in fname to '/' but not vice versa as - we don't create directories! */ + /* If no output filename was given, i.e. we constructed it, convert + all '.' in fname to '/' but not vice versa as we don't create + directories! */ if (!opt.outfile) for (c = 0; fname[c]; ++c) if (fname[c] == '.') @@ -418,7 +434,7 @@ pt->buf = NULL; } - if (fp && fp != stdout && fclose (fp)) + if (fp && fp != stdout && fp != opt.outfp && fclose (fp)) { rc = (errno ? gpg_error_from_syserror () : gpg_error (GPG_ERR_INTERNAL)); @@ -434,7 +450,7 @@ before checking the signature. */ fflush (stdout); - if (fp && fp != stdout) + if (fp && fp != stdout && fp != opt.outfp) fclose (fp); xfree (fname); return rc; Modified: trunk/g10/server.c =================================================================== --- trunk/g10/server.c 2009-10-02 12:31:14 UTC (rev 5171) +++ trunk/g10/server.c 2009-10-02 14:57:55 UTC (rev 5172) @@ -362,7 +362,7 @@ if (out_fd == -1) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + err = decrypt_message_fd (inp_fd, out_fd); /* Close and reset the fds. */ close_message_fd (ctrl); From cvs at cvs.gnupg.org Wed Oct 7 13:17:58 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 07 Oct 2009 13:17:58 +0200 Subject: [svn] gpgme - r1396 - trunk/src Message-ID: Author: wk Date: 2009-10-07 13:17:57 +0200 (Wed, 07 Oct 2009) New Revision: 1396 Modified: trunk/src/ChangeLog trunk/src/priv-io.h Log: Fix last change for Windows. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-08-06 19:09:10 UTC (rev 1395) +++ trunk/src/ChangeLog 2009-10-07 11:17:57 UTC (rev 1396) @@ -1,3 +1,7 @@ +2009-10-07 + + * priv-io.h [W32]: Include windows.h instead of sys/socket.h. + 2009-08-06 Werner Koch * op-support.c (_gpgme_parse_inv_recp): Allow for no fingerprint. Modified: trunk/src/priv-io.h =================================================================== --- trunk/src/priv-io.h 2009-08-06 19:09:10 UTC (rev 1395) +++ trunk/src/priv-io.h 2009-10-07 11:17:57 UTC (rev 1396) @@ -22,7 +22,11 @@ #ifndef IO_H #define IO_H -#include +#ifdef HAVE_W32_SYSTEM +# include +#else +# include +#endif /* A single file descriptor passed to spawn. For child fds, dup_to specifies the fd it should become in the child, but only 0, 1 and 2 From cvs at cvs.gnupg.org Thu Oct 8 14:48:21 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 08 Oct 2009 14:48:21 +0200 Subject: [svn] assuan - r306 - in trunk: . src Message-ID: Author: marcus Date: 2009-10-08 14:48:21 +0200 (Thu, 08 Oct 2009) New Revision: 306 Added: trunk/src/vasprintf.c Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/assuan-defs.h trunk/src/assuan-pipe-connect.c trunk/src/assuan.h trunk/src/libassuan.def trunk/src/libassuan.vers Log: 2009-10-08 Marcus Brinkmann * configure.ac: AC_REPLACE_FUNCS for vasprintf. src/ 2009-10-08 Marcus Brinkmann * assuan.h (assuan_get_assuan_log_stream, assuan_set_assuan_log_stream): Remove prototypes. * libassuan.def: Remove assuan_get_assuan_log_stream, assuan_set_assuan_log_stream. * libassuan.vers: Likewise. * assuan-defs.h (_assuan_w32_strerror): Fix prototype. (w32_strerror): Remove macro. * assuan-pipe-connect.c (build_w32_commandline): Add argument for context. Use it for malloc routines. Use _assuan_w32_strerror instead of w32_strerror. * vasprintf.c: New file. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/ChangeLog 2009-10-08 12:48:21 UTC (rev 306) @@ -1,3 +1,7 @@ +2009-10-08 Marcus Brinkmann + + * configure.ac: AC_REPLACE_FUNCS for vasprintf. + 2009-09-19 Marcus Brinkmann * tests/fdpassing.c: Update to new API. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/ChangeLog 2009-10-08 12:48:21 UTC (rev 306) @@ -1,3 +1,17 @@ +2009-10-08 Marcus Brinkmann + + * assuan.h (assuan_get_assuan_log_stream, + assuan_set_assuan_log_stream): Remove prototypes. + * libassuan.def: Remove assuan_get_assuan_log_stream, + assuan_set_assuan_log_stream. + * libassuan.vers: Likewise. + * assuan-defs.h (_assuan_w32_strerror): Fix prototype. + (w32_strerror): Remove macro. + * assuan-pipe-connect.c (build_w32_commandline): Add argument for + context. Use it for malloc routines. Use _assuan_w32_strerror + instead of w32_strerror. + * vasprintf.c: New file. + 2009-09-29 Werner Koch * assuan.h: Comment fix. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/configure.ac 2009-10-08 12:48:21 UTC (rev 306) @@ -308,6 +308,7 @@ # Check for unistd.h for setenv replacement function. AC_CHECK_HEADERS(unistd.h) AC_REPLACE_FUNCS(setenv) +AC_REPLACE_FUNCS(vasprintf) # Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/assuan-defs.h 2009-10-08 12:48:21 UTC (rev 306) @@ -276,8 +276,7 @@ assuan_set_error ((c), _assuan_error (c,e), (t)) #ifdef HAVE_W32_SYSTEM -const char *_assuan_w32_strerror (int ec); -#define w32_strerror(e) _assuan_w32_strerror ((e)) +char *_assuan_w32_strerror (assuan_context_t ctx, int ec); #endif /*HAVE_W32_SYSTEM*/ Modified: trunk/src/assuan-pipe-connect.c =================================================================== --- trunk/src/assuan-pipe-connect.c 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/assuan-pipe-connect.c 2009-10-08 12:48:21 UTC (rev 306) @@ -541,7 +541,7 @@ /* Build a command line for use with W32's CreateProcess. On success CMDLINE gets the address of a newly allocated string. */ static int -build_w32_commandline (const char * const *argv, char **cmdline) +build_w32_commandline (assuan_context_t ctx, const char * const *argv, char **cmdline) { int i, n; const char *s; @@ -558,7 +558,7 @@ } n++; - buf = p = _assuan_malloc (n); + buf = p = _assuan_malloc (ctx, n); if (!buf) return -1; @@ -606,7 +606,7 @@ if (!CreatePipe (&r, &w, &sec_attr, 0)) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx, - "CreatePipe failed: %s", w32_strerror (ctx, -1)); + "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1)); return -1; } @@ -615,7 +615,7 @@ TRUE, DUPLICATE_SAME_ACCESS )) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx, - "DuplicateHandle failed: %s", w32_strerror (ctx, -1)); + "DuplicateHandle failed: %s", _assuan_w32_strerror (ctx, -1)); CloseHandle (r); CloseHandle (w); return -1; @@ -675,13 +675,13 @@ sprintf (mypidstr, "%lu", (unsigned long)getpid ()); /* Build the command line. */ - if (build_w32_commandline (argv, &cmdline)) + if (build_w32_commandline (ctx, argv, &cmdline)) return _assuan_error (ctx, gpg_err_code_from_syserror ()); /* Create thew two pipes. */ if (create_inheritable_pipe (ctx, rp, 0)) { - _assuan_free (cmdline); + _assuan_free (ctx, cmdline); return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); } @@ -689,7 +689,7 @@ { CloseHandle (rp[0]); CloseHandle (rp[1]); - _assuan_free (cmdline); + _assuan_free (ctx, cmdline); return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); } @@ -729,12 +729,12 @@ if (nullfd == INVALID_HANDLE_VALUE) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_w32", ctx, - "can't open `nul': %s", w32_strerror (ctx, -1)); + "can't open `nul': %s", _assuan_w32_strerror (ctx, -1)); CloseHandle (rp[0]); CloseHandle (rp[1]); CloseHandle (wp[0]); CloseHandle (wp[1]); - _assuan_free (cmdline); + _assuan_free (ctx, cmdline); /* FIXME: Cleanup? */ return -1; } @@ -765,18 +765,18 @@ )) { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_w32", ctx, - "CreateProcess failed: %s", w32_strerror (ctx, -1)); + "CreateProcess failed: %s", _assuan_w32_strerror (ctx, -1)); CloseHandle (rp[0]); CloseHandle (rp[1]); CloseHandle (wp[0]); CloseHandle (wp[1]); if (nullfd != INVALID_HANDLE_VALUE) CloseHandle (nullfd); - _assuan_free (cmdline); + _assuan_free (ctx, cmdline); /* FIXME: Cleanup? */ return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); } - _assuan_free (cmdline); + _assuan_free (ctx, cmdline); cmdline = NULL; if (nullfd != INVALID_HANDLE_VALUE) { Modified: trunk/src/assuan.h =================================================================== --- trunk/src/assuan.h 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/assuan.h 2009-10-08 12:48:21 UTC (rev 306) @@ -246,16 +246,6 @@ /* Configuration of the default log handler. */ -/* Set the stream to which assuan should log message not associated - with a context. By default, this is stderr. The default value - will be changed when the first log stream is associated with a - context. Note, that this function is not thread-safe and should - in general be used right at startup. */ -extern void assuan_set_assuan_log_stream (FILE *fp); - -/* Return the stream which is currently being using for global logging. */ -extern FILE *assuan_get_assuan_log_stream (void); - /* Set the prefix to be used at the start of a line emitted by assuan on the log stream. The default is the empty string. Note, that this function is not thread-safe and should in general be used Modified: trunk/src/libassuan.def =================================================================== --- trunk/src/libassuan.def 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/libassuan.def 2009-10-08 12:48:21 UTC (rev 306) @@ -27,65 +27,63 @@ assuan_end_confidential @6 assuan_get_active_fds @7 assuan_get_assuan_log_prefix @8 - assuan_get_assuan_log_stream @9 - assuan_get_data_fp @10 - assuan_get_flag @11 - assuan_get_gpg_err_source @12 - assuan_get_input_fd @13 - assuan_get_log_cb @14 - assuan_get_malloc_hooks @15 - assuan_get_output_fd @16 - assuan_get_pid @17 - assuan_get_pointer @18 - assuan_init_pipe_server @19 - assuan_init_socket_server @20 - assuan_init_socket_server_ext @21 - assuan_inquire @22 - assuan_inquire_ext @23 - assuan_new @24 - assuan_new_ext @25 - assuan_pending_line @26 - assuan_pipe_connect @27 - assuan_pipe_connect_ext @28 - assuan_process @29 - assuan_process_done @30 - assuan_process_next @31 - assuan_read_line @32 - assuan_receivefd @33 - assuan_register_bye_notify @34 - assuan_register_cancel_notify @35 - assuan_register_command @36 - assuan_register_input_notify @37 - assuan_register_option_handler @38 - assuan_register_output_notify @39 - assuan_register_post_cmd_notify @40 - assuan_register_reset_notify @41 - assuan_release @42 - assuan_send_data @43 - assuan_sendfd @44 - assuan_set_assuan_log_prefix @45 - assuan_set_assuan_log_stream @46 - assuan_set_error @47 - assuan_set_flag @48 - assuan_set_gpg_err_source @49 - assuan_set_hello_line @50 - assuan_set_io_monitor @51 - assuan_set_log_cb @52 - assuan_set_log_stream @53 - assuan_set_malloc_hooks @54 - assuan_set_okay_line @55 - assuan_set_pointer @56 - assuan_sock_bind @57 - assuan_sock_check_nonce @58 - assuan_sock_close @59 - assuan_sock_connect @60 - assuan_sock_get_nonce @61 - assuan_sock_new @62 - assuan_socket_connect @63 - assuan_socket_connect_ext @64 - assuan_transact @65 - assuan_write_line @66 - assuan_write_status @67 + assuan_get_data_fp @9 + assuan_get_flag @10 + assuan_get_gpg_err_source @11 + assuan_get_input_fd @12 + assuan_get_log_cb @13 + assuan_get_malloc_hooks @14 + assuan_get_output_fd @15 + assuan_get_pid @16 + assuan_get_pointer @17 + assuan_init_pipe_server @18 + assuan_init_socket_server @19 + assuan_init_socket_server_ext @20 + assuan_inquire @21 + assuan_inquire_ext @22 + assuan_new @23 + assuan_new_ext @24 + assuan_pending_line @25 + assuan_pipe_connect @26 + assuan_pipe_connect_ext @27 + assuan_process @28 + assuan_process_done @29 + assuan_process_next @30 + assuan_read_line @31 + assuan_receivefd @32 + assuan_register_bye_notify @33 + assuan_register_cancel_notify @34 + assuan_register_command @35 + assuan_register_input_notify @36 + assuan_register_option_handler @37 + assuan_register_output_notify @38 + assuan_register_post_cmd_notify @39 + assuan_register_reset_notify @40 + assuan_release @41 + assuan_send_data @42 + assuan_sendfd @43 + assuan_set_assuan_log_prefix @44 + assuan_set_error @45 + assuan_set_flag @46 + assuan_set_gpg_err_source @47 + assuan_set_hello_line @48 + assuan_set_io_monitor @49 + assuan_set_log_cb @50 + assuan_set_log_stream @51 + assuan_set_malloc_hooks @52 + assuan_set_okay_line @53 + assuan_set_pointer @54 + assuan_sock_bind @55 + assuan_sock_check_nonce @56 + assuan_sock_close @57 + assuan_sock_connect @58 + assuan_sock_get_nonce @59 + assuan_sock_new @60 + assuan_socket_connect @61 + assuan_socket_connect_ext @62 + assuan_transact @63 + assuan_write_line @64 + assuan_write_status @65 ; END Modified: trunk/src/libassuan.vers =================================================================== --- trunk/src/libassuan.vers 2009-09-29 19:13:26 UTC (rev 305) +++ trunk/src/libassuan.vers 2009-10-08 12:48:21 UTC (rev 306) @@ -30,7 +30,6 @@ assuan_end_confidential; assuan_get_active_fds; assuan_get_assuan_log_prefix; - assuan_get_assuan_log_stream; assuan_get_data_fp; assuan_get_flag; assuan_get_input_fd; @@ -62,7 +61,6 @@ assuan_send_data; assuan_sendfd; assuan_set_assuan_log_prefix; - assuan_set_assuan_log_stream; assuan_set_error; assuan_set_flag; assuan_set_hello_line; Added: trunk/src/vasprintf.c =================================================================== --- trunk/src/vasprintf.c (rev 0) +++ trunk/src/vasprintf.c 2009-10-08 12:48:21 UTC (rev 306) @@ -0,0 +1,192 @@ +/* Like vsprintf but provides a pointer to malloc'd storage, which must + be freed by the caller. + Copyright (C) 1994, 2002 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + + +#ifndef va_copy /* According to POSIX, va_copy is a macro. */ +#if defined (__GNUC__) && defined (__PPC__) \ + && (defined (_CALL_SYSV) || defined (_WIN32)) +#define va_copy(d, s) (*(d) = *(s)) +#elif defined (MUST_COPY_VA_BYVAL) +#define va_copy(d, s) ((d) = (s)) +#else +#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list)) +#endif +#endif + + +#ifdef TEST +int global_total_width; +#endif + +static int int_vasprintf (char **, const char *, va_list *); + +static int +int_vasprintf (result, format, args) + char **result; + const char *format; + va_list *args; +{ + const char *p = format; + /* Add one to make sure that it is never zero, which might cause malloc + to return NULL. */ + int total_width = strlen (format) + 1; + va_list ap; + + va_copy (ap, *args); + + while (*p != '\0') + { + if (*p++ == '%') + { + while (strchr ("-+ #0", *p)) + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + total_width += strtoul (p, (char **) &p, 10); + if (*p == '.') + { + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + total_width += strtoul (p, (char **) &p, 10); + } + while (strchr ("hlL", *p)) + ++p; + /* Should be big enough for any format specifier except %s and floats. */ + total_width += 30; + switch (*p) + { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + (void) va_arg (ap, int); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + (void) va_arg (ap, double); + /* Since an ieee double can have an exponent of 307, we'll + make the buffer wide enough to cover the gross case. */ + total_width += 307; + break; + case 's': + { + char *tmp = va_arg (ap, char *); + if (tmp) + total_width += strlen (tmp); + else /* in case the vsprintf does prints a text */ + total_width += 25; /* e.g. "(null pointer reference)" */ + } + break; + case 'p': + case 'n': + (void) va_arg (ap, char *); + break; + } + p++; + } + } +#ifdef TEST + global_total_width = total_width; +#endif + *result = malloc (total_width); + if (*result != NULL) + return vsprintf (*result, format, *args); + else + return 0; +} + +int +vasprintf (result, format, args) + char **result; + const char *format; +#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) + _BSD_VA_LIST_ args; +#else + va_list args; +#endif +{ + return int_vasprintf (result, format, &args); +} + + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + va_start (ap, fmt); + status = vasprintf (buf, fmt, ap); + va_end (ap); + return status; +} + + +#ifdef TEST +void +checkit (const char* format, ...) +{ + va_list args; + char *result; + + va_start (args, format); + vasprintf (&result, format, args); + if (strlen (result) < global_total_width) + printf ("PASS: "); + else + printf ("FAIL: "); + printf ("%d %s\n", global_total_width, result); +} + +int +main (void) +{ + checkit ("%d", 0x12345678); + checkit ("%200d", 5); + checkit ("%.300d", 6); + checkit ("%100.150d", 7); + checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ +777777777777777777333333333333366666666666622222222222777777777777733333"); + checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); +} +#endif /* TEST */ From cvs at cvs.gnupg.org Tue Oct 13 11:11:47 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 13 Oct 2009 11:11:47 +0200 Subject: [svn] GnuPG - r5173 - trunk/tests Message-ID: Author: wk Date: 2009-10-13 11:11:47 +0200 (Tue, 13 Oct 2009) New Revision: 5173 Modified: trunk/tests/ChangeLog trunk/tests/asschk.c Log: Replace C99 style vararg macro which was anyway not correct. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-10-02 14:57:55 UTC (rev 5172) +++ trunk/tests/ChangeLog 2009-10-13 09:11:47 UTC (rev 5173) @@ -1,3 +1,9 @@ +2009-10-13 Werner Koch + + * asschk.c (die): Replace this vararg macro by C-89 compliant + macros die_0, die_1, die_2 and die 3. Change all callers. + Reported by Nelson H. F. Beebe. + 2009-02-19 Werner Koch * Makefile.am (TESTS_ENVIRONMENT): Use /bin/pwd. Modified: trunk/tests/asschk.c =================================================================== --- trunk/tests/asschk.c 2009-10-02 14:57:55 UTC (rev 5172) +++ trunk/tests/asschk.c 2009-10-13 09:11:47 UTC (rev 5173) @@ -199,7 +199,10 @@ exit (1); } -#define die(format, args...) (die) ("%s: " format, __func__ , ##args) +#define die_0(format) (die) ("%s: " format, __func__) +#define die_1(format, a) (die) ("%s: " format, __func__, (a)) +#define die_2(format, a, b) (die) ("%s: " format, __func__, (a),(b)) +#define die_3(format, a, b, c) (die) ("%s: " format, __func__, (a),(b),(c)) static void err (const char *format, ...) @@ -290,7 +293,7 @@ if (pending_len) { if (pending_len >= nleft) - die ("received line too large"); + die_0 ("received line too large"); memcpy (buf, pending, pending_len); n = pending_len; pending_len = 0; @@ -315,9 +318,9 @@ } if (n < 0) - die ("reading fd %d failed: %s", fd, strerror (errno)); + die_2 ("reading fd %d failed: %s", fd, strerror (errno)); else if (!n) - die ("received incomplete line on fd %d", fd); + die_1 ("received incomplete line on fd %d", fd); p = buf; nleft -= n; buf += n; @@ -337,7 +340,7 @@ } } if (!nleft) - die ("received line too large"); + die_0 ("received line too large"); p = recv_line; if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) @@ -367,7 +370,7 @@ p += 3; } else - die ("invalid line type (%.5s)", p); + die_1 ("invalid line type (%.5s)", p); return p; } @@ -381,13 +384,13 @@ size_t n = strlen (line); if (n > 1024) - die ("line too long for Assuan protocol"); + die_0 ("line too long for Assuan protocol"); strcpy (buffer, line); if (!n || buffer[n-1] != '\n') buffer[n++] = '\n'; if (writen (fd, buffer, n)) - die ("sending line (\"%s\") to %d failed: %s", buffer, fd, + die_3 ("sending line (\"%s\") to %d failed: %s", buffer, fd, strerror (errno)); } @@ -404,15 +407,15 @@ pid_t pid; if (pipe (rp) < 0) - die ("pipe creation failed: %s", strerror (errno)); + die_1 ("pipe creation failed: %s", strerror (errno)); if (pipe (wp) < 0) - die ("pipe creation failed: %s", strerror (errno)); + die_1 ("pipe creation failed: %s", strerror (errno)); fflush (stdout); fflush (stderr); pid = fork (); if (pid < 0) - die ("fork failed"); + die_0 ("fork failed"); if (!pid) { @@ -427,29 +430,29 @@ if (wp[0] != STDIN_FILENO) { if (dup2 (wp[0], STDIN_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (wp[0]); } if (rp[1] != STDOUT_FILENO) { if (dup2 (rp[1], STDOUT_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (rp[1]); } if (!opt_verbose) { int fd = open ("/dev/null", O_WRONLY); if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); + die_1 ("can't open `/dev/null': %s", strerror (errno)); if (dup2 (fd, STDERR_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (fd); } close (wp[1]); close (rp[0]); execl (pgmname, arg0, "--server", NULL); - die ("exec failed for `%s': %s", pgmname, strerror (errno)); + die_2 ("exec failed for `%s': %s", pgmname, strerror (errno)); } close (wp[0]); close (rp[1]); @@ -458,7 +461,7 @@ read_assuan (server_recv_fd); if (recv_type != LINE_OK) - die ("no greating message"); + die_0 ("no greating message"); } @@ -723,7 +726,7 @@ } while (recv_type != LINE_OK && recv_type != LINE_ERR); if (recv_type != LINE_OK) - die ("expected OK but got `%s'", recv_line); + die_1 ("expected OK but got `%s'", recv_line); } static void @@ -744,7 +747,7 @@ } while (recv_type != LINE_OK && recv_type != LINE_ERR); if (recv_type != LINE_ERR) - die ("expected ERR but got `%s'", recv_line); + die_1 ("expected ERR but got `%s'", recv_line); } static void @@ -753,7 +756,7 @@ char *p; if (!*assign_to || !*arg) - die ("syntax error: count-status requires an argument and a variable"); + die_0 ("syntax error: count-status requires an argument and a variable"); for (p=arg; *p && !spacep (p); p++) ; @@ -762,7 +765,7 @@ for (*p++ = 0; spacep (p); p++) ; if (*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); } set_type_var (assign_to, arg, VARTYPE_COUNTER); } @@ -777,7 +780,7 @@ fd = open (arg, O_RDONLY); while (fd == -1 && errno == EINTR); if (fd == -1) - die ("error opening `%s': %s", arg, strerror (errno)); + die_2 ("error opening `%s': %s", arg, strerror (errno)); sprintf (numbuf, "%d", fd); set_type_var (assign_to, numbuf, VARTYPE_FD); @@ -793,7 +796,7 @@ fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); while (fd == -1 && errno == EINTR); if (fd == -1) - die ("error creating `%s': %s", arg, strerror (errno)); + die_2 ("error creating `%s': %s", arg, strerror (errno)); sprintf (numbuf, "%d", fd); set_type_var (assign_to, numbuf, VARTYPE_FD); @@ -806,7 +809,7 @@ (void)assign_to; if (!*arg) - die ("syntax error: servername missing"); + die_0 ("syntax error: servername missing"); start_server (arg); } @@ -846,7 +849,7 @@ for (p=arg; *p && !spacep (p); p++) ; if (!*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); for (*p++ = 0; spacep (p); p++) ; second = p; @@ -857,7 +860,7 @@ for (*p++ = 0; spacep (p); p++) ; if (*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); } fp1 = fopen (arg, "rb"); @@ -973,7 +976,7 @@ assign_to = line; } if (!*line) - die ("syntax error"); + die_0 ("syntax error"); stmt = line; save_c = 0; save_p = NULL; @@ -1003,7 +1006,7 @@ if (!cmdtbl[i].name) { if (!assign_to) - die ("invalid statement `%s'\n", stmt); + die_1 ("invalid statement `%s'\n", stmt); if (save_p) *save_p = save_c; set_var (assign_to, stmt); @@ -1078,7 +1081,7 @@ { p = strchr (buffer,'\n'); if (!p) - die ("incomplete script line"); + die_0 ("incomplete script line"); *p = 0; if (interpreter (buffer)) break; From cvs at cvs.gnupg.org Tue Oct 13 11:13:19 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 13 Oct 2009 11:13:19 +0200 Subject: [svn] GnuPG - r5174 - branches/STABLE-BRANCH-2-0/tests Message-ID: Author: wk Date: 2009-10-13 11:13:19 +0200 (Tue, 13 Oct 2009) New Revision: 5174 Modified: branches/STABLE-BRANCH-2-0/tests/ChangeLog branches/STABLE-BRANCH-2-0/tests/asschk.c Log: Replace C-99 vararg macro Modified: branches/STABLE-BRANCH-2-0/tests/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tests/ChangeLog 2009-10-13 09:11:47 UTC (rev 5173) +++ branches/STABLE-BRANCH-2-0/tests/ChangeLog 2009-10-13 09:13:19 UTC (rev 5174) @@ -1,3 +1,9 @@ +2009-10-13 Werner Koch + + * asschk.c (die): Replace this vararg macro by C-89 compliant + macros die_0, die_1, die_2 and die_3. Change all callers. + Reported by Nelson H. F. Beebe. + 2009-02-19 Werner Koch * Makefile.am (TESTS_ENVIRONMENT): Use /bin/pwd. Modified: branches/STABLE-BRANCH-2-0/tests/asschk.c =================================================================== --- branches/STABLE-BRANCH-2-0/tests/asschk.c 2009-10-13 09:11:47 UTC (rev 5173) +++ branches/STABLE-BRANCH-2-0/tests/asschk.c 2009-10-13 09:13:19 UTC (rev 5174) @@ -199,7 +199,10 @@ exit (1); } -#define die(format, args...) (die) ("%s: " format, __func__ , ##args) +#define die_0(format) (die) ("%s: " format, __func__) +#define die_1(format, a) (die) ("%s: " format, __func__, (a)) +#define die_2(format, a, b) (die) ("%s: " format, __func__, (a),(b)) +#define die_3(format, a, b, c) (die) ("%s: " format, __func__, (a),(b),(c)) static void err (const char *format, ...) @@ -290,7 +293,7 @@ if (pending_len) { if (pending_len >= nleft) - die ("received line too large"); + die_0 ("received line too large"); memcpy (buf, pending, pending_len); n = pending_len; pending_len = 0; @@ -315,9 +318,9 @@ } if (n < 0) - die ("reading fd %d failed: %s", fd, strerror (errno)); + die_2 ("reading fd %d failed: %s", fd, strerror (errno)); else if (!n) - die ("received incomplete line on fd %d", fd); + die_1 ("received incomplete line on fd %d", fd); p = buf; nleft -= n; buf += n; @@ -337,7 +340,7 @@ } } if (!nleft) - die ("received line too large"); + die_0 ("received line too large"); p = recv_line; if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) @@ -367,7 +370,7 @@ p += 3; } else - die ("invalid line type (%.5s)", p); + die_1 ("invalid line type (%.5s)", p); return p; } @@ -381,13 +384,13 @@ size_t n = strlen (line); if (n > 1024) - die ("line too long for Assuan protocol"); + die_0 ("line too long for Assuan protocol"); strcpy (buffer, line); if (!n || buffer[n-1] != '\n') buffer[n++] = '\n'; if (writen (fd, buffer, n)) - die ("sending line (\"%s\") to %d failed: %s", buffer, fd, + die_3 ("sending line (\"%s\") to %d failed: %s", buffer, fd, strerror (errno)); } @@ -404,15 +407,15 @@ pid_t pid; if (pipe (rp) < 0) - die ("pipe creation failed: %s", strerror (errno)); + die_1 ("pipe creation failed: %s", strerror (errno)); if (pipe (wp) < 0) - die ("pipe creation failed: %s", strerror (errno)); + die_1 ("pipe creation failed: %s", strerror (errno)); fflush (stdout); fflush (stderr); pid = fork (); if (pid < 0) - die ("fork failed"); + die_0 ("fork failed"); if (!pid) { @@ -427,29 +430,29 @@ if (wp[0] != STDIN_FILENO) { if (dup2 (wp[0], STDIN_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (wp[0]); } if (rp[1] != STDOUT_FILENO) { if (dup2 (rp[1], STDOUT_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (rp[1]); } if (!opt_verbose) { int fd = open ("/dev/null", O_WRONLY); if (fd == -1) - die ("can't open `/dev/null': %s", strerror (errno)); + die_1 ("can't open `/dev/null': %s", strerror (errno)); if (dup2 (fd, STDERR_FILENO) == -1) - die ("dup2 failed in child: %s", strerror (errno)); + die_1 ("dup2 failed in child: %s", strerror (errno)); close (fd); } close (wp[1]); close (rp[0]); execl (pgmname, arg0, "--server", NULL); - die ("exec failed for `%s': %s", pgmname, strerror (errno)); + die_2 ("exec failed for `%s': %s", pgmname, strerror (errno)); } close (wp[0]); close (rp[1]); @@ -458,7 +461,7 @@ read_assuan (server_recv_fd); if (recv_type != LINE_OK) - die ("no greating message"); + die_0 ("no greating message"); } @@ -723,7 +726,7 @@ } while (recv_type != LINE_OK && recv_type != LINE_ERR); if (recv_type != LINE_OK) - die ("expected OK but got `%s'", recv_line); + die_1 ("expected OK but got `%s'", recv_line); } static void @@ -744,7 +747,7 @@ } while (recv_type != LINE_OK && recv_type != LINE_ERR); if (recv_type != LINE_ERR) - die ("expected ERR but got `%s'", recv_line); + die_1 ("expected ERR but got `%s'", recv_line); } static void @@ -753,7 +756,7 @@ char *p; if (!*assign_to || !*arg) - die ("syntax error: count-status requires an argument and a variable"); + die_0 ("syntax error: count-status requires an argument and a variable"); for (p=arg; *p && !spacep (p); p++) ; @@ -762,7 +765,7 @@ for (*p++ = 0; spacep (p); p++) ; if (*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); } set_type_var (assign_to, arg, VARTYPE_COUNTER); } @@ -777,7 +780,7 @@ fd = open (arg, O_RDONLY); while (fd == -1 && errno == EINTR); if (fd == -1) - die ("error opening `%s': %s", arg, strerror (errno)); + die_2 ("error opening `%s': %s", arg, strerror (errno)); sprintf (numbuf, "%d", fd); set_type_var (assign_to, numbuf, VARTYPE_FD); @@ -793,7 +796,7 @@ fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); while (fd == -1 && errno == EINTR); if (fd == -1) - die ("error creating `%s': %s", arg, strerror (errno)); + die_2 ("error creating `%s': %s", arg, strerror (errno)); sprintf (numbuf, "%d", fd); set_type_var (assign_to, numbuf, VARTYPE_FD); @@ -806,7 +809,7 @@ (void)assign_to; if (!*arg) - die ("syntax error: servername missing"); + die_0 ("syntax error: servername missing"); start_server (arg); } @@ -846,7 +849,7 @@ for (p=arg; *p && !spacep (p); p++) ; if (!*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); for (*p++ = 0; spacep (p); p++) ; second = p; @@ -857,7 +860,7 @@ for (*p++ = 0; spacep (p); p++) ; if (*p) - die ("cmpfiles: syntax error"); + die_0 ("cmpfiles: syntax error"); } fp1 = fopen (arg, "rb"); @@ -973,7 +976,7 @@ assign_to = line; } if (!*line) - die ("syntax error"); + die_0 ("syntax error"); stmt = line; save_c = 0; save_p = NULL; @@ -1003,7 +1006,7 @@ if (!cmdtbl[i].name) { if (!assign_to) - die ("invalid statement `%s'\n", stmt); + die_1 ("invalid statement `%s'\n", stmt); if (save_p) *save_p = save_c; set_var (assign_to, stmt); @@ -1078,7 +1081,7 @@ { p = strchr (buffer,'\n'); if (!p) - die ("incomplete script line"); + die_0 ("incomplete script line"); *p = 0; if (interpreter (buffer)) break; From cvs at cvs.gnupg.org Tue Oct 13 21:17:24 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 13 Oct 2009 21:17:24 +0200 Subject: [svn] GnuPG - r5175 - in trunk: . common g13 Message-ID: Author: wk Date: 2009-10-13 21:17:24 +0200 (Tue, 13 Oct 2009) New Revision: 5175 Added: trunk/g13/mount.c trunk/g13/mount.h trunk/g13/runner.c trunk/g13/runner.h Modified: trunk/ChangeLog trunk/NEWS trunk/common/ChangeLog trunk/common/exechelp.c trunk/common/exechelp.h trunk/common/iobuf.c trunk/configure.ac trunk/g13/Makefile.am trunk/g13/backend.c trunk/g13/backend.h trunk/g13/be-encfs.c trunk/g13/be-encfs.h trunk/g13/call-gpg.c trunk/g13/call-gpg.h trunk/g13/create.c trunk/g13/create.h trunk/g13/g13.c trunk/g13/keyblob.h trunk/g13/utils.c trunk/g13/utils.h Log: Keep on hacking on g13. A simple --create and --mount does now work. A hacked up encfs is required. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/ChangeLog 2009-10-13 19:17:24 UTC (rev 5175) @@ -1,3 +1,8 @@ +2009-10-12 Werner Koch + + * configure.ac: Use -O3 because newer gcc versions require that + for uninitialized variable warnings. + 2009-09-23 Werner Koch * configure.ac (HAVE_ASSUAN_SET_IO_MONITOR): Remove test. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/common/ChangeLog 2009-10-13 19:17:24 UTC (rev 5175) @@ -1,3 +1,7 @@ +2009-10-13 Werner Koch + + * exechelp.c (gnupg_kill_process): New. + 2009-09-29 Werner Koch * exechelp.c (create_inheritable_pipe): Rename to Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/NEWS 2009-10-13 19:17:24 UTC (rev 5175) @@ -1,7 +1,10 @@ Noteworthy changes in version 2.1 (under development) ------------------------------------------------- + * Encrypted OpenPGP messages with trailing data (e.g. other OpenPGP + packets) are now correctly parsed. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/common/exechelp.c =================================================================== --- trunk/common/exechelp.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/common/exechelp.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -1102,3 +1102,28 @@ return 0; #endif /* !HAVE_W32_SYSTEM*/ } + + +/* Kill a process; that is send an appropriate signal to the process. + gnupg_wait_process must be called to actually remove the process + from the system. An invalid PID is ignored. */ +void +gnupg_kill_process (pid_t pid) +{ +#ifdef HAVE_W32_SYSTEM + /* Older versions of libassuan set PID to 0 on Windows to indicate + an invalid value. */ + if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0) + { + HANDLE process = (HANDLE) pid; + + /* Arbitrary error code. */ + TerminateProcess (process, 1); + } +#else + if (pid != (pid_t)(-1)) + { + kill (pid, SIGTERM); + } +#endif +} Modified: trunk/common/exechelp.h =================================================================== --- trunk/common/exechelp.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/common/exechelp.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -86,6 +86,12 @@ gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int *exitcode); +/* Kill a process; that is send an appropriate signal to the process. + gnupg_wait_process must be called to actually remove the process + from the system. An invalid PID is ignored. */ +void gnupg_kill_process (pid_t pid); + + /* Spawn a new process and immediatley detach from it. The name of the program to exec is PGMNAME and its arguments are in ARGV (the programname is automatically passed as first argument). Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/common/iobuf.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -1262,22 +1262,22 @@ /* Either open the file specified by the file descriptor FD or - if FD - is GNUPG_INVALID_FD - the file with name FNAME. As of now MODE is - assumed to be "rb" if FNAME is used. In contrast to iobuf_fdopen - the fiel descriptor FD will not be closed during an iobuf_close. */ + is -1, the file with name FNAME. As of now MODE is assumed to be + "rb" if FNAME is used. In contrast to iobuf_fdopen the file + descriptor FD will not be closed during an iobuf_close. */ iobuf_t -iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, const char *mode) +iobuf_open_fd_or_name (int fd, const char *fname, const char *mode) { iobuf_t a; - if (fd == GNUPG_INVALID_FD) + if (fd == -1) a = iobuf_open (fname); else { - gnupg_fd_t fd2; + int fd2; fd2 = dup (fd); - if (fd2 == GNUPG_INVALID_FD) + if (fd2 == -1) a = NULL; else a = iobuf_fdopen (fd2, mode); Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/configure.ac 2009-10-13 19:17:24 UTC (rev 5175) @@ -1230,7 +1230,7 @@ # warning options and the user should have a chance of overriding # them. if test "$USE_MAINTAINER_MODE" = "yes"; then - CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" + CFLAGS="$CFLAGS -O3 -Wall -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security" AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers]) _gcc_cflags_save=$CFLAGS Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/Makefile.am 2009-10-13 19:17:24 UTC (rev 5175) @@ -31,7 +31,9 @@ keyblob.h \ utils.c utils.h \ create.c create.h \ + mount.c mount.h \ call-gpg.c call-gpg.h \ + runner.c runner.h \ backend.c backend.h \ be-encfs.c be-encfs.h \ be-truecrypt.c be-truecrypt.h Modified: trunk/g13/backend.c =================================================================== --- trunk/g13/backend.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/backend.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -41,6 +41,22 @@ } +/* Return true if CONTTYPE is supported by us. */ +int +be_is_supported_conttype (int conttype) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return 1; + + default: + return 0; + } +} + + + /* If the backend requires a separate file or directory for the container, return its name by computing it from FNAME which gives the g13 filename. The new file name is allocated and stored at @@ -81,3 +97,37 @@ } } + +/* Dispatcher to the backend's create function. */ +gpg_error_t +be_create_container (ctrl_t ctrl, int conttype, + const char *fname, int fd, tupledesc_t tuples) +{ + (void)fd; /* Not yet used. */ + + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_create_container (ctrl, fname, tuples); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's mount function. */ +gpg_error_t +be_mount_container (ctrl_t ctrl, int conttype, + const char *fname, const char *mountpoint, + tupledesc_t tuples) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_mount_container (ctrl, fname, mountpoint, tuples); + + default: + return no_such_backend (conttype); + } +} Modified: trunk/g13/backend.h =================================================================== --- trunk/g13/backend.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/backend.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -21,12 +21,20 @@ #define G13_BACKEND_H #include "../common/membuf.h" +#include "utils.h" /* For tupledesc_t */ - +int be_is_supported_conttype (int conttype); gpg_error_t be_get_detached_name (int conttype, const char *fname, char **r_name, int *r_isdir); gpg_error_t be_create_new_keys (int conttype, membuf_t *mb); +gpg_error_t be_create_container (ctrl_t ctrl, int conttype, + const char *fname, int fd, + tupledesc_t tuples); +gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, + const char *fname, const char *mountpoint, + tupledesc_t tuples); + #endif /*G13_BACKEND_H*/ Modified: trunk/g13/be-encfs.c =================================================================== --- trunk/g13/be-encfs.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/be-encfs.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -23,12 +23,301 @@ #include #include #include +#include #include "g13.h" #include "i18n.h" #include "keyblob.h" #include "be-encfs.h" +#include "runner.h" +#include "../common/exechelp.h" + +/* Command values used to run the encfs tool. */ +enum encfs_cmds + { + ENCFS_CMD_CREATE, + ENCFS_CMD_MOUNT, + ENCFS_CMD_UMOUNT + }; + + +/* An object to keep the private state of the encfs tool. It is + released by encfs_handler_cleanup. */ +struct encfs_parm_s +{ + enum encfs_cmds cmd; /* The current command. */ + tupledesc_t tuples; /* NULL or the tuples object. */ + char *mountpoint; /* The mountpoint. */ +}; +typedef struct encfs_parm_s *encfs_parm_t; + + +static gpg_error_t +send_cmd_bin (runner_t runner, const void *data, size_t datalen) +{ + return runner_send_line (runner, data, datalen); +} + + +static gpg_error_t +send_cmd (runner_t runner, const char *string) +{ + log_debug ("sending command -->%s<--\n", string); + return send_cmd_bin (runner, string, strlen (string)); +} + + + +static void +run_umount_helper (const char *mountpoint) +{ + gpg_error_t err; + const char pgmname[] = "/usr/bin/fusermount"; + const char *args[3]; + + args[0] = "-u"; + args[1] = mountpoint; + args[2] = NULL; + + err = gnupg_spawn_process_detached (pgmname, args, NULL); + if (err) + log_error ("failed to run `%s': %s\n", + pgmname, gpg_strerror (err)); +} + + +/* Handle one line of the encfs tool's output. This function is + allowed to modify the content of BUFFER. */ +static gpg_error_t +handle_status_line (runner_t runner, const char *line, + enum encfs_cmds cmd, tupledesc_t tuples) +{ + gpg_error_t err; + + /* Check that encfs understands our new options. */ + if (!strncmp (line, "$STATUS$", 8)) + { + for (line +=8; *line && spacep (line); line++) + ; + log_info ("got status `%s'\n", line); + if (!strcmp (line, "fuse_main_start")) + { + /* Send a special error code back to let the caller know + that everything has been setup by encfs. */ + err = gpg_error (GPG_ERR_UNFINISHED); + } + else + err = 0; + } + else if (!strncmp (line, "$PROMPT$", 8)) + { + for (line +=8; *line && spacep (line); line++) + ; + log_info ("got prompt `%s'\n", line); + if (!strcmp (line, "create_root_dir")) + err = send_cmd (runner, cmd == ENCFS_CMD_CREATE? "y":"n"); + else if (!strcmp (line, "create_mount_point")) + err = send_cmd (runner, "y"); + else if (!strcmp (line, "passwd") + || !strcmp (line, "new_passwd")) + { + if (tuples) + { + size_t n; + const void *value; + + value = find_tuple (tuples, KEYBLOB_TAG_ENCKEY, &n); + if (!value) + err = gpg_error (GPG_ERR_INV_SESSION_KEY); + else if ((err = send_cmd_bin (runner, value, n))) + { + if (gpg_err_code (err) == GPG_ERR_BUG + && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + err = gpg_error (GPG_ERR_INV_SESSION_KEY); + } + } + else + err = gpg_error (GPG_ERR_NO_DATA); + } + else + err = send_cmd (runner, ""); /* Default to send an empty line. */ + } + else if (strstr (line, "encfs: unrecognized option '")) + err = gpg_error (GPG_ERR_INV_ENGINE); + else + err = 0; + + return err; +} + + +/* The main processing function as used by the runner. */ +static gpg_error_t +encfs_handler (void *opaque, runner_t runner, const char *status_line) +{ + encfs_parm_t parm = opaque; + gpg_error_t err; + + if (!parm || !runner) + return gpg_error (GPG_ERR_BUG); + if (!status_line) + { + /* Runner requested internal flushing - nothing to do here. */ + return 0; + } + + err = handle_status_line (runner, status_line, parm->cmd, parm->tuples); + if (gpg_err_code (err) == GPG_ERR_UNFINISHED + && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + { + err = 0; + /* No more need for the tuples. */ + destroy_tupledesc (parm->tuples); + parm->tuples = NULL; + + if (parm->cmd == ENCFS_CMD_CREATE) + { + /* The encfs tool keeps on running after creation of the + container. We don't want that and thus need to stop the + encfs process. */ + run_umount_helper (parm->mountpoint); + /* In case the umount helper does not work we try to kill + the engine. FIXME: We should figure out how to make + fusermount work. */ + runner_cancel (runner); + } + } + + return err; +} + + +/* Called by the runner to cleanup the private data. */ +static void +encfs_handler_cleanup (void *opaque) +{ + encfs_parm_t parm = opaque; + + if (!parm) + return; + + destroy_tupledesc (parm->tuples); + xfree (parm->mountpoint); + xfree (parm); +} + + +/* Run the encfs tool. */ +static gpg_error_t +run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, + const char *rawdir, const char *mountpoint, tupledesc_t tuples) +{ + gpg_error_t err; + encfs_parm_t parm; + runner_t runner = NULL; + int outbound[2] = { -1, -1 }; + int inbound[2] = { -1, -1 }; + const char *pgmname; + const char *argv[10]; + pid_t pid = (pid_t)(-1); + int idx; + + (void)ctrl; + + parm = xtrycalloc (1, sizeof *parm); + if (!parm) + { + err = gpg_error_from_syserror (); + goto leave; + } + parm->cmd = cmd; + parm->tuples = ref_tupledesc (tuples); + parm->mountpoint = xtrystrdup (mountpoint); + if (!parm->mountpoint) + { + err = gpg_error_from_syserror (); + goto leave; + } + + { + static int namecounter; + char buffer[50]; + + snprintf (buffer, sizeof buffer, "encfs-%d", ++namecounter); + err = runner_new (&runner, buffer); + if (err) + goto leave; + } + + err = gnupg_create_inbound_pipe (inbound); + if (!err) + err = gnupg_create_outbound_pipe (outbound); + if (err) + { + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + goto leave; + } + + pgmname = "/usr/bin/encfs"; + idx = 0; + argv[idx++] = "-f"; + argv[idx++] = "-v"; + argv[idx++] = "--stdinpass"; + argv[idx++] = "--annotate"; + argv[idx++] = rawdir; + argv[idx++] = mountpoint; + argv[idx++] = NULL; + assert (idx <= DIM (argv)); + + err = gnupg_spawn_process_fd (pgmname, argv, + outbound[0], -1, inbound[1], &pid); + if (err) + { + log_error ("error spawning `%s': %s\n", pgmname, gpg_strerror (err)); + goto leave; + } + close (outbound[0]); outbound[0] = -1; + close ( inbound[1]); inbound[1] = -1; + + runner_set_fds (runner, inbound[0], outbound[1]); + inbound[0] = -1; /* Now owned by RUNNER. */ + outbound[1] = -1; /* Now owned by RUNNER. */ + + runner_set_handler (runner, encfs_handler, encfs_handler_cleanup, parm); + parm = NULL; /* Now owned by RUNNER. */ + + runner_set_pid (runner, pid); + pid = (pid_t)(-1); /* The process is now owned by RUNNER. */ + + err = runner_spawn (runner); + if (err) + goto leave; + + log_info ("running `%s' in the background\n", pgmname); + + leave: + if (inbound[0] != -1) + close (inbound[0]); + if (inbound[1] != -1) + close (inbound[1]); + if (outbound[0] != -1) + close (outbound[0]); + if (outbound[1] != -1) + close (outbound[1]); + if (pid != (pid_t)(-1)) + { + gnupg_wait_process (pgmname, pid, NULL); + } + runner_release (runner); + encfs_handler_cleanup (parm); + return err; +} + + + + + /* See be_get_detached_name for a description. Note that the dispatcher code makes sure that NULL is stored at R_NAME before calling us. */ @@ -49,10 +338,134 @@ } +/* Create a new session key and append it as a tuple to the memory + buffer MB. + + The EncFS daemon takes a passphrase from stdin and internally + mangles it by means of some KDF from OpenSSL. We want to store a + binary key but we need to make sure that certain characters are not + used because the EncFS utility reads it from stdin and obviously + acts on some of the characters. This we replace CR (in case of an + MSDOS version of EncFS), LF (the delimiter used by EncFS) and Nul + (because it is unlikely to work). We use 32 bytes (256 bit) + because that is sufficient for the largest cipher (AES-256) and in + addition gives enough margin for a possible entropy degradation by + the KDF. */ gpg_error_t be_encfs_create_new_keys (membuf_t *mb) { + char *buffer; + int i, j; + + /* Allocate a buffer of 32 bytes plus 8 spare bytes we may need to + replace the unwanted values. */ + buffer = xtrymalloc_secure (32+8); + if (!buffer) + return gpg_error_from_syserror (); + + /* Randomize the buffer. STRONG random should be enough as it is a + good compromise between security and performance. The + anticipated usage of this tool is the quite often creation of new + containers and thus this should not deplete the system's entropy + tool too much. */ + gcry_randomize (buffer, 32+8, GCRY_STRONG_RANDOM); + for (i=j=0; i < 32; i++) + { + if (buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == 0 ) + { + /* Replace. */ + if (j == 8) + { + /* Need to get more random. */ + gcry_randomize (buffer+32, 8, GCRY_STRONG_RANDOM); + j = 0; + } + buffer[i] = buffer[32+j]; + j++; + } + } + + /* Store the key. */ + append_tuple (mb, KEYBLOB_TAG_ENCKEY, buffer, 32); + + /* Free the temporary buffer. */ + wipememory (buffer, 32+8); /* A failsafe extra wiping. */ + xfree (buffer); + return 0; } +/* Create the container described by the filename FNAME and the keyblob + information in TUPLES. */ +gpg_error_t +be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples) +{ + gpg_error_t err; + int dummy; + char *containername = NULL; + char *mountpoint = NULL; + + err = be_encfs_get_detached_name (fname, &containername, &dummy); + if (err) + goto leave; + + mountpoint = xtrystrdup ("/tmp/.#g13_XXXXXX"); + if (!mountpoint) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (!mkdtemp (mountpoint)) + { + err = gpg_error_from_syserror (); + log_error (_("can't create directory `%s': %s\n"), + "/tmp/g13-XXXXXX", gpg_strerror (err)); + goto leave; + } + + err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint, + tuples); + + /* In any case remove the temporary mount point. */ + if (rmdir (mountpoint)) + log_error ("error removing temporary mount point `%s': %s\n", + mountpoint, gpg_strerror (gpg_error_from_syserror ())); + + + leave: + xfree (containername); + xfree (mountpoint); + return err; +} + + +/* Mount the container described by the filename FNAME and the keyblob + information in TUPLES. */ +gpg_error_t +be_encfs_mount_container (ctrl_t ctrl, + const char *fname, const char *mountpoint, + tupledesc_t tuples) +{ + gpg_error_t err; + int dummy; + char *containername = NULL; + + if (!mountpoint) + { + log_error ("the encfs backend requires an explicit mountpoint\n"); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + + err = be_encfs_get_detached_name (fname, &containername, &dummy); + if (err) + goto leave; + + err = run_encfs_tool (ctrl, ENCFS_CMD_MOUNT, containername, mountpoint, + tuples); + + leave: + xfree (containername); + return err; +} Modified: trunk/g13/be-encfs.h =================================================================== --- trunk/g13/be-encfs.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/be-encfs.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -26,6 +26,15 @@ char **r_name, int *r_isdir); gpg_error_t be_encfs_create_new_keys (membuf_t *mb); +gpg_error_t be_encfs_create_container (ctrl_t ctrl, + const char *fname, + tupledesc_t tuples); +gpg_error_t be_encfs_mount_container (ctrl_t ctrl, + const char *fname, + const char *mountpoint, + tupledesc_t tuples); + + #endif /*G13_BE_ENCFS_H*/ Modified: trunk/g13/call-gpg.c =================================================================== --- trunk/g13/call-gpg.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/call-gpg.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -43,7 +43,7 @@ gpg_error_t err; assuan_context_t ctx = NULL; const char *pgmname; - const char *argv[6]; + const char *argv[7]; int no_close_list[5]; int i; char line[ASSUAN_LINELENGTH]; @@ -464,3 +464,133 @@ } + +/* Call GPG to decrypt a block of data. + + + */ +gpg_error_t +gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, + void **r_plain, size_t *r_plainlen) +{ + gpg_error_t err; + assuan_context_t ctx; + int outbound_fds[2] = { -1, -1 }; + int inbound_fds[2] = { -1, -1 }; + pth_t writer_tid = NULL; + pth_t reader_tid = NULL; + gpg_error_t writer_err, reader_err; + membuf_t reader_mb; + + *r_plain = NULL; + *r_plainlen = 0; + + /* Init the memory buffer to receive the encrypted stuff. */ + init_membuf_secure (&reader_mb, 1024); + + /* Create two pipes. */ + err = gnupg_create_outbound_pipe (outbound_fds); + if (!err) + err = gnupg_create_inbound_pipe (inbound_fds); + if (err) + { + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + goto leave; + } + + /* Start GPG and send the INPUT and OUTPUT commands. */ + err = start_gpg (ctrl, outbound_fds[0], inbound_fds[1], &ctx); + if (err) + goto leave; + close (outbound_fds[0]); outbound_fds[0] = -1; + close (inbound_fds[1]); inbound_fds[1] = -1; + + /* Start a writer thread to feed the INPUT command of the server. */ + err = start_writer (outbound_fds[1], ciph, ciphlen, + &writer_tid, &writer_err); + if (err) + return err; + outbound_fds[1] = -1; /* The thread owns the FD now. */ + + /* Start a reader thread to eat from the OUTPUT command of the + server. */ + err = start_reader (inbound_fds[0], &reader_mb, + &reader_tid, &reader_err); + if (err) + return err; + outbound_fds[0] = -1; /* The thread owns the FD now. */ + + /* Run the decryption. */ + err = assuan_transact (ctx, "DECRYPT", NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + { + log_error ("the engine's DECRYPT command failed: %s <%s>\n", + gpg_strerror (err), gpg_strsource (err)); + goto leave; + } + + /* Wait for reader and return the data. */ + if (!pth_join (reader_tid, NULL)) + { + err = gpg_error_from_syserror (); + log_error ("waiting for reader thread failed: %s\n", gpg_strerror (err)); + goto leave; + } + reader_tid = NULL; + if (reader_err) + { + err = reader_err; + log_error ("read error in reader thread: %s\n", gpg_strerror (err)); + goto leave; + } + + /* Wait for the writer to catch a writer error. */ + if (!pth_join (writer_tid, NULL)) + { + err = gpg_error_from_syserror (); + log_error ("waiting for writer thread failed: %s\n", gpg_strerror (err)); + goto leave; + } + writer_tid = NULL; + if (writer_err) + { + err = writer_err; + log_error ("write error in writer thread: %s\n", gpg_strerror (err)); + goto leave; + } + + /* Return the data. */ + *r_plain = get_membuf (&reader_mb, r_plainlen); + if (!*r_plain) + { + err = gpg_error_from_syserror (); + log_error ("error while storing the data in the reader thread: %s\n", + gpg_strerror (err)); + goto leave; + } + + leave: + if (reader_tid) + { + pth_cancel (reader_tid); + pth_join (reader_tid, NULL); + } + if (writer_tid) + { + pth_cancel (writer_tid); + pth_join (writer_tid, NULL); + } + if (outbound_fds[0] != -1) + close (outbound_fds[0]); + if (outbound_fds[1] != -1) + close (outbound_fds[1]); + if (inbound_fds[0] != -1) + close (inbound_fds[0]); + if (inbound_fds[1] != -1) + close (inbound_fds[1]); + release_gpg (ctx); + xfree (get_membuf (&reader_mb, NULL)); + return err; +} + + Modified: trunk/g13/call-gpg.h =================================================================== --- trunk/g13/call-gpg.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/call-gpg.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -23,6 +23,8 @@ gpg_error_t gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, void **r_ciph, size_t *r_ciphlen); +gpg_error_t gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, + void **r_plain, size_t *r_plainlen); Modified: trunk/g13/create.c =================================================================== --- trunk/g13/create.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/create.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -79,9 +79,9 @@ if (err) goto leave; + /* Just for testing. */ append_tuple (&mb, KEYBLOB_TAG_FILLER, "filler", 6); - *r_blob = get_membuf (&mb, r_bloblen); if (!*r_blob) { @@ -122,7 +122,7 @@ appropriate header. This fucntion is called with a lock file in place and after checking that the filename does not exists. */ static gpg_error_t -write_keyblob (ctrl_t ctrl, const char *filename, +write_keyblob (const char *filename, const void *keyblob, size_t keybloblen) { gpg_error_t err; @@ -152,7 +152,7 @@ packet[4] = 0; packet[5] = 26; memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype. */ - packet[16] = 1; /* G13 packet format. */ + packet[16] = 1; /* G13 packet format version. */ packet[17] = 0; /* Reserved. */ packet[18] = 0; /* Reserved. */ packet[19] = 0; /* OS Flag. */ @@ -202,7 +202,7 @@ return err; } - return err; + return 0; writeerr: @@ -220,7 +220,7 @@ using the current settings. If the file already exists an error is returned. */ gpg_error_t -create_new_container (ctrl_t ctrl, const char *filename) +g13_create_container (ctrl_t ctrl, const char *filename) { gpg_error_t err; dotlock_t lock; @@ -230,6 +230,7 @@ size_t enckeybloblen; char *detachedname = NULL; int detachedisdir; + tupledesc_t tuples = NULL; /* A quick check to see that no container with that name already exists. */ @@ -286,17 +287,28 @@ &enckeyblob, &enckeybloblen); if (err) goto leave; + + /* Put a copy of the keyblob into a tuple structure. */ + err = create_tupledesc (&tuples, keyblob, keybloblen); + if (err) + goto leave; + keyblob = NULL; + /* if (opt.verbose) */ + /* dump_keyblob (tuples); */ /* Write out the header, the encrypted keyblob and some padding. */ - err = write_keyblob (ctrl, filename, enckeyblob, enckeybloblen); + err = write_keyblob (filename, enckeyblob, enckeybloblen); if (err) goto leave; - /* Create and append the container. */ + /* Create and append the container. FIXME: We should pass the + estream object in addition to the filename, so that the backend + can append the container to the g13 file. */ + err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples); - leave: + destroy_tupledesc (tuples); xfree (detachedname); xfree (enckeyblob); xfree (keyblob); Modified: trunk/g13/create.h =================================================================== --- trunk/g13/create.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/create.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -20,7 +20,7 @@ #ifndef G13_CREATE_H #define G13_CREATE_H -gpg_error_t create_new_container (ctrl_t ctrl, const char *filename); +gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename); #endif /*G13_CREATE_H*/ Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/g13.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -35,8 +35,10 @@ #include "i18n.h" #include "sysutils.h" #include "gc-opt-flags.h" -#include "create.h" #include "keyblob.h" +#include "./runner.h" +#include "./create.h" +#include "./mount.h" enum cmd_and_opt_values { @@ -84,6 +86,7 @@ oHomedir, oWithColons, oDryRun, + oNoDetach, oRecipient, @@ -111,6 +114,7 @@ ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), ARGPARSE_s_n (oNoTTY, "no-tty", N_("don't use the terminal at all")), + ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")), ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write log output to FILE")), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), @@ -329,6 +333,7 @@ int nogreeting = 0; int debug_wait = 0; int use_random_seed = 1; + int nodetach = 0; int nokeysetup = 0; enum cmd_and_opt_values cmd = 0; struct server_control_s ctrl; @@ -499,6 +504,8 @@ case oAuditLog: auditlog = pargs.r.ret_str; break; + case oNoDetach: nodetach = 1; break; + case oDebug: debug_value |= pargs.r.ret_ulong; break; case oDebugAll: debug_value = ~0; break; case oDebugNone: debug_value = 0; break; @@ -677,16 +684,47 @@ { if (argc != 1) wrong_args ("--create filename"); - err = create_new_container (&ctrl, argv[0]); + err = g13_create_container (&ctrl, argv[0]); if (err) log_error ("error creating a new container: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); + else + { + unsigned int n; + + while ((n = runner_get_threads ())) + { + log_info ("number of running threads: %u\n", n); + pth_sleep (5); + } + } } break; + case aMount: /* Mount a container. */ + { + if (argc != 1 && argc != 2 ) + wrong_args ("--mount filename [mountpoint]"); + err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL); + if (err) + log_error ("error mounting container `%s': %s <%s>\n", + *argv, gpg_strerror (err), gpg_strsource (err)); + else + { + unsigned int n; + + while ((n = runner_get_threads ())) + { + log_info ("number of running threads: %u\n", n); + pth_sleep (5); + } + } + } + break; + default: - log_error (_("invalid command (there is no implicit command)\n")); - break; + log_error (_("invalid command (there is no implicit command)\n")); + break; } /* Print the audit result if needed. */ @@ -735,3 +773,84 @@ } +/* static void */ +/* daemonize (int nodetach) */ +/* { */ +/* gnupg_fd_t fd; */ +/* gnupg_fd_t fd_ssh; */ +/* pid_t pid; */ + +/* fflush (NULL); */ +/* #ifdef HAVE_W32_SYSTEM */ +/* pid = getpid (); */ +/* #else /\*!HAVE_W32_SYSTEM*\/ */ +/* pid = fork (); */ +/* if (pid == (pid_t)-1) */ +/* { */ +/* log_fatal ("fork failed: %s\n", strerror (errno) ); */ +/* g13_exit (1); */ +/* } */ +/* else if (pid) /\* We are the parent *\/ */ +/* { */ +/* /\* We need to clwanup our resources. An gcry_atfork might be */ +/* needed. *\/ */ +/* exit (0); */ +/* /\*NOTREACHED*\/ */ +/* } /\* End parent *\/ */ + +/* /\* */ +/* This is the child */ +/* *\/ */ + +/* /\* Detach from tty and put process into a new session *\/ */ +/* if (!nodetach ) */ +/* { */ +/* int i; */ +/* unsigned int oldflags; */ + +/* /\* Close stdin, stdout and stderr unless it is the log stream *\/ */ +/* for (i=0; i <= 2; i++) */ +/* { */ +/* if (!log_test_fd (i) && i != fd ) */ +/* { */ +/* if ( ! close (i) */ +/* && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1) */ +/* { */ +/* log_error ("failed to open `%s': %s\n", */ +/* "/dev/null", strerror (errno)); */ +/* cleanup (); */ +/* exit (1); */ +/* } */ +/* } */ +/* } */ +/* if (setsid() == -1) */ +/* { */ +/* log_error ("setsid() failed: %s\n", strerror(errno) ); */ +/* cleanup (); */ +/* exit (1); */ +/* } */ + +/* log_get_prefix (&oldflags); */ +/* log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED); */ +/* opt.running_detached = 1; */ +/* } */ + +/* if (chdir("/")) */ +/* { */ +/* log_error ("chdir to / failed: %s\n", strerror (errno)); */ +/* exit (1); */ +/* } */ + +/* { */ +/* struct sigaction sa; */ + +/* sa.sa_handler = SIG_IGN; */ +/* sigemptyset (&sa.sa_mask); */ +/* sa.sa_flags = 0; */ +/* sigaction (SIGPIPE, &sa, NULL); */ +/* } */ +/* #endif /\*!HAVE_W32_SYSTEM*\/ */ + +/* log_info ("%s %s started\n", strusage(11), strusage(13) ); */ +/* handle_something (fd, opt.ssh_support ? fd_ssh : GNUPG_INVALID_FD); */ +/* } */ Modified: trunk/g13/keyblob.h =================================================================== --- trunk/g13/keyblob.h 2009-10-13 09:13:19 UTC (rev 5174) +++ trunk/g13/keyblob.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -63,8 +63,9 @@ #define KEYBLOB_TAG_BLOBVERSION 0 /* This tag is used to describe the version of the keyblob. It must - be the first tag in a keyblob. Its value is a single byte giving - the blob version. The current version is 1. */ + be the first tag in a keyblob and may only occur once. Its value + is a single byte giving the blob version. The only defined version + is 1. */ #define KEYBLOB_TAG_CONTTYPE 1 /* This tag gives the type of the container. The value is a two byte Added: trunk/g13/mount.c =================================================================== --- trunk/g13/mount.c (rev 0) +++ trunk/g13/mount.c 2009-10-13 19:17:24 UTC (rev 5175) @@ -0,0 +1,303 @@ +/* mount.c - Mount a crypto container + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "i18n.h" +#include "mount.h" + +#include "keyblob.h" +#include "backend.h" +#include "utils.h" +#include "call-gpg.h" +#include "estream.h" + + +/* Parse the header prefix and return the length of the entire header. */ +static gpg_error_t +parse_header (const char *filename, + const unsigned char *packet, size_t packetlen, + size_t *r_headerlen) +{ + unsigned int len; + + if (packetlen != 32) + return gpg_error (GPG_ERR_BUG); + + len = ((packet[2] << 24) | (packet[3] << 16) + | (packet[4] << 8) | packet[5]); + if (packet[0] != (0xc0|61) || len < 26 + || memcmp (packet+6, "GnuPG/G13", 10)) + { + log_error ("file `%s' is not valid container\n", filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + if (packet[16] != 1) + { + log_error ("unknown version %u of container `%s'\n", + (unsigned int)packet[16], filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + if (packet[17] || packet[18] + || packet[26] || packet[27] || packet[28] || packet[29] + || packet[30] || packet[31]) + log_info ("WARNING: unknown meta information in `%s'\n", filename); + if (packet[19]) + log_info ("WARNING: OS flag is not supported in `%s'\n", filename); + if (packet[24] != 1 || packet[25] != 0) + { + log_error ("meta data copies in `%s' are not supported\n", filename); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + + len = ((packet[20] << 24) | (packet[21] << 16) + | (packet[22] << 8) | packet[23]); + + /* Do a basic sanity check on the length. */ + if (len < 32 || len > 1024*1024) + { + log_error ("bad length given in container `%s'\n", filename); + return gpg_error (GPG_ERR_INV_OBJ); + } + + *r_headerlen = len; + return 0; +} + + + +/* Read the keyblob at FILENAME. The caller should have acquired a + lockfile and checked that the file exists. */ +static gpg_error_t +read_keyblob (const char *filename, + void **r_enckeyblob, size_t *r_enckeybloblen) +{ + gpg_error_t err; + estream_t fp; + unsigned char packet[32]; + size_t headerlen, msglen; + void *msg = NULL; + + *r_enckeyblob = NULL; + *r_enckeybloblen = 0; + + fp = es_fopen (filename, "rb"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("error reading `%s': %s\n", + filename, gpg_strerror (err)); + return err; + } + + /* Read the header. It is defined as 32 bytes thus we read it in one go. */ + if (es_fread (packet, 32, 1, fp) != 1) + { + err = gpg_error_from_syserror (); + log_error ("error reading the header of `%s': %s\n", + filename, gpg_strerror (err)); + goto leave; + } + + err = parse_header (filename, packet, 32, &headerlen); + if (err) + goto leave; + + if (opt.verbose) + log_info ("header length of `%s' is %zu\n", filename, headerlen); + + /* Read everything including the padding. We should eventually do a + regular OpenPGP parsing to detect the padding packet and pass + only the actual used OpenPGP data to the engine. This is in + particular required when supporting CMS which will be + encapsulated in an OpenPGP packet. */ + assert (headerlen >= 32); + msglen = headerlen - 32; + if (!msglen) + { + err = gpg_error (GPG_ERR_NO_DATA); + goto leave; + } + msg = xtrymalloc (msglen); + if (!msglen) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (es_fread (msg, msglen, 1, fp) != 1) + { + err = gpg_error_from_syserror (); + log_error ("error reading keyblob of `%s': %s\n", + filename, gpg_strerror (err)); + goto leave; + } + + *r_enckeyblob = msg; + msg = NULL; + *r_enckeybloblen = msglen; + + leave: + xfree (msg); + es_fclose (fp); + + return err; +} + + + + +/* Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result at + (R_KEYBLOB, R_KEYBLOBLEN). Returns 0 on success or an error code. + On error R_KEYBLOB is set to NULL. */ +static gpg_error_t +decrypt_keyblob (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen, + void **r_keyblob, size_t *r_keybloblen) +{ + gpg_error_t err; + + /* FIXME: For now we only implement OpenPGP. */ + err = gpg_decrypt_blob (ctrl, enckeyblob, enckeybloblen, + r_keyblob, r_keybloblen); + + return err; +} + + +static void +dump_keyblob (tupledesc_t tuples) +{ + size_t n; + unsigned int tag; + const void *value; + + log_info ("keyblob dump:\n"); + tag = KEYBLOB_TAG_BLOBVERSION; + value = find_tuple (tuples, tag, &n); + while (value) + { + log_info (" tag: %-5u len: %-2u value: ", tag, (unsigned int)n); + if (tag == KEYBLOB_TAG_ENCKEY + || tag == KEYBLOB_TAG_MACKEY) + log_printf ("[confidential]\n"); + else if (!n) + log_printf ("[none]\n"); + else + log_printhex ("", value, n); + value = next_tuple (tuples, &tag, &n); + } +} + + + +/* Mount the container with name FILENAME at MOUNTPOINT. */ +gpg_error_t +g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) +{ + gpg_error_t err; + dotlock_t lock; + void *enckeyblob = NULL; + size_t enckeybloblen; + void *keyblob = NULL; + size_t keybloblen; + tupledesc_t tuples = NULL; + size_t n; + const unsigned char *value; + int conttype; + + /* A quick check to see whether the container exists. */ + if (access (filename, R_OK)) + return gpg_error_from_syserror (); + + /* Try to take a lock. */ + lock = create_dotlock (filename); + if (!lock) + return gpg_error_from_syserror (); + + if (make_dotlock (lock, 0)) + { + err = gpg_error_from_syserror (); + goto leave; + } + else + err = 0; + + /* Check again that the file exists. */ + { + struct stat sb; + + if (stat (filename, &sb)) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + /* Read the encrypted keyblob. */ + err = read_keyblob (filename, &enckeyblob, &enckeybloblen); + if (err) + goto leave; + + /* Decrypt that keyblob and store it in a tuple descriptor. */ + err = decrypt_keyblob (ctrl, enckeyblob, enckeybloblen, + &keyblob, &keybloblen); + if (err) + goto leave; + xfree (enckeyblob); + enckeyblob = NULL; + + err = create_tupledesc (&tuples, keyblob, keybloblen); + if (!err) + keyblob = NULL; + else + { + if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) + log_error ("unknown keyblob version\n"); + goto leave; + } + if (opt.verbose) + dump_keyblob (tuples); + + value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n); + if (!value || n != 2) + conttype = 0; + else + conttype = (value[0] << 8 | value[1]); + if (!be_is_supported_conttype (conttype)) + { + log_error ("content type %d is not supported\n", conttype); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples); + + leave: + destroy_tupledesc (tuples); + xfree (keyblob); + xfree (enckeyblob); + destroy_dotlock (lock); + return err; +} Added: trunk/g13/mount.h =================================================================== --- trunk/g13/mount.h (rev 0) +++ trunk/g13/mount.h 2009-10-13 19:17:24 UTC (rev 5175) @@ -0,0 +1,29 @@ +/* mmount.h - Defs to mount a crypto container + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#ifndef G13_MOUNT_H +#define G13_MOUNT_H + +gpg_error_t g13_mount_container (ctrl_t ctrl, + const char *filename, + const char *mountpoint); + + From cvs at cvs.gnupg.org Wed Oct 14 01:38:23 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 14 Oct 2009 01:38:23 +0200 Subject: [svn] assuan - r307 - trunk/src Message-ID: Author: marcus Date: 2009-10-14 01:38:23 +0200 (Wed, 14 Oct 2009) New Revision: 307 Removed: trunk/src/assuan-util.c Log: Really delete. From cvs at cvs.gnupg.org Wed Oct 14 13:27:08 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 14 Oct 2009 13:27:08 +0200 Subject: [svn] assuan - r308 - in trunk: . doc src Message-ID: Author: wk Date: 2009-10-14 13:27:08 +0200 (Wed, 14 Oct 2009) New Revision: 308 Modified: trunk/NEWS trunk/autogen.sh trunk/doc/ChangeLog trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/assuan-defs.h trunk/src/assuan-handler.c trunk/src/assuan.c trunk/src/assuan.h trunk/src/libassuan.def trunk/src/libassuan.vers Log: Add new ducntion assuan_get_command_name. This makes error reporting in the server much easier. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/doc/ChangeLog 2009-10-14 11:27:08 UTC (rev 308) @@ -1,3 +1,7 @@ +2009-10-14 Werner Koch + + * assuan.texi (Utilities): Describe assuan_get_command_name. + 2009-09-21 Marcus Brinkmann * assuan.texi: Update to new API. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/ChangeLog 2009-10-14 11:27:08 UTC (rev 308) @@ -1,3 +1,10 @@ +2009-10-14 Werner Koch + + * assuan-defs.h (assuan_context_s): Add field CURRENT_CMD_NAME. + * assuan-handler.c (dispatch_command): Set this field. + (assuan_get_command_name): New. + * assuan.h, libassuan.vers, libassuan.def: Add new fucntion. + 2009-10-08 Marcus Brinkmann * assuan.h (assuan_get_assuan_log_stream, Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/NEWS 2009-10-14 11:27:08 UTC (rev 308) @@ -50,8 +50,10 @@ assuan_set_io_hooks REMOVED: Will come back in expanded form. assuan_io_hooks_t REMOVED: Will come back in expanded form. assuan_io_monitor_t CHANGED: Add a hook data argument. +assuan_get_command_name NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Noteworthy changes in version 1.0.5 (2008-05-25) ------------------------------------------------ Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/autogen.sh 2009-10-14 11:27:08 UTC (rev 308) @@ -197,4 +197,6 @@ echo "Running autoconf${FORCE} ..." $AUTOCONF${FORCE} -echo "You may now run \"./configure --enable-maintainer-mode && make\"." +echo "You may now run + ./configure --enable-maintainer-mode && make +" Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/doc/assuan.texi 2009-10-14 11:27:08 UTC (rev 308) @@ -1675,6 +1675,15 @@ @end deftypefun + at deftypefun @w{const char *} assuan_get_command_name (@w{assuan_context_t @var{ctx}}) + +Return the name of the command currently processed by a handler. +The returned string is valid until the next call to an Assuan +function on the same context. Returns @code{NULL} if no handler is +executed or the command is not known. + at end deftypefun + + @deftypefun int assuan_get_input_fd (@w{assuan_context_t @var{ctx}}) Return the file descriptor sent by the client using the last @code{INPUT} Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/assuan-defs.h 2009-10-14 11:27:08 UTC (rev 308) @@ -200,6 +200,11 @@ struct cmdtbl_s *cmdtbl; size_t cmdtbl_used; /* used entries */ size_t cmdtbl_size; /* allocated size of table */ + + /* The name of the command currently processed by a command handler. + This is a pointer into CMDTBL. NULL if not in a command + handler. */ + const char *current_cmd_name; void (*bye_notify_fnc)(assuan_context_t); void (*reset_notify_fnc)(assuan_context_t); Modified: trunk/src/assuan-handler.c =================================================================== --- trunk/src/assuan-handler.c 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/assuan-handler.c 2009-10-14 11:27:08 UTC (rev 308) @@ -330,6 +330,16 @@ return 0; } +/* Return the name of the command currently processed by a handler. + The string returned is valid until the next call to an assuan + function on the same context. Returns NULL if no handler is + executed or the command is not known. */ +const char * +assuan_get_command_name (assuan_context_t ctx) +{ + return ctx? ctx->current_cmd_name : NULL; +} + gpg_error_t assuan_register_post_cmd_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t, gpg_error_t)) @@ -453,6 +463,7 @@ static gpg_error_t dispatch_command (assuan_context_t ctx, char *line, int linelen) { + gpg_error_t err; char *p; const char *s; int shift, i; @@ -499,7 +510,10 @@ linelen -= shift; /* fprintf (stderr, "DBG-assuan: processing %s `%s'\n", s, line); */ - return ctx->cmdtbl[i].handler (ctx, line); + ctx->current_cmd_name = ctx->cmdtbl[i].name; + err = ctx->cmdtbl[i].handler (ctx, line); + ctx->current_cmd_name = NULL; + return err; } Modified: trunk/src/assuan.c =================================================================== --- trunk/src/assuan.c 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/assuan.c 2009-10-14 11:27:08 UTC (rev 308) @@ -160,7 +160,7 @@ ctx->engine.release = NULL; } - // FIXME: Clean standard commands + /* FIXME: Clean standard commands */ } Modified: trunk/src/assuan.h =================================================================== --- trunk/src/assuan.h 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/assuan.h 2009-10-14 11:27:08 UTC (rev 308) @@ -288,6 +288,7 @@ int assuan_get_active_fds (assuan_context_t ctx, int what, assuan_fd_t *fdarray, int fdarraysize); +const char *assuan_get_command_name (assuan_context_t ctx); FILE *assuan_get_data_fp (assuan_context_t ctx); gpg_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line); Modified: trunk/src/libassuan.def =================================================================== --- trunk/src/libassuan.def 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/libassuan.def 2009-10-14 11:27:08 UTC (rev 308) @@ -84,6 +84,7 @@ assuan_transact @63 assuan_write_line @64 assuan_write_status @65 + assuan_get_command_name @66 ; END Modified: trunk/src/libassuan.vers =================================================================== --- trunk/src/libassuan.vers 2009-10-13 23:38:23 UTC (rev 307) +++ trunk/src/libassuan.vers 2009-10-14 11:27:08 UTC (rev 308) @@ -30,6 +30,7 @@ assuan_end_confidential; assuan_get_active_fds; assuan_get_assuan_log_prefix; + assuan_get_command_name; assuan_get_data_fp; assuan_get_flag; assuan_get_input_fd; From cvs at cvs.gnupg.org Wed Oct 14 19:06:10 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 14 Oct 2009 19:06:10 +0200 Subject: [svn] GnuPG - r5176 - trunk/g13 Message-ID: Author: wk Date: 2009-10-14 19:06:10 +0200 (Wed, 14 Oct 2009) New Revision: 5176 Added: trunk/g13/server.c trunk/g13/server.h Modified: trunk/g13/Makefile.am trunk/g13/be-encfs.c trunk/g13/create.c trunk/g13/g13.c trunk/g13/g13.h trunk/g13/runner.c trunk/g13/runner.h Log: mount does now work in server and standalone mode. Implemented a signal handler. Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/Makefile.am 2009-10-14 17:06:10 UTC (rev 5176) @@ -30,6 +30,7 @@ g13.c g13.h \ keyblob.h \ utils.c utils.h \ + server.c server.h \ create.c create.h \ mount.c mount.h \ call-gpg.c call-gpg.h \ Modified: trunk/g13/be-encfs.c =================================================================== --- trunk/g13/be-encfs.c 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/be-encfs.c 2009-10-14 17:06:10 UTC (rev 5176) @@ -262,7 +262,8 @@ pgmname = "/usr/bin/encfs"; idx = 0; argv[idx++] = "-f"; - argv[idx++] = "-v"; + if (opt.verbose) + argv[idx++] = "-v"; argv[idx++] = "--stdinpass"; argv[idx++] = "--annotate"; argv[idx++] = rawdir; Modified: trunk/g13/create.c =================================================================== --- trunk/g13/create.c 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/create.c 2009-10-14 17:06:10 UTC (rev 5176) @@ -39,7 +39,7 @@ /* Create a new blob with all the session keys and other meta information which are to be stored encrypted in the crypto container header. On success the malloced blob is stored at R_BLOB - and its length at R_BLOBLEN. On error en error ocde is returned + and its length at R_BLOBLEN. On error an error code is returned and (R_BLOB,R_BLOBLEN) are set to (NULL,0). The format of this blob is a sequence of tag-length-value tuples. Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/g13.c 2009-10-14 17:06:10 UTC (rev 5176) @@ -36,8 +36,9 @@ #include "sysutils.h" #include "gc-opt-flags.h" #include "keyblob.h" -#include "./runner.h" -#include "./create.h" +#include "server.h" +#include "runner.h" +#include "create.h" #include "./mount.h" @@ -51,6 +52,7 @@ aCreate, aMount, aUmount, + aServer, oOptions, oDebug, @@ -102,6 +104,7 @@ ARGPARSE_c (aCreate, "create", N_("Create a new file system container")), ARGPARSE_c (aMount, "mount", N_("Mount a file system container") ), ARGPARSE_c (aUmount, "umount", N_("Unmount a file system container") ), + ARGPARSE_c (aServer, "server", N_("Run in server mode")), ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"), ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"), @@ -168,6 +171,10 @@ }; +/* The timer tick interval used by the idle task. */ +#define TIMERTICK_INTERVAL_SEC (1) + + /* Global variable to keep an error count. */ int g13_errors_seen = 0; @@ -178,11 +185,23 @@ static const char *debug_level; static unsigned int debug_value; +/* Flag to indicate that a shutdown was requested. */ +static int shutdown_pending; + +/* The thread id of the idle task. */ +static pth_t idle_task_tid; + + + static void set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ); static void emergency_cleanup (void); +static void start_idle_task (void); +static void join_idle_task (void); + + /* Begin Pth wrapper functions. */ GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) @@ -475,6 +494,7 @@ nokeysetup = 1; break; + case aServer: case aMount: case aUmount: nokeysetup = 1; @@ -591,9 +611,9 @@ if (greeting) { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); + fprintf (stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + fprintf (stderr, "%s\n", strusage(15) ); } if (may_coredump && !opt.quiet) @@ -680,24 +700,25 @@ configuration file is valid. */ break; + case aServer: + { + start_idle_task (); + err = g13_server (&ctrl); + if (err) + log_error ("server exited with error: %s <%s>\n", + gpg_strerror (err), gpg_strsource (err)); + } + break; + case aCreate: /* Create a new container. */ { if (argc != 1) wrong_args ("--create filename"); + start_idle_task (); err = g13_create_container (&ctrl, argv[0]); if (err) log_error ("error creating a new container: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); - else - { - unsigned int n; - - while ((n = runner_get_threads ())) - { - log_info ("number of running threads: %u\n", n); - pth_sleep (5); - } - } } break; @@ -705,20 +726,11 @@ { if (argc != 1 && argc != 2 ) wrong_args ("--mount filename [mountpoint]"); + start_idle_task (); err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL); if (err) log_error ("error mounting container `%s': %s <%s>\n", *argv, gpg_strerror (err), gpg_strsource (err)); - else - { - unsigned int n; - - while ((n = runner_get_threads ())) - { - log_info ("number of running threads: %u\n", n); - pth_sleep (5); - } - } } break; @@ -727,6 +739,9 @@ break; } + if (!err) + join_idle_task (); + /* Print the audit result if needed. */ if (auditlog && auditfp) { @@ -741,6 +756,7 @@ return 8; /*NOTREACHED*/ } + /* Note: This function is used by signal handlers!. */ static void emergency_cleanup (void) @@ -766,6 +782,7 @@ } +/* Store defaults into the per-connection CTRL object. */ void g13_init_default_ctrl (struct server_control_s *ctrl) { @@ -773,84 +790,179 @@ } -/* static void */ -/* daemonize (int nodetach) */ -/* { */ -/* gnupg_fd_t fd; */ -/* gnupg_fd_t fd_ssh; */ -/* pid_t pid; */ +/* This function is called for each signal we catch. It is run in the + main context or the one of a Pth thread and thus it is not + restricted in what it may do. */ +static void +handle_signal (int signo) +{ + switch (signo) + { +#ifndef HAVE_W32_SYSTEM + case SIGHUP: + log_info ("SIGHUP received - re-reading configuration\n"); + /* Fixme: Not yet implemented. */ + break; + + case SIGUSR1: + log_info ("SIGUSR1 received - printing internal information:\n"); + pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); + break; -/* fflush (NULL); */ -/* #ifdef HAVE_W32_SYSTEM */ -/* pid = getpid (); */ -/* #else /\*!HAVE_W32_SYSTEM*\/ */ -/* pid = fork (); */ -/* if (pid == (pid_t)-1) */ -/* { */ -/* log_fatal ("fork failed: %s\n", strerror (errno) ); */ -/* g13_exit (1); */ -/* } */ -/* else if (pid) /\* We are the parent *\/ */ -/* { */ -/* /\* We need to clwanup our resources. An gcry_atfork might be */ -/* needed. *\/ */ -/* exit (0); */ -/* /\*NOTREACHED*\/ */ -/* } /\* End parent *\/ */ + case SIGUSR2: + log_info ("SIGUSR2 received - no action defined\n"); + break; -/* /\* */ -/* This is the child */ -/* *\/ */ - -/* /\* Detach from tty and put process into a new session *\/ */ -/* if (!nodetach ) */ -/* { */ -/* int i; */ -/* unsigned int oldflags; */ + case SIGTERM: + if (!shutdown_pending) + log_info ("SIGTERM received - shutting down ...\n"); + else + log_info ("SIGTERM received - still %u runners active\n", + runner_get_threads ()); + shutdown_pending++; + if (shutdown_pending > 2) + { + log_info ("shutdown forced\n"); + log_info ("%s %s stopped\n", strusage(11), strusage(13) ); + g13_exit (0); + } + break; -/* /\* Close stdin, stdout and stderr unless it is the log stream *\/ */ -/* for (i=0; i <= 2; i++) */ -/* { */ -/* if (!log_test_fd (i) && i != fd ) */ -/* { */ -/* if ( ! close (i) */ -/* && open ("/dev/null", i? O_WRONLY : O_RDONLY) == -1) */ -/* { */ -/* log_error ("failed to open `%s': %s\n", */ -/* "/dev/null", strerror (errno)); */ -/* cleanup (); */ -/* exit (1); */ -/* } */ -/* } */ -/* } */ -/* if (setsid() == -1) */ -/* { */ -/* log_error ("setsid() failed: %s\n", strerror(errno) ); */ -/* cleanup (); */ -/* exit (1); */ -/* } */ + case SIGINT: + log_info ("SIGINT received - immediate shutdown\n"); + log_info( "%s %s stopped\n", strusage(11), strusage(13)); + g13_exit (0); + break; +#endif /*!HAVE_W32_SYSTEM*/ + + default: + log_info ("signal %d received - no action defined\n", signo); + } +} -/* log_get_prefix (&oldflags); */ -/* log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED); */ -/* opt.running_detached = 1; */ -/* } */ + +/* This ticker function is called about every TIMERTICK_INTERVAL_SEC + seconds. */ +static void +handle_tick (void) +{ + /* log_debug ("TICK\n"); */ +} + + +/* The idle task. We use a separate thread to do idle stuff and to + catch signals. */ +static void * +idle_task (void *dummy_arg) +{ + sigset_t sigs; /* The set of signals we want to catch. */ + pth_event_t ev; /* The main event to catch signals. */ + pth_event_t time_ev; /* The time event. */ + int signo; /* The number of a raised signal is stored here. */ + + (void)dummy_arg; + + /* Create the event to catch the signals. */ +#ifndef HAVE_W32_SYSTEM + sigemptyset (&sigs ); + sigaddset (&sigs, SIGHUP); + sigaddset (&sigs, SIGUSR1); + sigaddset (&sigs, SIGUSR2); + sigaddset (&sigs, SIGINT); + sigaddset (&sigs, SIGTERM); + pth_sigmask (SIG_UNBLOCK, &sigs, NULL); +#else + sigs = 0; +#endif + ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); + + /* The time event neds to computed n tghe fly. */ + time_ev = NULL; + + for (;;) + { + /* The shutdown flag allows us to terminate the idle task. */ + if (shutdown_pending) + { + runner_cancel_all (); + + if (!runner_get_threads ()) + break; /* ready */ + } + + /* Create a timeout event if needed. To help with power saving + we syncronize the ticks to the next full second. */ + if (!time_ev) + { + pth_time_t nexttick; + + nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC, 0); + if (nexttick.tv_usec > 10) /* Use a 10 usec threshhold. */ + { + nexttick.tv_sec++; + nexttick.tv_usec = 0; + } + time_ev = pth_event (PTH_EVENT_TIME, nexttick); + } + + pth_event_concat (ev, time_ev, NULL); + pth_wait (ev); + pth_event_isolate (time_ev); + + if (pth_event_occurred (ev)) + { + handle_signal (signo); + } + + if (time_ev && pth_event_occurred (time_ev)) + { + pth_event_free (time_ev, PTH_FREE_ALL); + time_ev = NULL; + handle_tick (); + } + } + + pth_event_free (ev, PTH_FREE_ALL); + if (time_ev) + pth_event_free (time_ev, PTH_FREE_ALL); + log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); + return NULL; +} + + +/* Start the idle task. */ +static void +start_idle_task (void) +{ + pth_attr_t tattr; + pth_t tid; -/* if (chdir("/")) */ -/* { */ -/* log_error ("chdir to / failed: %s\n", strerror (errno)); */ -/* exit (1); */ -/* } */ + tattr = pth_attr_new (); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); + pth_attr_set (tattr, PTH_ATTR_NAME, "idle-task"); + + tid = pth_spawn (tattr, idle_task, NULL); + if (!tid) + { + log_fatal ("error starting idle task: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return; /*NOTREACHED*/ + } + idle_task_tid = tid; + pth_attr_destroy (tattr); +} -/* { */ -/* struct sigaction sa; */ - -/* sa.sa_handler = SIG_IGN; */ -/* sigemptyset (&sa.sa_mask); */ -/* sa.sa_flags = 0; */ -/* sigaction (SIGPIPE, &sa, NULL); */ -/* } */ -/* #endif /\*!HAVE_W32_SYSTEM*\/ */ -/* log_info ("%s %s started\n", strusage(11), strusage(13) ); */ -/* handle_something (fd, opt.ssh_support ? fd_ssh : GNUPG_INVALID_FD); */ -/* } */ +/* Wait for the idle task to finish. */ +static void +join_idle_task (void) +{ + if (idle_task_tid) + { + if (!pth_join (idle_task_tid, NULL)) + log_error ("waiting for idle task thread failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + } +} + Modified: trunk/g13/g13.h =================================================================== --- trunk/g13/g13.h 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/g13.h 2009-10-14 17:06:10 UTC (rev 5176) @@ -30,6 +30,7 @@ #include "../common/status.h" #include "../common/estream.h" #include "../common/audit.h" +#include "../common/session-env.h" /* A large struct named "opt" to keep global flags. */ struct @@ -58,6 +59,7 @@ char *lc_messages; char *xauthority; char *pinentry_user_data; + session_env_t session_env; /* Name of the output file - FIXME: what is this? */ const char *outfile; Modified: trunk/g13/runner.c =================================================================== --- trunk/g13/runner.c 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/runner.c 2009-10-14 17:06:10 UTC (rev 5176) @@ -40,9 +40,12 @@ int spawned; /* True if runner_spawn has been called. */ pth_t threadid; /* The TID of the runner thread. */ + runner_t next_running; /* Builds a list of all running threads. */ + int canceled; /* Set if a cancel has already been send once. */ int cancel_flag; /* If set the thread should terminate itself. */ + /* We use a reference counter to know when it is safe to remove the object. Lackiong an explicit ref fucntion this counter will take only these two values: @@ -66,10 +69,11 @@ }; -/* Avariabale to track the number of active runner threads. */ -static unsigned int thread_count; +/* The head of the list of all running threads. */ +static runner_t running_threads; + /* Write NBYTES of BUF to file descriptor FD. */ static int @@ -114,7 +118,12 @@ unsigned int runner_get_threads (void) { - return thread_count; + unsigned int n = 0; + runner_t r; + + for (r = running_threads; r; r = r->next_running) + n++; + return n; } @@ -240,7 +249,7 @@ runner_thread (void *arg) { runner_t runner = arg; - gpg_error_t err; + gpg_error_t err = 0; log_debug ("starting runner thread\n"); /* If a status_fp is available, the thread's main task is to read @@ -257,7 +266,6 @@ estream_t fp = runner->status_fp; pos = 0; - err = 0; cont_line = 0; while (!err && !runner->cancel_flag && (c=es_getc (fp)) != EOF) { @@ -322,9 +330,22 @@ /* Get rid of the runner object (note: it is refcounted). */ log_debug ("runner thread releasing runner ...\n"); + { + runner_t r, rprev; + + for (r = running_threads, rprev = NULL; r; rprev = r, r = r->next_running) + if (r == runner) + { + if (!rprev) + running_threads = r->next_running; + else + rprev->next_running = r->next_running; + r->next_running = NULL; + break; + } + } runner_release (runner); log_debug ("runner thread runner released\n"); - thread_count--; return NULL; } @@ -374,14 +395,14 @@ } /* The scheduler has not yet kicked in, thus we can safely set the spawned flag and the tid. */ - thread_count++; runner->spawned = 1; runner->threadid = tid; + runner->next_running = running_threads; + running_threads = runner; + pth_attr_destroy (tattr); /* The runner thread is now runnable. */ - - return 0; } @@ -391,8 +412,10 @@ void runner_cancel (runner_t runner) { + /* Warning: runner_cancel_all has knowledge of this code. */ if (runner->spawned) { + runner->canceled = 1; /* Mark that we canceled this one already. */ /* FIXME: This does only work if the thread emits status lines. We need to change the trhead to wait on an event. */ runner->cancel_flag = 1; @@ -402,6 +425,25 @@ } +/* Cancel all runner threads. */ +void +runner_cancel_all (void) +{ + runner_t r; + + do + { + for (r = running_threads; r; r = r->next_running) + if (r->spawned && !r->canceled) + { + runner_cancel (r); + break; + } + } + while (r); +} + + /* Send a line of data down to the engine. This line may not contain a binary Nul or a LF character. This function is used by the engine's handler. */ Modified: trunk/g13/runner.h =================================================================== --- trunk/g13/runner.h 2009-10-13 19:17:24 UTC (rev 5175) +++ trunk/g13/runner.h 2009-10-14 17:06:10 UTC (rev 5176) @@ -57,6 +57,9 @@ /* Cancel a runner. */ void runner_cancel (runner_t runner); +/* Cancel all runner. */ +void runner_cancel_all (void); + /* Send data back to the engine. This function is used by the engine's handler. */ gpg_error_t runner_send_line (runner_t runner, Added: trunk/g13/server.c =================================================================== --- trunk/g13/server.c (rev 0) +++ trunk/g13/server.c 2009-10-14 17:06:10 UTC (rev 5176) @@ -0,0 +1,709 @@ +/* server.c - The G13 Assuan server + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include +#include "i18n.h" +#include "keyblob.h" +#include "./server.h" +#include "./mount.h" + + +/* Local data for this server module. A pointer to this is stored in + the CTRL object of each connection. */ +struct server_local_s +{ + /* The Assuan contect we are working on. */ + assuan_context_t assuan_ctx; + + char *mountpoint; /* Malloced current mountpoint. */ + +}; + + +/* Cookie definition for assuan data line output. */ +static ssize_t data_line_cookie_write (void *cookie, + const void *buffer, size_t size); +static int data_line_cookie_close (void *cookie); +static es_cookie_io_functions_t data_line_cookie_functions = + { + NULL, + data_line_cookie_write, + NULL, + data_line_cookie_close + }; + + +/* The filepointer for status message used in non-server mode. */ +/* static FILE *statusfp; FIXME; */ + + + + +static int command_has_option (const char *cmd, const char *cmdopt); + + + + +#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) + + + + +/* 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. */ +static int +has_option (const char *line, const char *name) +{ + const char *s; + 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))); +} + + +/* A write handler used by es_fopencookie to write Assuan data + lines. */ +static ssize_t +data_line_cookie_write (void *cookie, const void *buffer, size_t size) +{ + assuan_context_t ctx = cookie; + + if (assuan_send_data (ctx, buffer, size)) + { + errno = EIO; + return -1; + } + + return size; +} + +/* A close handler used by es_fopencookie to write Assuan data + lines. */ +static int +data_line_cookie_close (void *cookie) +{ + assuan_context_t ctx = cookie; + + if (assuan_send_data (ctx, NULL, 0)) + { + errno = EIO; + return -1; + } + + return 0; +} + + +/* The handler for Assuan OPTION commands. */ +static gpg_error_t +option_handler (assuan_context_t ctx, const char *key, const char *value) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + + if (!strcmp (key, "putenv")) + { + /* Change the session's environment to be used for the + Pinentry. Valid values are: + Delete envvar NAME + = Set envvar NAME to the empty string + = Set envvar NAME to VALUE + */ + err = session_env_putenv (opt.session_env, value); + } + else if (!strcmp (key, "display")) + { + err = session_env_setenv (opt.session_env, "DISPLAY", value); + } + else if (!strcmp (key, "ttyname")) + { + err = session_env_setenv (opt.session_env, "GPG_TTY", value); + } + else if (!strcmp (key, "ttytype")) + { + err = session_env_setenv (opt.session_env, "TERM", value); + } + else if (!strcmp (key, "lc-ctype")) + { + xfree (opt.lc_ctype); + opt.lc_ctype = xtrystrdup (value); + if (!opt.lc_ctype) + err = gpg_error_from_syserror (); + } + else if (!strcmp (key, "lc-messages")) + { + xfree (opt.lc_messages); + opt.lc_messages = xtrystrdup (value); + if (!opt.lc_messages) + err = gpg_error_from_syserror (); + } + else if (!strcmp (key, "xauthority")) + { + err = session_env_setenv (opt.session_env, "XAUTHORITY", value); + } + else if (!strcmp (key, "pinentry-user-data")) + { + err = session_env_setenv (opt.session_env, "PINENTRY_USER_DATA", value); + } + else if (!strcmp (key, "enable-audit-log")) + { + /* This is not yet used. */ + /* int i = *value? atoi (value) : 0; */ + /* ctrl->server_local->enable_audit_log = i; */ + } + else if (!strcmp (key, "allow-pinentry-notify")) + { + ; /* We always allow it. */ + } + else + err = gpg_error (GPG_ERR_UNKNOWN_OPTION); + + return err; +} + + +/* The handler for an Assuan RESET command. */ +static void +reset_notify (assuan_context_t ctx) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + + xfree (ctrl->server_local->mountpoint); + ctrl->server_local->mountpoint = NULL; + + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); +} + + +/* Helper to print a message while leaving a command. */ +static gpg_error_t +leave_cmd (assuan_context_t ctx, gpg_error_t err) +{ + if (err) + { + const char *name = assuan_get_command_name (ctx); + if (!name) + name = "?"; + if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + log_error ("command '%s' failed: %s\n", name, + gpg_strerror (err)); + else + log_error ("command '%s' failed: %s <%s>\n", name, + gpg_strerror (err), gpg_strsource (err)); + } + return err; +} + + + +/* RECIPIENT + + FIXME - description. + All RECIPIENT commands are cumulative until a RESET or an + successful CREATE command. + */ +static gpg_error_t +cmd_recipient (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ + /* &ctrl->server_local->recplist, 0); */ + /* if (err) */ + /* { */ + /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ + /* get_inv_recpsgnr_code (rc), line, NULL); */ + /* } */ + + return leave_cmd (ctx, err); +} + + +/* SIGNER + + FIXME - description. + */ +static gpg_error_t +cmd_signer (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + return leave_cmd (ctx, err); +} + + +/* SETMOUNTPOINT [options] [] + + Set DIRNAME as the new mount point for future operations. + */ +static gpg_error_t +cmd_setmountpoint (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + char *p, *pend; + size_t len; + + line = skip_options (line); + for (p=line; *p && !spacep (p); p++) + ; + pend = p; + while (spacep(p)) + p++; + if (*p) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + *pend = 0; + + /* Unescape the line and check for embedded Nul bytes. */ + len = percent_plus_unescape_inplace (line, 0); + line[len] = 0; + if (memchr (line, 0, len)) + { + err = gpg_error (GPG_ERR_INV_NAME); + goto leave; + } + + xfree (ctrl->server_local->mountpoint); + if (!len) /* Reset mountpoint. */ + ctrl->server_local->mountpoint = NULL; + else + { + ctrl->server_local->mountpoint = xtrystrdup (line); + if (!ctrl->server_local->mountpoint) + err = gpg_error_from_syserror (); + } + + if (!err) + log_debug ("mountpoint is now `%s'\n", + ctrl->server_local->mountpoint + ? ctrl->server_local->mountpoint: "[none]"); + + leave: + return leave_cmd (ctx, err); +} + + +/* MOUNT [options] + + Mount CONTAINERNAME onto the current mount point. CONTAINERNAME is + the name of a file in the g13 format and must be percent-plus + escaped to allow for arbitrary names. The mount poiunt must have + been set already. + + + A reason why we use a separate command for the mount point is to + allow for longer filenames (an assuan command line is limited to + ~1000 byte. + */ +static gpg_error_t +cmd_mount (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; + char *p, *pend; + size_t len; + + line = skip_options (line); + for (p=line; *p && !spacep (p); p++) + ; + pend = p; + while (spacep(p)) + p++; + if (*p || pend == line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + *pend = 0; + + /* Unescape the line and check for embedded Nul bytes. */ + len = percent_plus_unescape_inplace (line, 0); + line[len] = 0; + if (!len || memchr (line, 0, len)) + { + err = gpg_error (GPG_ERR_INV_NAME); + goto leave; + } + + /* Perform the mount. */ + err = g13_mount_container (ctrl, line, ctrl->server_local->mountpoint); + + leave: + return leave_cmd (ctx, err); +} + + +/* GETINFO + + Multipurpose function to return a variety of information. + Supported values for WHAT are: + + version - Return the version of the program. + pid - Return the process id of the server. + cmd_has_option CMD OPT + - Returns OK if the command CMD implements the option OPT. + + */ +static gpg_error_t +cmd_getinfo (assuan_context_t ctx, char *line) +{ + gpg_error_t err = 0; + + if (!strcmp (line, "version")) + { + const char *s = PACKAGE_VERSION; + err = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "pid")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); + err = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else if (!strncmp (line, "cmd_has_option", 14) + && (line[14] == ' ' || line[14] == '\t' || !line[14])) + { + char *cmd, *cmdopt; + line += 14; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + err = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmd = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + err = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + *line++ = 0; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + err = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmdopt = line; + if (!command_has_option (cmd, cmdopt)) + err = gpg_error (GPG_ERR_GENERAL); + } + } + } + } + else + err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + + return leave_cmd (ctx, err); +} + + + +/* Return true if the command CMD implements the option CMDOPT. */ +static int +command_has_option (const char *cmd, const char *cmdopt) +{ + (void)cmd; + (void)cmdopt; + + return 0; +} + + +/* Tell the Assuan library about our commands. */ +static int +register_commands (assuan_context_t ctx) +{ + static struct { + const char *name; + gpg_error_t (*handler)(assuan_context_t, char *line); + } table[] = { + { "RECIPIENT", cmd_recipient }, + { "SIGNER", cmd_signer }, + { "MOUNT", cmd_mount }, + { "SETMOUNTPOINT", cmd_setmountpoint }, + { "INPUT", NULL }, + { "OUTPUT", NULL }, + { "GETINFO", cmd_getinfo }, + { NULL } + }; + gpg_error_t err; + int i; + + for (i=0; table[i].name; i++) + { + err = assuan_register_command (ctx, table[i].name, table[i].handler); + if (err) + return err; + } + return 0; +} + + +/* Startup the server. DEFAULT_RECPLIST is the list of recipients as + set from the command line or config file. We only require those + marked as encrypt-to. */ +gpg_error_t +g13_server (ctrl_t ctrl) +{ + gpg_error_t err; + int filedes[2]; + assuan_context_t ctx = NULL; + static const char hello[] = ("GNU Privacy Guard's G13 server " + PACKAGE_VERSION " ready"); + + /* We use a pipe based server so that we can work from scripts. + assuan_init_pipe_server will automagically detect when we are + called with a socketpair and ignore FIELDES in this case. */ + filedes[0] = 0; + filedes[1] = 1; + err = assuan_new (&ctx); + if (err) + { + log_error ("failed to allocate an Assuan context: %s\n", + gpg_strerror (err)); + goto leave; + } + + err = assuan_init_pipe_server (ctx, filedes); + if (err) + { + log_error ("failed to initialize the server: %s\n", gpg_strerror (err)); + goto leave; + } + + err = register_commands (ctx); + if (err) + { + log_error ("failed to the register commands with Assuan: %s\n", + gpg_strerror (err)); + goto leave; + } + + assuan_set_pointer (ctx, ctrl); + + if (opt.verbose || opt.debug) + { + char *tmp = NULL; + const char *s1 = getenv ("GPG_AGENT_INFO"); + + tmp = xtryasprintf ("Home: %s\n" + "Config: %s\n" + "AgentInfo: %s\n" + "%s", + opt.homedir, + opt.config_filename, + s1?s1:"[not set]", + hello); + if (tmp) + { + assuan_set_hello_line (ctx, tmp); + xfree (tmp); + } + } + else + assuan_set_hello_line (ctx, hello); + + assuan_register_reset_notify (ctx, reset_notify); + assuan_register_option_handler (ctx, option_handler); + + ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local); + if (!ctrl->server_local) + { + err = gpg_error_from_syserror (); + goto leave; + } + ctrl->server_local->assuan_ctx = ctx; + + if (DBG_ASSUAN) + assuan_set_log_stream (ctx, log_get_stream ()); + + while ( !(err = assuan_accept (ctx)) ) + { + err = assuan_process (ctx); + if (err) + log_info ("Assuan processing failed: %s\n", gpg_strerror (err)); + } + if (err == -1) + err = 0; + else + log_info ("Assuan accept problem: %s\n", gpg_strerror (err)); + + leave: + if (ctrl->server_local) + { + xfree (ctrl->server_local); + ctrl->server_local = NULL; + } + + assuan_release (ctx); + return err; +} + + + +/* gpg_error_t */ +/* gpgsm_status2 (ctrl_t ctrl, int no, ...) */ +/* { */ +/* gpg_error_t err = 0; */ +/* va_list arg_ptr; */ +/* const char *text; */ + +/* va_start (arg_ptr, no); */ + +/* if (ctrl->no_server && ctrl->status_fd == -1) */ +/* ; /\* No status wanted. *\/ */ +/* else if (ctrl->no_server) */ +/* { */ +/* if (!statusfp) */ +/* { */ +/* if (ctrl->status_fd == 1) */ +/* statusfp = stdout; */ +/* else if (ctrl->status_fd == 2) */ +/* statusfp = stderr; */ +/* else */ +/* statusfp = fdopen (ctrl->status_fd, "w"); */ + +/* if (!statusfp) */ +/* { */ +/* log_fatal ("can't open fd %d for status output: %s\n", */ +/* ctrl->status_fd, strerror(errno)); */ +/* } */ +/* } */ + +/* fputs ("[GNUPG:] ", statusfp); */ +/* fputs (get_status_string (no), statusfp); */ + +/* while ( (text = va_arg (arg_ptr, const char*) )) */ +/* { */ +/* putc ( ' ', statusfp ); */ +/* for (; *text; text++) */ +/* { */ +/* if (*text == '\n') */ +/* fputs ( "\\n", statusfp ); */ +/* else if (*text == '\r') */ +/* fputs ( "\\r", statusfp ); */ +/* else */ +/* putc ( *(const byte *)text, statusfp ); */ +/* } */ +/* } */ +/* putc ('\n', statusfp); */ +/* fflush (statusfp); */ +/* } */ +/* else */ +/* { */ +/* assuan_context_t ctx = ctrl->server_local->assuan_ctx; */ +/* char buf[950], *p; */ +/* size_t n; */ + +/* p = buf; */ +/* n = 0; */ +/* while ( (text = va_arg (arg_ptr, const char *)) ) */ +/* { */ +/* if (n) */ +/* { */ +/* *p++ = ' '; */ +/* n++; */ +/* } */ +/* for ( ; *text && n < DIM (buf)-2; n++) */ +/* *p++ = *text++; */ +/* } */ +/* *p = 0; */ +/* err = assuan_write_status (ctx, get_status_string (no), buf); */ +/* } */ + +/* va_end (arg_ptr); */ +/* return err; */ +/* } */ + +/* gpg_error_t */ +/* gpgsm_status (ctrl_t ctrl, int no, const char *text) */ +/* { */ +/* return gpgsm_status2 (ctrl, no, text, NULL); */ +/* } */ + +/* gpg_error_t */ +/* gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, */ +/* gpg_err_code_t ec) */ +/* { */ +/* char buf[30]; */ + +/* sprintf (buf, "%u", (unsigned int)ec); */ +/* if (text) */ +/* return gpgsm_status2 (ctrl, no, text, buf, NULL); */ +/* else */ +/* return gpgsm_status2 (ctrl, no, buf, NULL); */ +/* } */ + + +/* Helper to notify the client about Pinentry events. Returns an gpg + error code. */ +gpg_error_t +g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line) +{ + if (!ctrl || !ctrl->server_local) + return 0; + return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0); +} + + + + Added: trunk/g13/server.h =================================================================== --- trunk/g13/server.h (rev 0) +++ trunk/g13/server.h 2009-10-14 17:06:10 UTC (rev 5176) @@ -0,0 +1,29 @@ +/* server.h - The G13 Assuan server + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#ifndef G13_SERVER_H +#define G13_SERVER_H + + +gpg_error_t g13_server (ctrl_t ctrl); + +gpg_error_t g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line); + +#endif /*G13_SERVER_H*/ + From cvs at cvs.gnupg.org Thu Oct 15 19:20:42 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 15 Oct 2009 19:20:42 +0200 Subject: [svn] GnuPG - r5177 - trunk/g13 Message-ID: Author: wk Date: 2009-10-15 19:20:41 +0200 (Thu, 15 Oct 2009) New Revision: 5177 Added: trunk/g13/mountinfo.c trunk/g13/mountinfo.h Modified: trunk/g13/Makefile.am trunk/g13/backend.c trunk/g13/backend.h trunk/g13/be-encfs.c trunk/g13/be-encfs.h trunk/g13/create.c trunk/g13/g13.c trunk/g13/mount.c trunk/g13/mount.h trunk/g13/runner.c trunk/g13/runner.h trunk/g13/server.c Log: Reworked the server commands. Track mounts. --create does now work as expected. Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/Makefile.am 2009-10-15 17:20:41 UTC (rev 5177) @@ -33,6 +33,7 @@ server.c server.h \ create.c create.h \ mount.c mount.h \ + mountinfo.c mountinfo.h \ call-gpg.c call-gpg.h \ runner.c runner.h \ backend.c backend.h \ Modified: trunk/g13/backend.c =================================================================== --- trunk/g13/backend.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/backend.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -101,14 +101,15 @@ /* Dispatcher to the backend's create function. */ gpg_error_t be_create_container (ctrl_t ctrl, int conttype, - const char *fname, int fd, tupledesc_t tuples) + const char *fname, int fd, tupledesc_t tuples, + unsigned int *r_id) { (void)fd; /* Not yet used. */ switch (conttype) { case CONTTYPE_ENCFS: - return be_encfs_create_container (ctrl, fname, tuples); + return be_encfs_create_container (ctrl, fname, tuples, r_id); default: return no_such_backend (conttype); @@ -120,12 +121,12 @@ gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, const char *fname, const char *mountpoint, - tupledesc_t tuples) + tupledesc_t tuples, unsigned int *r_id) { switch (conttype) { case CONTTYPE_ENCFS: - return be_encfs_mount_container (ctrl, fname, mountpoint, tuples); + return be_encfs_mount_container (ctrl, fname, mountpoint, tuples, r_id); default: return no_such_backend (conttype); Modified: trunk/g13/backend.h =================================================================== --- trunk/g13/backend.h 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/backend.h 2009-10-15 17:20:41 UTC (rev 5177) @@ -30,10 +30,12 @@ gpg_error_t be_create_container (ctrl_t ctrl, int conttype, const char *fname, int fd, - tupledesc_t tuples); + tupledesc_t tuples, + unsigned int *r_id); gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, const char *fname, const char *mountpoint, - tupledesc_t tuples); + tupledesc_t tuples, + unsigned int *r_id); #endif /*G13_BACKEND_H*/ Modified: trunk/g13/be-encfs.c =================================================================== --- trunk/g13/be-encfs.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/be-encfs.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -211,7 +211,8 @@ /* Run the encfs tool. */ static gpg_error_t run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, - const char *rawdir, const char *mountpoint, tupledesc_t tuples) + const char *rawdir, const char *mountpoint, tupledesc_t tuples, + unsigned int *r_id) { gpg_error_t err; encfs_parm_t parm; @@ -240,16 +241,10 @@ goto leave; } - { - static int namecounter; - char buffer[50]; + err = runner_new (&runner, "encfs"); + if (err) + goto leave; - snprintf (buffer, sizeof buffer, "encfs-%d", ++namecounter); - err = runner_new (&runner, buffer); - if (err) - goto leave; - } - err = gnupg_create_inbound_pipe (inbound); if (!err) err = gnupg_create_outbound_pipe (outbound); @@ -295,6 +290,7 @@ if (err) goto leave; + *r_id = runner_get_rid (runner); log_info ("running `%s' in the background\n", pgmname); leave: @@ -400,7 +396,8 @@ /* Create the container described by the filename FNAME and the keyblob information in TUPLES. */ gpg_error_t -be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples) +be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples, + unsigned int *r_id) { gpg_error_t err; int dummy; @@ -426,7 +423,7 @@ } err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint, - tuples); + tuples, r_id); /* In any case remove the temporary mount point. */ if (rmdir (mountpoint)) @@ -442,11 +439,11 @@ /* Mount the container described by the filename FNAME and the keyblob - information in TUPLES. */ + information in TUPLES. On success the runner id is stored at R_ID. */ gpg_error_t be_encfs_mount_container (ctrl_t ctrl, const char *fname, const char *mountpoint, - tupledesc_t tuples) + tupledesc_t tuples, unsigned int *r_id) { gpg_error_t err; int dummy; @@ -464,7 +461,7 @@ goto leave; err = run_encfs_tool (ctrl, ENCFS_CMD_MOUNT, containername, mountpoint, - tuples); + tuples, r_id); leave: xfree (containername); Modified: trunk/g13/be-encfs.h =================================================================== --- trunk/g13/be-encfs.h 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/be-encfs.h 2009-10-15 17:20:41 UTC (rev 5177) @@ -28,12 +28,14 @@ gpg_error_t be_encfs_create_container (ctrl_t ctrl, const char *fname, - tupledesc_t tuples); + tupledesc_t tuples, + unsigned int *r_id); gpg_error_t be_encfs_mount_container (ctrl_t ctrl, const char *fname, const char *mountpoint, - tupledesc_t tuples); + tupledesc_t tuples, + unsigned int *r_id); #endif /*G13_BE_ENCFS_H*/ Modified: trunk/g13/create.c =================================================================== --- trunk/g13/create.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/create.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -231,6 +231,7 @@ char *detachedname = NULL; int detachedisdir; tupledesc_t tuples = NULL; + unsigned int dummy_rid; /* A quick check to see that no container with that name already exists. */ @@ -304,7 +305,8 @@ /* Create and append the container. FIXME: We should pass the estream object in addition to the filename, so that the backend can append the container to the g13 file. */ - err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples); + err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples, + &dummy_rid); leave: Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/g13.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -39,7 +39,8 @@ #include "server.h" #include "runner.h" #include "create.h" -#include "./mount.h" +#include "mount.h" +#include "mountinfo.h" enum cmd_and_opt_values { @@ -707,6 +708,8 @@ if (err) log_error ("server exited with error: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); + else + shutdown_pending++; } break; @@ -719,6 +722,8 @@ if (err) log_error ("error creating a new container: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); + else + shutdown_pending++; } break; @@ -807,6 +812,7 @@ case SIGUSR1: log_info ("SIGUSR1 received - printing internal information:\n"); pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); + mountinfo_dump_all (); break; case SIGUSR2: Modified: trunk/g13/mount.c =================================================================== --- trunk/g13/mount.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/mount.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -35,6 +35,8 @@ #include "utils.h" #include "call-gpg.h" #include "estream.h" +#include "mountinfo.h" +#include "runner.h" /* Parse the header prefix and return the length of the entire header. */ @@ -89,28 +91,23 @@ } - -/* Read the keyblob at FILENAME. The caller should have acquired a - lockfile and checked that the file exists. */ +/* Read the prefix of the keyblob and do some basic parsing. On + success returns an open estream file at R_FP and the length of the + header at R_HEADERLEN. */ static gpg_error_t -read_keyblob (const char *filename, - void **r_enckeyblob, size_t *r_enckeybloblen) +read_keyblob_prefix (const char *filename, estream_t *r_fp, size_t *r_headerlen) { gpg_error_t err; estream_t fp; unsigned char packet[32]; - size_t headerlen, msglen; - void *msg = NULL; - *r_enckeyblob = NULL; - *r_enckeybloblen = 0; + *r_fp = NULL; fp = es_fopen (filename, "rb"); if (!fp) { err = gpg_error_from_syserror (); - log_error ("error reading `%s': %s\n", - filename, gpg_strerror (err)); + log_error ("error reading `%s': %s\n", filename, gpg_strerror (err)); return err; } @@ -120,11 +117,36 @@ err = gpg_error_from_syserror (); log_error ("error reading the header of `%s': %s\n", filename, gpg_strerror (err)); - goto leave; + es_fclose (fp); + return err; } - err = parse_header (filename, packet, 32, &headerlen); + err = parse_header (filename, packet, 32, r_headerlen); if (err) + es_fclose (fp); + else + *r_fp = fp; + + return err; +} + + +/* Read the keyblob at FILENAME. The caller should have acquired a + lockfile and checked that the file exists. */ +static gpg_error_t +read_keyblob (const char *filename, + void **r_enckeyblob, size_t *r_enckeybloblen) +{ + gpg_error_t err; + estream_t fp = NULL; + size_t headerlen, msglen; + void *msg = NULL; + + *r_enckeyblob = NULL; + *r_enckeybloblen = 0; + + err = read_keyblob_prefix (filename, &fp, &headerlen); + if (err) goto leave; if (opt.verbose) @@ -227,6 +249,7 @@ size_t n; const unsigned char *value; int conttype; + unsigned int rid; /* A quick check to see whether the container exists. */ if (access (filename, R_OK)) @@ -292,7 +315,13 @@ err = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; } - err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples); + err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid); + if (!err) + { + err = mountinfo_add_mount (filename, mountpoint, conttype, rid); + /* Fixme: What shall we do if this fails? Add a provisional + mountinfo entry first and remove it on error? */ + } leave: destroy_tupledesc (tuples); @@ -301,3 +330,56 @@ destroy_dotlock (lock); return err; } + + +/* Unmount the container with name FILENAME or the one mounted at + MOUNTPOINT. If both are given the FILENAME takes precedence. */ +gpg_error_t +g13_umount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) +{ + gpg_error_t err; + unsigned int rid; + runner_t runner; + + (void)ctrl; + + if (!filename && !mountpoint) + return gpg_error (GPG_ERR_ENOENT); + err = mountinfo_find_mount (filename, mountpoint, &rid); + if (err) + return err; + + runner = runner_find_by_rid (rid); + if (!runner) + { + log_error ("runner %u not found\n", rid); + return gpg_error (GPG_ERR_NOT_FOUND); + } + + runner_cancel (runner); + runner_release (runner); + + return 0; +} + + +/* Test whether the container with name FILENAME is a suitable G13 + container. This function may even be called on a mounted + container. */ +gpg_error_t +g13_is_container (ctrl_t ctrl, const char *filename) +{ + gpg_error_t err; + estream_t fp = NULL; + size_t dummy; + + (void)ctrl; + + /* Read just the prefix of the header. */ + err = read_keyblob_prefix (filename, &fp, &dummy); + if (!err) + es_fclose (fp); + return err; +} + + Modified: trunk/g13/mount.h =================================================================== --- trunk/g13/mount.h 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/mount.h 2009-10-15 17:20:41 UTC (rev 5177) @@ -1,4 +1,4 @@ -/* mmount.h - Defs to mount a crypto container +/* mount.h - Defs to mount a crypto container * Copyright (C) 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. @@ -23,7 +23,12 @@ gpg_error_t g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint); +gpg_error_t g13_umount_container (ctrl_t ctrl, + const char *filename, + const char *mountpoint); +gpg_error_t g13_is_container (ctrl_t ctrl, const char *filename); + #endif /*G13_MOUNT_H*/ Added: trunk/g13/mountinfo.c =================================================================== --- trunk/g13/mountinfo.c (rev 0) +++ trunk/g13/mountinfo.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -0,0 +1,183 @@ +/* mountinfo.c - Track infos about mounts + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "i18n.h" +#include "mountinfo.h" + +#include "keyblob.h" +#include "utils.h" + + + +/* The object to keep track of mount information. */ +struct mounttable_s +{ + int in_use; /* The slot is in use. */ + char *container; /* Name of the container. */ + char *mountpoint; /* Name of the mounttype. */ + int conttype; /* Type of the container. */ + unsigned int rid; /* Identifier of the runner task. */ +}; + + +/* The allocated table of mounts and its size. */ +static mtab_t mounttable; +size_t mounttable_size; + + + +/* Add CONTAINER,MOUNTPOINT,CONTTYPE,RID to the mounttable. */ +gpg_error_t +mountinfo_add_mount (const char *container, const char *mountpoint, + int conttype, unsigned int rid) +{ + size_t idx; + mtab_t m; + + for (idx=0; idx < mounttable_size; idx++) + if (!mounttable[idx].in_use) + break; + if (!(idx < mounttable_size)) + { + size_t nslots = mounttable_size; + + mounttable_size += 10; + m = xtrycalloc (mounttable_size, sizeof *mounttable); + if (!m) + return gpg_error_from_syserror (); + if (mounttable) + { + for (idx=0; idx < nslots; idx++) + m[idx] = mounttable[idx]; + xfree (mounttable); + } + mounttable = m; + m = mounttable + nslots; + assert (!m->in_use); + } + else + m = mounttable + idx; + + m->container = xtrystrdup (container); + if (!m->container) + return gpg_error_from_syserror (); + m->mountpoint = xtrystrdup (mountpoint); + if (!m->mountpoint) + { + xfree (m->container); + m->container = NULL; + return gpg_error_from_syserror (); + } + m->conttype = conttype; + m->rid = rid; + m->in_use = 1; + + return 0; +} + + +/* Remove a mount info. Either the CONTAINER, the MOUNTPOINT or the + RID must be given. The first argument given is used. */ +gpg_error_t +mountinfo_del_mount (const char *container, const char *mountpoint, + unsigned int rid) +{ + gpg_error_t err; + size_t idx; + mtab_t m; + + /* If a container or mountpint is givem search the RID via the + standard find fucntion. */ + if (container || mountpoint) + { + err = mountinfo_find_mount (container, mountpoint, &rid); + if (err) + return err; + } + + /* Find via RID and delete. */ + for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) + if (m->in_use && m->rid == rid) + { + m->in_use = 0; + xfree (m->container); + m->container = NULL; + xfree (m->mountpoint); + m->mountpoint = NULL; + return 0; + } + return gpg_error (GPG_ERR_NOT_FOUND); +} + + +/* Find a mount and return its rid at R_RID. If CONTAINER is given, + the search is done by the container name, if it is not given the + search is done by MOUNTPOINT. */ +gpg_error_t +mountinfo_find_mount (const char *container, const char *mountpoint, + unsigned int *r_rid) +{ + size_t idx; + mtab_t m; + + if (container) + { + for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) + if (m->in_use && !strcmp (m->container, container)) + break; + } + else if (mountpoint) + { + for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) + if (m->in_use && !strcmp (m->mountpoint, mountpoint)) + break; + } + else + idx = mounttable_size; + if (!(idx < mounttable_size)) + return gpg_error (GPG_ERR_NOT_FOUND); + + *r_rid = m->rid; + return 0; +} + + +/* Dump all info to the log stream. */ +void +mountinfo_dump_all (void) +{ + size_t idx; + mtab_t m; + + for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) + if (m->in_use) + log_info ("mtab[%d] %s on %s type %d rid %u\n", + idx, m->container, m->mountpoint, m->conttype, m->rid); +} + Added: trunk/g13/mountinfo.h =================================================================== --- trunk/g13/mountinfo.h (rev 0) +++ trunk/g13/mountinfo.h 2009-10-15 17:20:41 UTC (rev 5177) @@ -0,0 +1,40 @@ +/* mountinfo.h - Track infos about mounts + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#ifndef G13_MOUNTINFO_H +#define G13_MOUNTINFO_H + +struct mounttable_s; +typedef struct mounttable_s *mtab_t; + +gpg_error_t mountinfo_add_mount (const char *container, + const char *mountpoint, + int conttype, unsigned int rid); +gpg_error_t mountinfo_del_mount (const char *container, + const char *mountpoint, + unsigned int rid); +gpg_error_t mountinfo_find_mount (const char *container, + const char *mountpoint, + unsigned int *r_rid); + +void mountinfo_dump_all (void); + + +#endif /*G13_MOUNTINFO_H*/ + Modified: trunk/g13/runner.c =================================================================== --- trunk/g13/runner.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/runner.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -31,12 +31,13 @@ #include "keyblob.h" #include "runner.h" #include "../common/exechelp.h" +#include "mountinfo.h" - /* The runner object. */ struct runner_s { - char *name; /* The name of this runner. */ + char *name; /* The name of this runner. */ + unsigned int identifier; /* The runner identifier. */ int spawned; /* True if runner_spawn has been called. */ pth_t threadid; /* The TID of the runner thread. */ @@ -131,12 +132,19 @@ void runner_release (runner_t runner) { + gpg_error_t err; + if (!runner) return; if (!--runner->refcount) return; + err = mountinfo_del_mount (NULL, NULL, runner->identifier); + if (err) + log_error ("failed to remove mount with rid %u from mtab: %s\n", + runner->identifier, gpg_strerror (err)); + es_fclose (runner->status_fp); if (runner->in_fd != -1) close (runner->in_fd); @@ -171,14 +179,32 @@ gpg_error_t runner_new (runner_t *r_runner, const char *name) { - runner_t runner; + static unsigned int namecounter; /* Global name counter. */ + char *namebuffer; + runner_t runner, r; *r_runner = NULL; runner = xtrycalloc (1, sizeof *runner); if (!runner) return gpg_error_from_syserror (); - runner->name = xtrystrdup (name? name: "[unknown]"); + + /* Bump up the namecounter. In case we ever had an overflow we + check that this number is currently not in use. The algorithm is + a bit lame but should be sufficient because such an wrap is not + very likely: Assuming that we do a mount 10 times a second, then + we would overwrap on a 32 bit system after 13 years. */ + do + { + namecounter++; + for (r = running_threads; r; r = r->next_running) + if (r->identifier == namecounter) + break; + } + while (r); + + runner->identifier = namecounter; + runner->name = namebuffer = xtryasprintf ("%s-%d", name, namecounter); if (!runner->name) { xfree (runner); @@ -189,13 +215,37 @@ runner->in_fd = -1; runner->out_fd = -1; - *r_runner = runner; return 0; } -/* A runner usually maintaines two file descriptors to control the +/* Return the identifier of RUNNER. */ +unsigned int +runner_get_rid (runner_t runner) +{ + return runner->identifier; +} + + +/* Find a runner by its rid. Returns the runner object. The caller + must release the runner object. */ +runner_t +runner_find_by_rid (unsigned int rid) +{ + runner_t r; + + for (r = running_threads; r; r = r->next_running) + if (r->identifier == rid) + { + r->refcount++; + return r; + } + return NULL; +} + + +/* A runner usually maintains two file descriptors to control the backend engine. This function is used to set these file descriptors. The function takes ownership of these file descriptors. IN_FD will be used to read from engine and OUT_FD to @@ -382,8 +432,8 @@ } tattr = pth_attr_new (); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 128*1024); pth_attr_set (tattr, PTH_ATTR_NAME, runner->name); tid = pth_spawn (tattr, runner_thread, runner); Modified: trunk/g13/runner.h =================================================================== --- trunk/g13/runner.h 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/runner.h 2009-10-15 17:20:41 UTC (rev 5177) @@ -40,6 +40,12 @@ /* Free a runner object. */ void runner_release (runner_t runner); +/* Return the identifier of RUNNER. */ +unsigned int runner_get_rid (runner_t runner); + +/* Find a runner by its rid. */ +runner_t runner_find_by_rid (unsigned int rid); + /* Functions to set properties of the runner. */ void runner_set_fds (runner_t runner, int in_fd, int out_fd); Modified: trunk/g13/server.c =================================================================== --- trunk/g13/server.c 2009-10-14 17:06:10 UTC (rev 5176) +++ trunk/g13/server.c 2009-10-15 17:20:41 UTC (rev 5177) @@ -40,42 +40,28 @@ /* The Assuan contect we are working on. */ assuan_context_t assuan_ctx; - char *mountpoint; /* Malloced current mountpoint. */ + char *containername; /* Malloced active containername. */ }; -/* Cookie definition for assuan data line output. */ -static ssize_t data_line_cookie_write (void *cookie, - const void *buffer, size_t size); -static int data_line_cookie_close (void *cookie); -static es_cookie_io_functions_t data_line_cookie_functions = - { - NULL, - data_line_cookie_write, - NULL, - data_line_cookie_close - }; - -/* The filepointer for status message used in non-server mode. */ -/* static FILE *statusfp; FIXME; */ - - - +/* Local prototypes. */ static int command_has_option (const char *cmd, const char *cmdopt); +/* + Helper functions. + */ + +/* Set an error and a description. */ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) - - -/* Skip over options. - Blanks after the options are also removed. */ +/* Skip over options. Blanks after the options are also removed. */ static char * skip_options (const char *line) { @@ -93,52 +79,41 @@ /* Check whether the option NAME appears in LINE. */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); +/* static int */ +/* has_option (const char *line, const char *name) */ +/* { */ +/* const char *s; */ +/* 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))); -} +/* s = strstr (line, name); */ +/* if (s && s >= skip_options (line)) */ +/* return 0; */ +/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */ +/* } */ -/* A write handler used by es_fopencookie to write Assuan data - lines. */ -static ssize_t -data_line_cookie_write (void *cookie, const void *buffer, size_t size) +/* Helper to print a message while leaving a command. */ +static gpg_error_t +leave_cmd (assuan_context_t ctx, gpg_error_t err) { - assuan_context_t ctx = cookie; - - if (assuan_send_data (ctx, buffer, size)) + if (err) { - errno = EIO; - return -1; + const char *name = assuan_get_command_name (ctx); + if (!name) + name = "?"; + if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + log_error ("command '%s' failed: %s\n", name, + gpg_strerror (err)); + else + log_error ("command '%s' failed: %s <%s>\n", name, + gpg_strerror (err), gpg_strsource (err)); } - - return size; + return err; } -/* A close handler used by es_fopencookie to write Assuan data - lines. */ -static int -data_line_cookie_close (void *cookie) -{ - assuan_context_t ctx = cookie; - if (assuan_send_data (ctx, NULL, 0)) - { - errno = EIO; - return -1; - } - return 0; -} - - + /* The handler for Assuan OPTION commands. */ static gpg_error_t option_handler (assuan_context_t ctx, const char *key, const char *value) @@ -146,6 +121,8 @@ ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; + (void)ctrl; + if (!strcmp (key, "putenv")) { /* Change the session's environment to be used for the @@ -213,84 +190,83 @@ { ctrl_t ctrl = assuan_get_pointer (ctx); - xfree (ctrl->server_local->mountpoint); - ctrl->server_local->mountpoint = NULL; + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); } -/* Helper to print a message while leaving a command. */ -static gpg_error_t -leave_cmd (assuan_context_t ctx, gpg_error_t err) -{ - if (err) - { - const char *name = assuan_get_command_name (ctx); - if (!name) - name = "?"; - if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) - log_error ("command '%s' failed: %s\n", name, - gpg_strerror (err)); - else - log_error ("command '%s' failed: %s <%s>\n", name, - gpg_strerror (err), gpg_strsource (err)); - } - return err; -} +/* OPEN [options] - -/* RECIPIENT - - FIXME - description. - All RECIPIENT commands are cumulative until a RESET or an - successful CREATE command. + Open the container FILENAME. FILENAME must be percent-plus + escaped. A quick check to see whether this is a suitable G13 + container file is done. However no cryptographic check or any + other check is done. This command is used to define the target for + further commands. The filename is reset with the RESET command, + another OPEN or the CREATE command. */ static gpg_error_t -cmd_recipient (assuan_context_t ctx, char *line) +cmd_open (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; + gpg_error_t err = 0; + char *p, *pend; + size_t len; - (void)ctrl; - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ - /* &ctrl->server_local->recplist, 0); */ - /* if (err) */ - /* { */ - /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ - /* get_inv_recpsgnr_code (rc), line, NULL); */ - /* } */ + /* In any case reset the active container. */ + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; - return leave_cmd (ctx, err); -} + /* Parse the line. */ + line = skip_options (line); + for (p=line; *p && !spacep (p); p++) + ; + pend = p; + while (spacep(p)) + p++; + if (*p || pend == line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + *pend = 0; + /* Unescape the line and check for embedded Nul bytes. */ + len = percent_plus_unescape_inplace (line, 0); + line[len] = 0; + if (!len || memchr (line, 0, len)) + { + err = gpg_error (GPG_ERR_INV_NAME); + goto leave; + } -/* SIGNER + /* Do a basic check. */ + err = g13_is_container (ctrl, line); + if (err) + goto leave; - FIXME - description. - */ -static gpg_error_t -cmd_signer (assuan_context_t ctx, char *line) -{ - ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; - - (void)ctrl; - - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* Store the filename. */ + ctrl->server_local->containername = xtrystrdup (line); + if (!ctrl->server_local->containername) + err = gpg_error_from_syserror (); + + + leave: return leave_cmd (ctx, err); } -/* SETMOUNTPOINT [options] [] +/* MOUNT [options] [] - Set DIRNAME as the new mount point for future operations. + Mount the currently open file onto MOUNTPOINT. If MOUNTPOINT is + not given the system picks an unused mountpoint. MOUNTPOINT must + be percent-plus escaped to allow for arbitrary names. */ static gpg_error_t -cmd_setmountpoint (assuan_context_t ctx, char *line) +cmd_mount (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; @@ -319,40 +295,28 @@ goto leave; } - xfree (ctrl->server_local->mountpoint); - if (!len) /* Reset mountpoint. */ - ctrl->server_local->mountpoint = NULL; - else + if (!ctrl->server_local->containername) { - ctrl->server_local->mountpoint = xtrystrdup (line); - if (!ctrl->server_local->mountpoint) - err = gpg_error_from_syserror (); + err = gpg_error (GPG_ERR_MISSING_ACTION); + goto leave; } - if (!err) - log_debug ("mountpoint is now `%s'\n", - ctrl->server_local->mountpoint - ? ctrl->server_local->mountpoint: "[none]"); + /* Perform the mount. */ + err = g13_mount_container (ctrl, ctrl->server_local->containername, + *line? line : NULL); leave: return leave_cmd (ctx, err); } -/* MOUNT [options] +/* UMOUNT [options] [] - Mount CONTAINERNAME onto the current mount point. CONTAINERNAME is - the name of a file in the g13 format and must be percent-plus - escaped to allow for arbitrary names. The mount poiunt must have - been set already. - - - A reason why we use a separate command for the mount point is to - allow for longer filenames (an assuan command line is limited to - ~1000 byte. + Unmount the currently open file or the one opened at MOUNTPOINT. + MOUNTPOINT must be percent-plus escaped. */ static gpg_error_t -cmd_mount (assuan_context_t ctx, char *line) +cmd_umount (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; @@ -365,7 +329,7 @@ pend = p; while (spacep(p)) p++; - if (*p || pend == line) + if (*p) { err = gpg_error (GPG_ERR_ASS_SYNTAX); goto leave; @@ -375,20 +339,89 @@ /* Unescape the line and check for embedded Nul bytes. */ len = percent_plus_unescape_inplace (line, 0); line[len] = 0; - if (!len || memchr (line, 0, len)) + if (memchr (line, 0, len)) { err = gpg_error (GPG_ERR_INV_NAME); goto leave; } - - /* Perform the mount. */ - err = g13_mount_container (ctrl, line, ctrl->server_local->mountpoint); + /* Perform the unmount. */ + err = g13_umount_container (ctrl, ctrl->server_local->containername, + *line? line : NULL); + leave: return leave_cmd (ctx, err); } + +/* RECIPIENT + + FIXME - description. + All RECIPIENT commands are cumulative until a RESET or an + successful CREATE command. + */ +static gpg_error_t +cmd_recipient (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ + /* &ctrl->server_local->recplist, 0); */ + /* if (err) */ + /* { */ + /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ + /* get_inv_recpsgnr_code (rc), line, NULL); */ + /* } */ + + return leave_cmd (ctx, err); +} + + +/* SIGNER + + FIXME - description. + */ +static gpg_error_t +cmd_signer (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + return leave_cmd (ctx, err); +} + + +/* CREATE [options] filename + + Create a new container. On success the OPEN command is done + implictly for the new container. + */ +static gpg_error_t +cmd_create (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + + /* First we close the active container. */ + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; + + + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + return leave_cmd (ctx, err); +} + + /* GETINFO Multipurpose function to return a variety of information. @@ -476,10 +509,12 @@ const char *name; gpg_error_t (*handler)(assuan_context_t, char *line); } table[] = { + { "OPEN", cmd_open }, + { "MOUNT", cmd_mount }, + { "UMOUNT", cmd_umount }, { "RECIPIENT", cmd_recipient }, { "SIGNER", cmd_signer }, - { "MOUNT", cmd_mount }, - { "SETMOUNTPOINT", cmd_setmountpoint }, + { "CREATE", cmd_create }, { "INPUT", NULL }, { "OUTPUT", NULL }, { "GETINFO", cmd_getinfo }, From cvs at cvs.gnupg.org Thu Oct 15 22:54:26 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 15 Oct 2009 22:54:26 +0200 Subject: [svn] gpgme - r1397 - trunk/tests Message-ID: Author: wk Date: 2009-10-15 22:54:25 +0200 (Thu, 15 Oct 2009) New Revision: 1397 Added: trunk/tests/run-verify.c Modified: trunk/tests/ChangeLog trunk/tests/Makefile.am Log: Add new debug helper Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-10-07 11:17:57 UTC (rev 1396) +++ trunk/tests/ChangeLog 2009-10-15 20:54:25 UTC (rev 1397) @@ -1,3 +1,7 @@ +2009-10-15 Werner Koch + + * run-verify.c: New. + 2009-08-06 Werner Koch * run-sign.c: New. @@ -4,8 +8,8 @@ 2009-07-07 Werner Koch - * run-keylist.c (main): Add options --cms and --openpgp. - + * run-keylist.c (main): Add options --cms and --openpgp. + * gpg/pgp-keylist.c: Rename to ... * run-keylist.c: ... this. * gpg/pgp-import.c: Rename to ... Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2009-10-07 11:17:57 UTC (rev 1396) +++ trunk/tests/Makefile.am 2009-10-15 20:54:25 UTC (rev 1397) @@ -32,7 +32,8 @@ noinst_HEADERS = run-support.h -noinst_PROGRAMS = $(TESTS) run-keylist run-export run-import run-sign +noinst_PROGRAMS = $(TESTS) run-keylist run-export run-import run-sign \ + run-verify if RUN_GPG_TESTS Added: trunk/tests/run-verify.c =================================================================== --- trunk/tests/run-verify.c (rev 0) +++ trunk/tests/run-verify.c 2009-10-15 20:54:25 UTC (rev 1397) @@ -0,0 +1,244 @@ +/* run-verify.c - Helper to perform a verify operation + Copyright (C) 2009 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 Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see . +*/ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#define PGM "run-verify" + +#include "run-support.h" + + +static int verbose; + +static void +print_summary (gpgme_sigsum_t summary) +{ + if ( (summary & GPGME_SIGSUM_VALID )) + fputs (" valid", stdout); + if ( (summary & GPGME_SIGSUM_GREEN )) + fputs (" green", stdout); + if ( (summary & GPGME_SIGSUM_RED )) + fputs (" red", stdout); + if ( (summary & GPGME_SIGSUM_KEY_REVOKED)) + fputs (" revoked", stdout); + if ( (summary & GPGME_SIGSUM_KEY_EXPIRED)) + fputs (" key-expired", stdout); + if ( (summary & GPGME_SIGSUM_SIG_EXPIRED)) + fputs (" sig-expired", stdout); + if ( (summary & GPGME_SIGSUM_KEY_MISSING)) + fputs (" key-missing", stdout); + if ( (summary & GPGME_SIGSUM_CRL_MISSING)) + fputs (" crl-missing", stdout); + if ( (summary & GPGME_SIGSUM_CRL_TOO_OLD)) + fputs (" crl-too-old", stdout); + if ( (summary & GPGME_SIGSUM_BAD_POLICY )) + fputs (" bad-policy", stdout); + if ( (summary & GPGME_SIGSUM_SYS_ERROR )) + fputs (" sys-error", stdout); +} + +static void +print_validity (gpgme_validity_t val) +{ + const char *s = NULL; + + switch (val) + { + case GPGME_VALIDITY_UNKNOWN: s = "unknown"; break; + case GPGME_VALIDITY_UNDEFINED:s = "undefined"; break; + case GPGME_VALIDITY_NEVER: s = "never"; break; + case GPGME_VALIDITY_MARGINAL: s = "marginal"; break; + case GPGME_VALIDITY_FULL: s = "full"; break; + case GPGME_VALIDITY_ULTIMATE: s = "ultimate"; break; + } + if (s) + fputs (s, stdout); + else + printf ("[bad validity value %u]", (unsigned int)val); +} + + +static void +print_result (gpgme_verify_result_t result) +{ + gpgme_signature_t sig; + int count = 0; + + printf ("Original file name: %s\n", nonnull(result->file_name)); + for (sig = result->signatures; sig; sig = sig->next) + { + printf ("Signature %d\n", count++); + printf (" status ....: %s\n", gpg_strerror (sig->status)); + printf (" summary ...:"); print_summary (sig->summary); putchar ('\n'); + printf (" fingerprint: %s\n", nonnull (sig->fpr)); + printf (" created ...: %lu\n", sig->timestamp); + printf (" expires ...: %lu\n", sig->exp_timestamp); + printf (" validity ..: "); + print_validity (sig->validity); putchar ('\n'); + printf (" val.reason : %s\n", gpg_strerror (sig->status)); + printf (" pubkey algo: %d\n", sig->pubkey_algo); + printf (" digest algo: %d\n", sig->hash_algo); + printf (" pka address: %s\n", nonnull (sig->pka_address)); + printf (" pka trust .: %s\n", + sig->pka_trust == 0? "n/a" : + sig->pka_trust == 1? "bad" : + sig->pka_trust == 2? "okay": "RFU"); + printf (" other flags:%s%s\n", + sig->wrong_key_usage? " wrong-key-usage":"", + sig->chain_model? " chain-model":"" + ); + printf (" notations .: %s\n", + sig->notations? "yes":"no"); + } +} + + + +static int +show_usage (int ex) +{ + fputs ("usage: " PGM " [options] [DETACHEDSIGFILE] FILE\n\n" + "Options:\n" + " --verbose run in verbose mode\n" + " --openpgp use the OpenPGP protocol (default)\n" + " --cms use the CMS protocol\n" + , stderr); + exit (ex); +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; + FILE *fp_sig = NULL; + gpgme_data_t sig = NULL; + FILE *fp_msg = NULL; + gpgme_data_t msg = NULL; + gpgme_verify_result_t result; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + show_usage (0); + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--openpgp")) + { + protocol = GPGME_PROTOCOL_OpenPGP; + argc--; argv++; + } + else if (!strcmp (*argv, "--cms")) + { + protocol = GPGME_PROTOCOL_CMS; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + show_usage (1); + + } + + if (argc < 1 || argc > 2) + show_usage (1); + + fp_sig = fopen (argv[0], "rb"); + if (!fp_sig) + { + err = gpg_error_from_syserror (); + fprintf (stderr, PGM ": can't open `%s': %s\n", + argv[0], gpg_strerror (err)); + exit (1); + } + if (argc > 1) + { + fp_msg = fopen (argv[1], "rb"); + if (!fp_msg) + { + err = gpg_error_from_syserror (); + fprintf (stderr, PGM ": can't open `%s': %s\n", + argv[1], gpg_strerror (err)); + exit (1); + } + } + + init_gpgme (protocol); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, protocol); + + err = gpgme_data_new_from_stream (&sig, fp_sig); + if (err) + { + fprintf (stderr, PGM ": error allocating data object: %s\n", + gpg_strerror (err)); + exit (1); + } + if (fp_msg) + { + err = gpgme_data_new_from_stream (&msg, fp_msg); + if (err) + { + fprintf (stderr, PGM ": error allocating data object: %s\n", + gpg_strerror (err)); + exit (1); + } + } + + err = gpgme_op_verify (ctx, sig, msg, NULL); + result = gpgme_op_verify_result (ctx); + if (result) + print_result (result); + if (err) + { + fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err)); + exit (1); + } + + gpgme_data_release (msg); + gpgme_data_release (sig); + + gpgme_release (ctx); + return 0; +} From cvs at cvs.gnupg.org Fri Oct 16 12:56:59 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 16 Oct 2009 12:56:59 +0200 Subject: [svn] GnuPG - r5178 - in branches/STABLE-BRANCH-2-0: . doc sm Message-ID: Author: wk Date: 2009-10-16 12:56:59 +0200 (Fri, 16 Oct 2009) New Revision: 5178 Modified: branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/doc/gpgsm.texi branches/STABLE-BRANCH-2-0/sm/ChangeLog branches/STABLE-BRANCH-2-0/sm/gpgsm.c Log: Change default for --include-certs to -2. Modified: branches/STABLE-BRANCH-2-0/sm/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/sm/ChangeLog 2009-10-15 17:20:41 UTC (rev 5177) +++ branches/STABLE-BRANCH-2-0/sm/ChangeLog 2009-10-16 10:56:59 UTC (rev 5178) @@ -1,3 +1,8 @@ +2009-10-16 Werner Koch + + * gpgsm.c (DEFAULT_INCLUDE_CERTS): New. + (default_include_certs): Init to -2. + 2009-08-06 Werner Koch * sign.c (gpgsm_sign): Print INV_SNDR for a bad default key. Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2009-10-15 17:20:41 UTC (rev 5177) +++ branches/STABLE-BRANCH-2-0/NEWS 2009-10-16 10:56:59 UTC (rev 5178) @@ -1,7 +1,10 @@ Noteworthy changes in version 2.0.14 ------------------------------------------------- + * The default for --inlucde-cert is now to include all certificates + in the chain except for the root certificate. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: branches/STABLE-BRANCH-2-0/doc/gpgsm.texi =================================================================== --- branches/STABLE-BRANCH-2-0/doc/gpgsm.texi 2009-10-15 17:20:41 UTC (rev 5177) +++ branches/STABLE-BRANCH-2-0/doc/gpgsm.texi 2009-10-16 10:56:59 UTC (rev 5178) @@ -560,8 +560,8 @@ -1 includes all certs, 0 does not include any certs, 1 includes only the signers cert (this is the default) and all other positive values include up to @var{n} certificates starting with the signer cert. +The default is -2. - @item --cipher-algo @var{oid} @opindex cipher-algo Use the cipher algorithm with the ASN.1 object identifier @var{oid} for Modified: branches/STABLE-BRANCH-2-0/sm/gpgsm.c =================================================================== --- branches/STABLE-BRANCH-2-0/sm/gpgsm.c 2009-10-15 17:20:41 UTC (rev 5177) +++ branches/STABLE-BRANCH-2-0/sm/gpgsm.c 2009-10-16 10:56:59 UTC (rev 5178) @@ -402,8 +402,11 @@ /* Option --enable-special-filenames */ static int allow_special_filenames; -/* Default value for include-certs. */ -static int default_include_certs = 1; /* Only include the signer's cert. */ +/* Default value for include-certs. We need an extra macro for + gpgconf-list because the variable will be changed by the command + line option. */ +#define DEFAULT_INCLUDE_CERTS -2 /* Include all certs but root. */ +static int default_include_certs = DEFAULT_INCLUDE_CERTS; /* Whether the chain mode shall be used for validation. */ static int default_validation_model; @@ -1606,7 +1609,8 @@ printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE); printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE); printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE); - printf ("include-certs:%lu:1:\n", GC_OPT_FLAG_DEFAULT); + printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, + DEFAULT_INCLUDE_CERTS); printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); From cvs at cvs.gnupg.org Fri Oct 16 14:32:05 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 16 Oct 2009 14:32:05 +0200 Subject: [svn] gpg-error - r223 - in trunk: . src Message-ID: Author: wk Date: 2009-10-16 14:32:05 +0200 (Fri, 16 Oct 2009) New Revision: 223 Modified: trunk/NEWS trunk/src/err-codes.h.in Log: Add another error code. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-09-21 18:59:12 UTC (rev 222) +++ trunk/NEWS 2009-10-16 12:32:05 UTC (rev 223) @@ -5,6 +5,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPG_ERR_NOT_ENABLED NEW GPG_ERR_SOURCE_G13 NEW + GPG_ERR_NO_ENGINE NEW. Noteworthy changes in version 1.7 (2008-11-26) Modified: trunk/src/err-codes.h.in =================================================================== --- trunk/src/err-codes.h.in 2009-09-21 18:59:12 UTC (rev 222) +++ trunk/src/err-codes.h.in 2009-10-16 12:32:05 UTC (rev 223) @@ -209,7 +209,8 @@ 177 GPG_ERR_NO_PASSPHRASE No passphrase given 178 GPG_ERR_NO_PIN No PIN given 179 GPG_ERR_NOT_ENABLED Not enabled -# 180 to 198 are free to be used. +180 GPG_ERR_NO_ENGINE No crypto engine +# 181 to 198 are free to be used. 199 GPG_ERR_UNFINISHED Operation not yet finished 200 GPG_ERR_BUFFER_TOO_SHORT Buffer too short From cvs at cvs.gnupg.org Fri Oct 16 15:13:00 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 16 Oct 2009 15:13:00 +0200 Subject: [svn] GnuPG - r5179 - in trunk: g13 po Message-ID: Author: marcus Date: 2009-10-16 15:13:00 +0200 (Fri, 16 Oct 2009) New Revision: 5179 Modified: trunk/g13/ChangeLog trunk/g13/Makefile.am trunk/po/ChangeLog trunk/po/POTFILES.in Log: po/ 2009-10-16 Marcus Brinkmann * POTFILES.in: g10/encode.c was renamed to g10/encrypt.c, and encr-data.c was renamed to decrypt-data.c g13/ 2009-10-16 Marcus Brinkmann * Makefile.am (AM_CFLAGS): Add $(KSBA_CFLAGS). (g13_LDADD): Add $(KSBA_LIBS). Modified: trunk/g13/ChangeLog =================================================================== --- trunk/g13/ChangeLog 2009-10-16 10:56:59 UTC (rev 5178) +++ trunk/g13/ChangeLog 2009-10-16 13:13:00 UTC (rev 5179) @@ -0,0 +1,5 @@ +2009-10-16 Marcus Brinkmann + + * Makefile.am (AM_CFLAGS): Add $(KSBA_CFLAGS). + (g13_LDADD): Add $(KSBA_LIBS). + Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2009-10-16 10:56:59 UTC (rev 5178) +++ trunk/po/ChangeLog 2009-10-16 13:13:00 UTC (rev 5179) @@ -1,3 +1,8 @@ +2009-10-16 Marcus Brinkmann + + * POTFILES.in: g10/encode.c was renamed to g10/encrypt.c, and + encr-data.c was renamed to decrypt-data.c + 2009-09-03 Werner Koch * de.po: Translate new strings. Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-16 10:56:59 UTC (rev 5178) +++ trunk/g13/Makefile.am 2009-10-16 13:13:00 UTC (rev 5179) @@ -24,7 +24,8 @@ include $(top_srcdir)/am/cmacros.am -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) \ + $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) g13_SOURCES = \ g13.c g13.h \ @@ -41,6 +42,6 @@ be-truecrypt.c be-truecrypt.h g13_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) Modified: trunk/po/POTFILES.in =================================================================== --- trunk/po/POTFILES.in 2009-10-16 10:56:59 UTC (rev 5178) +++ trunk/po/POTFILES.in 2009-10-16 13:13:00 UTC (rev 5179) @@ -28,8 +28,8 @@ g10/dearmor.c g10/decrypt.c g10/delkey.c -g10/encode.c -g10/encr-data.c +g10/encrypt.c +g10/decrypt-data.c g10/exec.c g10/export.c g10/getkey.c From cvs at cvs.gnupg.org Fri Oct 16 20:24:47 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 16 Oct 2009 20:24:47 +0200 Subject: [svn] assuan - r309 - in trunk: . doc src Message-ID: Author: marcus Date: 2009-10-16 20:24:46 +0200 (Fri, 16 Oct 2009) New Revision: 309 Removed: trunk/src/assuan-io-pth.c Modified: trunk/ChangeLog trunk/NEWS trunk/autogen.sh trunk/configure.ac trunk/doc/ChangeLog trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/assuan-buffer.c trunk/src/assuan-client.c trunk/src/assuan-defs.h trunk/src/assuan-error.c trunk/src/assuan-handler.c trunk/src/assuan-inquire.c trunk/src/assuan-io.c trunk/src/assuan-listen.c trunk/src/assuan-pipe-connect.c trunk/src/assuan-pipe-server.c trunk/src/assuan-socket-connect.c trunk/src/assuan-socket-server.c trunk/src/assuan-socket.c trunk/src/assuan-uds.c trunk/src/assuan.c trunk/src/assuan.h trunk/src/context.c trunk/src/conversion.c trunk/src/debug.h trunk/src/libassuan-config.in trunk/src/libassuan.def trunk/src/libassuan.m4 trunk/src/libassuan.vers trunk/src/system.c Log: 2009-10-16 Marcus Brinkmann * autogen.sh: Remove --with-pth-prefix from configure invocation. * configure.ac (_ASSUAN_IN_LIBASSUAN, PTH_SYSCALL_SOFT): Do not set anymore. (GNUPG_PATH_PTH): Don't invoke. (HAVE_PTH): Remove conditional. (LIBASSUAN_CONFIG_THREAD_MODULES): Removed. doc/ 2009-10-16 Marcus Brinkmann * assuan.texi: Remove documentation for thread support. (assuan_pipe_connect_ext): Update prototype. src/ 2009-10-16 Marcus Brinkmann * conversion.c: Do not include and . * debug.h (TRACE_BEG6, TRACE4): New macros. (TRACE_SYSERR): Pass _assuan_trace_context to _assuan_debug. * context.c (assuan_set_pointer, assuan_get_pointer, assuan_set_flag, assuan_get_flag, assuan_set_io_monitor, assuan_set_error): Add trace messages. * libassuan-config.in, libassuan.m4, Makefile.am: Remove PTH support. * assuan.h (assuan_msghdr_t): New type. (ASSUAN_INVALID_PID): New macro. (ASSUAN_NO_FIXSIGNALS): New flag macro. (ASSUAN_SYSTEM_HOOKS_VERSION): New macro. (struct assuan_system_hooks, assuan_system_hooks_t): New types. (assuan_pipe_connect, assuan_pipe_connect_ext): Don't make ARGV const for name==NULL operation. Make fd_child_list an array of assuan_fd_t. (assuan_sock_init, assuan_sock_deinit, assuan_set_system_hooks, assuan_ctx_set_system_hooks, __assuan_pipe, __assuan_close, __assuan_spawn, __assuan_socketpair): New function prototypes. (_ASSUAN_SYSTEM_PTH_IMPL, ASSUAN_SYSTEM_PTH_DECL, ASSUAN_SYSTEM_PTH): New macros. (_assuan_system_pth): New declaration. * libassuan.vers, libassuan.defs: Add assuan_sock_init, assuan_sock_deinit, __assuan_pipe, __assuan_close, __assuan_spawn, __assuan_socketpair, assuan_set_system_hooks, assuan_ctx_set_system_hooks. * assuan-defs.h (struct assuan_io): Removed, move members to ... (struct assuan_context_s): ... this to ENGINE. New flag no_fixsignals. New member SYSTEM. Remove member IO. (_assuan_pipe, _assuan_read, _assuan_write, _assuan_recvmsg, _assuan_sendmsg, _assuan_spawn, _assuan_socketpair, _assuan_system_hooks, _assuan_system_hooks_copy): New declarations. (_assuan_error_is_eagain, _assuan_waitpid, _assuan_usleep, _assuan_close, _assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind, _assuan_sock_get_nonce, _assuan_sock_check_nonce): Add context argument. (_assuan_io_read, _assuan_io_write, _assuan_simple_sendmsg, _assuan_simple_recvmsg): Removed. * context.c (assuan_ctx_set_system_hooks): New function. * assuan.c (assuan_set_system_hooks): New function. (assuan_new_ext): Initialize CTX->system. (assuan_release): Always output trace message. * assuan-error.c (_assuan_error_is_eagain): Add ctx argument, pass along to _assuan_usleep. * assuan-inquire.c assuan-listen.c, assuan-socket-server.c, assuan-handler.c, assuan-socket-connect.c, assuan-client.c, assuan-pipe-connect.c, assuan-socket.c: Pass CTX argument to functions that need it (_assuan_sock_new, _assuan_sock_check_none, _assuan_close, _assuan_error_is_eagain and many more). * assuan-socket-server.c (assuan_init_socket_server_ext): Update fields in CTX->engine instead of CTX->io. * assuan-socket-connect (assuan_socket_connect_ext): Likewise. * assuan-uds.c (uds_reader, uds_writer, uds_sendfd): Use _assuan_recvmsg and _assuan_sendmsg instead of _assuan_simple_recvmsg and _assuan_simple_sendmsg respectively. (_assuan_init_uds_io): Update fields in CTX->engine instead of CTX->io. * assuan-buffer.c: Use functions in CTX->engine instead of CTX->io. * assuan-pipe-server.c (assuan_init_pipe_server): Update fields in CTX->engine instead of CTX->io. * system.c: Include , , , and resp. . Define MAX_OPEN_FDS. (_assuan_system_hooks_copy, __assuan_usleep, _assuan_usleep, __assuan_pipe, _assuan_pipe, __assuan_close, _assuan_close, __assuan_read, _assuan_read, __assuan_write, _assuan_write, __assuan_recvmsg, _assuan_recvmsg, __assuan_sendmsg, _assuan_sendmsg, __assuan_spawn, _assuan_spawn, __assuan_waitpid, _assuan_waitpid, __assuan_socketpair, _assuan_socketpair): New functions. (_assuan_system_hooks): New singleton. * assuan-io.c (_assuan_waitpid, do_io_read, _assuan_io_read, do_io_write, _assuan_io_write, _assuan_simple_sendmsg, _assuan_simple_recvmsg, _assuan_usleep): Removed. * assuan-pipe-connect (writen, build_w32_commandline, create_inheritable_pipe): Removed (actually moved to system.c). (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: Still fix signals. (do_finish): Move waitpid logic to _assuan_waitpid, just call that. (struct at_pipe_fork, struct at_socketpair_fork): New types. (at_pipe_fork_cb, at_socketpair_fork_cb): New callback functions. (pipe_connect_unix, pipe_connect_w32): Replaced by ... (pipe_connect): ... this new function using new system functions. (socketpair_connect): Reimplement to use new system functions. (assuan_pipe_connect, assuan_pipe_connect_ext): Add trace message. * assuan-socket.c (_assuan_close): Removed (moved to system.c). (_assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind, _assuan_sock_get_nonce, _assuan_sock_check_nonce): Add context argument. Use new system interface. (sock_ctx): New singleton. (assuan_sock_init, assuan_sock_deinit): New functions to initialize and deinitialize the singleton. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/ChangeLog 2009-10-16 18:24:46 UTC (rev 309) @@ -1,3 +1,12 @@ +2009-10-16 Marcus Brinkmann + + * autogen.sh: Remove --with-pth-prefix from configure invocation. + * configure.ac (_ASSUAN_IN_LIBASSUAN, PTH_SYSCALL_SOFT): Do not + set anymore. + (GNUPG_PATH_PTH): Don't invoke. + (HAVE_PTH): Remove conditional. + (LIBASSUAN_CONFIG_THREAD_MODULES): Removed. + 2009-10-08 Marcus Brinkmann * configure.ac: AC_REPLACE_FUNCS for vasprintf. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/doc/ChangeLog 2009-10-16 18:24:46 UTC (rev 309) @@ -1,3 +1,8 @@ +2009-10-16 Marcus Brinkmann + + * assuan.texi: Remove documentation for thread support. + (assuan_pipe_connect_ext): Update prototype. + 2009-10-14 Werner Koch * assuan.texi (Utilities): Describe assuan_get_command_name. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/ChangeLog 2009-10-16 18:24:46 UTC (rev 309) @@ -1,3 +1,105 @@ +2009-10-16 Marcus Brinkmann + + * conversion.c: Do not include and . + * debug.h (TRACE_BEG6, TRACE4): New macros. + (TRACE_SYSERR): Pass _assuan_trace_context to _assuan_debug. + * context.c (assuan_set_pointer, assuan_get_pointer, + assuan_set_flag, assuan_get_flag, assuan_set_io_monitor, + assuan_set_error): Add trace messages. + + * libassuan-config.in, libassuan.m4, Makefile.am: Remove PTH support. + * assuan.h (assuan_msghdr_t): New type. + (ASSUAN_INVALID_PID): New macro. + (ASSUAN_NO_FIXSIGNALS): New flag macro. + (ASSUAN_SYSTEM_HOOKS_VERSION): New macro. + (struct assuan_system_hooks, assuan_system_hooks_t): New types. + (assuan_pipe_connect, assuan_pipe_connect_ext): Don't make ARGV + const for name==NULL operation. Make fd_child_list an array of + assuan_fd_t. + (assuan_sock_init, assuan_sock_deinit, assuan_set_system_hooks, + assuan_ctx_set_system_hooks, __assuan_pipe, __assuan_close, + __assuan_spawn, __assuan_socketpair): New function prototypes. + (_ASSUAN_SYSTEM_PTH_IMPL, ASSUAN_SYSTEM_PTH_DECL, + ASSUAN_SYSTEM_PTH): New macros. + (_assuan_system_pth): New declaration. + * libassuan.vers, libassuan.defs: Add assuan_sock_init, + assuan_sock_deinit, __assuan_pipe, __assuan_close, __assuan_spawn, + __assuan_socketpair, assuan_set_system_hooks, + assuan_ctx_set_system_hooks. + + * assuan-defs.h (struct assuan_io): Removed, move members to ... + (struct assuan_context_s): ... this to ENGINE. New flag + no_fixsignals. New member SYSTEM. Remove member IO. + (_assuan_pipe, _assuan_read, _assuan_write, _assuan_recvmsg, + _assuan_sendmsg, _assuan_spawn, _assuan_socketpair, + _assuan_system_hooks, _assuan_system_hooks_copy): New + declarations. + (_assuan_error_is_eagain, _assuan_waitpid, _assuan_usleep, + _assuan_close, _assuan_sock_new, _assuan_sock_connect, + _assuan_sock_bind, _assuan_sock_get_nonce, + _assuan_sock_check_nonce): Add context argument. + (_assuan_io_read, _assuan_io_write, _assuan_simple_sendmsg, + _assuan_simple_recvmsg): Removed. + + * context.c (assuan_ctx_set_system_hooks): New function. + * assuan.c (assuan_set_system_hooks): New function. + (assuan_new_ext): Initialize CTX->system. + (assuan_release): Always output trace message. + + * assuan-error.c (_assuan_error_is_eagain): Add ctx argument, pass + along to _assuan_usleep. + * assuan-inquire.c assuan-listen.c, assuan-socket-server.c, + assuan-handler.c, assuan-socket-connect.c, assuan-client.c, + assuan-pipe-connect.c, assuan-socket.c: Pass CTX argument to + functions that need it + (_assuan_sock_new, _assuan_sock_check_none, _assuan_close, + _assuan_error_is_eagain and many more). + * assuan-socket-server.c (assuan_init_socket_server_ext): Update + fields in CTX->engine instead of CTX->io. + * assuan-socket-connect (assuan_socket_connect_ext): Likewise. + * assuan-uds.c (uds_reader, uds_writer, uds_sendfd): Use + _assuan_recvmsg and _assuan_sendmsg instead of + _assuan_simple_recvmsg and _assuan_simple_sendmsg respectively. + (_assuan_init_uds_io): Update fields in CTX->engine instead of + CTX->io. + * assuan-buffer.c: Use functions in CTX->engine instead of CTX->io. + * assuan-pipe-server.c (assuan_init_pipe_server): Update + fields in CTX->engine instead of CTX->io. + + * system.c: Include , , , and + resp. . Define MAX_OPEN_FDS. + (_assuan_system_hooks_copy, __assuan_usleep, _assuan_usleep, + __assuan_pipe, _assuan_pipe, __assuan_close, _assuan_close, + __assuan_read, _assuan_read, __assuan_write, _assuan_write, + __assuan_recvmsg, _assuan_recvmsg, __assuan_sendmsg, + _assuan_sendmsg, __assuan_spawn, _assuan_spawn, __assuan_waitpid, + _assuan_waitpid, __assuan_socketpair, _assuan_socketpair): New + functions. + (_assuan_system_hooks): New singleton. + * assuan-io.c (_assuan_waitpid, do_io_read, _assuan_io_read, + do_io_write, _assuan_io_write, _assuan_simple_sendmsg, + _assuan_simple_recvmsg, _assuan_usleep): Removed. + + * assuan-pipe-connect (writen, build_w32_commandline, + create_inheritable_pipe): Removed (actually moved to system.c). + (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: Still fix signals. + (do_finish): Move waitpid logic to _assuan_waitpid, just call + that. + (struct at_pipe_fork, struct at_socketpair_fork): New types. + (at_pipe_fork_cb, at_socketpair_fork_cb): New callback functions. + (pipe_connect_unix, pipe_connect_w32): Replaced by ... + (pipe_connect): ... this new function using new system functions. + (socketpair_connect): Reimplement to use new system functions. + (assuan_pipe_connect, assuan_pipe_connect_ext): Add trace message. + + * assuan-socket.c (_assuan_close): Removed (moved to system.c). + (_assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind, + _assuan_sock_get_nonce, _assuan_sock_check_nonce): Add context + argument. Use new system interface. + (sock_ctx): New singleton. + (assuan_sock_init, assuan_sock_deinit): New functions to + initialize and deinitialize the singleton. + 2009-10-14 Werner Koch * assuan-defs.h (assuan_context_s): Add field CURRENT_CMD_NAME. @@ -7,6 +109,18 @@ 2009-10-08 Marcus Brinkmann + * Makefile.am (libassuan_pth): Removed. + (lib_LTLIBRARIES): Remove $(libassuan_pth). + (libassuan_pth_la_SOURCES, libassuan_pth_la_CPPFLAGS) + (libassuan_pth_la_CFLAGS, libassuan_pth_la_LIBADD): Removed. + * libassuan.m4 (AM_PATH_LIBASSUAN_PTH, AM_PATH_LIBASSUAN_PTHREAD): + Removed. + * assuan-io-pth.c: Removed. + * libassuan-config.in (all_thread_modules): Removed. Also removed + option --thread. + +2009-10-08 Marcus Brinkmann + * assuan.h (assuan_get_assuan_log_stream, assuan_set_assuan_log_stream): Remove prototypes. * libassuan.def: Remove assuan_get_assuan_log_stream, Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/NEWS 2009-10-16 18:24:46 UTC (rev 309) @@ -13,8 +13,12 @@ If you use assuan_pipe_connect or assuan_pipe_connect_ext with NAME of NULL, you have to provide a non-NULL ARGV argument and check that against "server" or "client" to determine which end you got - after fork(). + after fork(). If you use the assuan sock interface, you must call + assuan_sock_init after setting global context defaults. + * Pth support has changed. This now follows the same style as + libgcrypt by setting system hook callbacks. + * Interface changes relative to the 1.0.5 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ _ASSUAN_ONLY_GPG_ERRORS REMOVED @@ -51,6 +55,18 @@ assuan_io_hooks_t REMOVED: Will come back in expanded form. assuan_io_monitor_t CHANGED: Add a hook data argument. assuan_get_command_name NEW +assuan_msghdr_t NEW +ASSUAN_INVALID_PID NEW +ASSUAN_NO_FIXSIGNALS NEW +ASSUAN_SYSTEM_HOOKS_VERSION NEW +assuan_system_hooks_t NEW +assuan_set_system_hooks NEW +assuan_ctx_set_system_hooks NEW +ASSUAN_SYSTEM_PTH_IMPL NEW +ASSUAN_SYSTEM_PTH_DECL NEW +ASSUAN_SYSTEM_PTH NEW +assuan_sock_init NEW +assuan_sock_deinit NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/autogen.sh 2009-10-16 18:24:46 UTC (rev 309) @@ -77,7 +77,6 @@ ./configure --enable-maintainer-mode --prefix=${w32root} \ --host=${host} --build=${build} \ - --with-pth-prefix=${w32root} \ --disable-shared exit $? Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/configure.ac 2009-10-16 18:24:46 UTC (rev 309) @@ -1,5 +1,5 @@ # configure.ac - for libassuan -# Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 2001-2003, 2006, 2007, 2009 Free Software Foundation, Inc. # # This file is part of Assuan. # @@ -132,16 +132,6 @@ fi -AH_BOTTOM([ -#define _ASSUAN_IN_LIBASSUAN 1 - -/* We explicitly need to disable PTH's soft mapping as Debian - currently enables it by default for no reason. */ -#define PTH_SYSCALL_SOFT 0 - -]) - - # # Options depending on the host OS. # @@ -191,13 +181,7 @@ AC_SUBST(BUILD_FILEVERSION) AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) -# -# See whether we can build a Pth enabled version -# -GNUPG_PATH_PTH -AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes") - # Check for network libraries. They are needed for tests. AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt, [NETLIBS="-lsocket $NETLIBS"])) @@ -211,10 +195,6 @@ # For src/libassuan-config.in LIBASSUAN_CONFIG_LIB="-lassuan" LIBASSUAN_CONFIG_CFLAGS="" -LIBASSUAN_CONFIG_THREAD_MODULES= -if test "$have_pth" = yes; then -LIBASSUAN_CONFIG_THREAD_MODULES="pth" -fi LIBASSUAN_CONFIG_EXTRA_LIBS= if test x"$NETLIBS" != x; then LIBASSUAN_CONFIG_EXTRA_LIBS="$LIBASSUAN_CONFIG_EXTRA_LIBS $NETLIBS" @@ -222,7 +202,6 @@ AC_SUBST(LIBASSUAN_CONFIG_LIB) AC_SUBST(LIBASSUAN_CONFIG_CFLAGS) AC_SUBST(LIBASSUAN_CONFIG_API_VERSION) -AC_SUBST(LIBASSUAN_CONFIG_THREAD_MODULES) AC_SUBST(LIBASSUAN_CONFIG_EXTRA_LIBS) # Checks for header files. Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/doc/assuan.texi 2009-10-16 18:24:46 UTC (rev 309) @@ -465,11 +465,7 @@ gcc -o foo foo.c $(libassuan-config --cflags --libs) @end example -If your application uses Pth or pthread, you need to pass the option - at option{--thread=pth} respective @option{--thread=pthread} to the -invocation of @command{libassuan-config}. - @node Automake @section Building sources using Automake @@ -498,36 +494,27 @@ LDADD = $(LIBASSUAN_LIBS) @end example - at defmac AM_PATH_LIBASSUAN_PTH (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found}) -Same as @code{AM_PATH_LIBASSUAN} but checks for the GNU Pth enabled -version of the library and defines @code{LIBASSUAN_PTH_CFLAGS} - at code{LIBASSUAN_PTH_LIBS} instead. Use this is you are using GNU Pth. -Note that you also need to pass the appropriate options for Pth to the -compiler and linker. - at end defmac - at defmac AM_PATH_LIBASSUAN_PTHREAD (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found}) -Same as @code{AM_PATH_LIBASSUAN} but checks for the pthreads enabled -version of the library and defines @code{LIBASSUAN_PTHREAD_CFLAGS} - at code{LIBASSUAN_PTHREAD_LIBS} instead. Use this is you are using GNU Pth. -Note that you also need to pass the appropriate options for Pth to the -compiler and linker. - at end defmac - - - @node Multi Threading @section Multi Threading -The @code{libassuan} library is thread-safe if you adhere to the following -requirements: +The @code{libassuan} library is designed so that it can be used in a +threaded application, if some rules are followed. @itemize @bullet @item Run the initialization functions before you actually start -to use threads. +to use threads. Specifically, the functions + at code{assuan_set_gpg_err_source}, @code{assuan_set_malloc_hooks} and + at code{assuan_set_log_cb} should not be called concurrently with + at code{assuan_new}. Use @code{assuan_new_ext} instead or ensure proper +serialization. @item Only one thread at a time may access an @code{libassuan} context. @item If you use the default log handler, use @code{assuan_set_assuan_log_stream} to setup a default log stream. + at item If you have callback functions shared by multiple functions, +the callback function must be reentrant for that purpose. + at code{libassuan} does not serialize invocation of callback functions +across contexts. @end itemize @@ -950,12 +937,12 @@ sockets, the full-fledged variant of the above function should be used: - at deftypefun gpg_error_t assuan_pipe_connect_ext (@w{assuan_context_t *@var{ctx}}, at w{const char *@var{name}}, @w{const char *@var{argv}[]}, @w{int *@var{fd_child_list}}, @w{void (*@var{atfork}) (void *, int)}, @w{void *@var{atforkvalue}}, @w{unsigned int @var{flags}}) + at deftypefun gpg_error_t assuan_pipe_connect_ext (@w{assuan_context_t *@var{ctx}}, at w{const char *@var{name}}, @w{const char *@var{argv}[]}, @w{assuan_fd_t *@var{fd_child_list}}, @w{void (*@var{atfork}) (void *, int)}, @w{void *@var{atforkvalue}}, @w{unsigned int @var{flags}}) A call to this functions forks the current process and executes the program @var{name}, passing the arguments given in the NULL-terminated list @var{argv}. A list of file descriptors not to be closed may be -given using the @code{-1} terminated array @var{fd_child_list}. +given using the @code{ASSUAN_INVLID_FD} terminated array @var{fd_child_list}. If @var{name} is a null pointer, only a fork but no exec is done. Thus the child continues to run. However all file descriptors are Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/Makefile.am 2009-10-16 18:24:46 UTC (rev 309) @@ -21,16 +21,10 @@ versioninfo.rc.in libassuan.def INCLUDES = -I.. -I$(top_srcdir)/include -if HAVE_PTH -libassuan_pth = libassuan-pth.la -else -libassuan_pth = -endif - bin_SCRIPTS = libassuan-config m4datadir = $(datadir)/aclocal m4data_DATA = libassuan.m4 -lib_LTLIBRARIES = libassuan.la $(libassuan_pth) +lib_LTLIBRARIES = libassuan.la include_HEADERS = assuan.h if HAVE_LD_VERSION_SCRIPT @@ -107,11 +101,3 @@ libassuan_la_DEPENDENCIES = @LTLIBOBJS@ \ $(srcdir)/libassuan.vers $(libassuan_deps) libassuan_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@ - -if HAVE_PTH -libassuan_pth_la_SOURCES = $(common_sources) assuan-io-pth.c -libassuan_pth_la_CPPFLAGS = $(AM_CPPFLAGS) @GPG_ERROR_CFLAGS@ @PTH_CFLAGS@ -libassuan_pth_la_CFLAGS = $(AM_CFLAGS) @GPG_ERROR_CFLAGS@ $(PTH_CFLAGS) -libassuan_pth_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@ @PTH_LIBS@ -endif - Modified: trunk/src/assuan-buffer.c =================================================================== --- trunk/src/assuan-buffer.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-buffer.c 2009-10-16 18:24:46 UTC (rev 309) @@ -37,7 +37,7 @@ { while (length) { - ssize_t nwritten = ctx->io->writefnc (ctx, buffer, length); + ssize_t nwritten = ctx->engine.writefnc (ctx, buffer, length); if (nwritten < 0) { @@ -66,7 +66,7 @@ *r_nread = 0; while (nleft > 0) { - ssize_t n = ctx->io->readfnc (ctx, buf, nleft); + ssize_t n = ctx->engine.readfnc (ctx, buf, nleft); if (n < 0) { @@ -249,7 +249,7 @@ { err = _assuan_read_line (ctx); } - while (_assuan_error_is_eagain (err)); + while (_assuan_error_is_eagain (ctx, err)); *line = ctx->inbound.line; *linelen = ctx->inbound.linelen; @@ -551,19 +551,19 @@ return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED); #endif - if (! ctx->io->sendfd) + if (! ctx->engine.sendfd) return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, "server does not support sending and receiving " "of file descriptors"); - return ctx->io->sendfd (ctx, fd); + return ctx->engine.sendfd (ctx, fd); } gpg_error_t assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd) { - if (! ctx->io->receivefd) + if (! ctx->engine.receivefd) return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, "server does not support sending and receiving " "of file descriptors"); - return ctx->io->receivefd (ctx, fd); + return ctx->engine.receivefd (ctx, fd); } Modified: trunk/src/assuan-client.c =================================================================== --- trunk/src/assuan-client.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-client.c 2009-10-16 18:24:46 UTC (rev 309) @@ -49,7 +49,7 @@ { rc = _assuan_read_line (ctx); } - while (_assuan_error_is_eagain (rc)); + while (_assuan_error_is_eagain (ctx, rc)); if (rc) return rc; line = ctx->inbound.line; Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-defs.h 2009-10-16 18:24:46 UTC (rev 309) @@ -56,19 +56,6 @@ }; -/* A structure to dispatch I/O functions. */ -struct assuan_io -{ - /* Routine to read from input_fd. Sets errno on failure. */ - ssize_t (*readfnc) (assuan_context_t, void *, size_t); - /* Routine to write to output_fd. Sets errno on failure. */ - ssize_t (*writefnc) (assuan_context_t, const void *, size_t); - /* Send a file descriptor. */ - gpg_error_t (*sendfd) (assuan_context_t, assuan_fd_t); - /* Receive a file descriptor. */ - gpg_error_t (*receivefd) (assuan_context_t, assuan_fd_t *); -}; - /* The context we use with most functions. */ struct assuan_context_s @@ -97,17 +84,30 @@ { unsigned int no_waitpid : 1; unsigned int confidential : 1; + unsigned int no_fixsignals : 1; } flags; /* If set, this is called right before logging an I/O line. */ assuan_io_monitor_t io_monitor; void *io_monitor_data; + /* Callback handlers replacing system I/O functions. */ + struct assuan_system_hooks system; + /* Now come the members specific to subsystems or engines. FIXME: This is not developed yet. See below for the legacy members. */ struct { void (*release) (assuan_context_t ctx); + + /* Routine to read from input_fd. Sets errno on failure. */ + ssize_t (*readfnc) (assuan_context_t, void *, size_t); + /* Routine to write to output_fd. Sets errno on failure. */ + ssize_t (*writefnc) (assuan_context_t, const void *, size_t); + /* Send a file descriptor. */ + gpg_error_t (*sendfd) (assuan_context_t, assuan_fd_t); + /* Receive a file descriptor. */ + gpg_error_t (*receivefd) (assuan_context_t, assuan_fd_t *); } engine; @@ -220,11 +220,6 @@ assuan_fd_t input_fd; /* Set by the INPUT command. */ assuan_fd_t output_fd; /* Set by the OUTPUT command. */ - - /* io routines. */ - struct assuan_io *io; - - }; @@ -242,6 +237,38 @@ void *_assuan_calloc (assuan_context_t ctx, size_t cnt, size_t elsize); void _assuan_free (assuan_context_t ctx, void *ptr); +/* System hooks. */ +void _assuan_usleep (assuan_context_t ctx, unsigned int usec); +int _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx); +int _assuan_close (assuan_context_t ctx, assuan_fd_t fd); +ssize_t _assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, + size_t size); +ssize_t _assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, + size_t size); +int _assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd, + assuan_msghdr_t msg, int flags); +int _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd, + assuan_msghdr_t msg, int flags); +int _assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, + const char *argv[], + assuan_fd_t fd_in, assuan_fd_t fd_out, + assuan_fd_t *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue, unsigned int flags); +pid_t _assuan_waitpid (assuan_context_t ctx, pid_t pid, int nowait, + int *status, int options); +int _assuan_socketpair (assuan_context_t ctx, int namespace, int style, + int protocol, int filedes[2]); + +extern struct assuan_system_hooks _assuan_system_hooks; + +/* Copy the system hooks struct, paying attention to version + differences. SRC is usually from the user, DST MUST be from the + library. */ +void +_assuan_system_hooks_copy (assuan_system_hooks_t dst, + assuan_system_hooks_t src); + /*-- assuan-pipe-server.c --*/ void _assuan_release_context (assuan_context_t ctx); @@ -273,7 +300,7 @@ void _assuan_inquire_release (assuan_context_t ctx); /* Check if ERR means EAGAIN. */ -int _assuan_error_is_eagain (gpg_error_t err); +int _assuan_error_is_eagain (assuan_context_t ctx, gpg_error_t err); @@ -290,33 +317,22 @@ /*-- assuan-io.c --*/ -pid_t _assuan_waitpid (pid_t pid, int *status, int options); - ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size); ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size); -ssize_t _assuan_io_read (assuan_fd_t fd, void *buffer, size_t size); -ssize_t _assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size); -#ifdef HAVE_W32_SYSTEM -int _assuan_simple_sendmsg (assuan_context_t ctx, void *msg); -int _assuan_simple_recvmsg (assuan_context_t ctx, void *msg); -#else -ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg); -ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg); -#endif -void _assuan_usleep (unsigned int usec); +/*-- assuan-socket.c --*/ - -/*-- assuan-socket.c --*/ -int _assuan_close (assuan_fd_t fd); -assuan_fd_t _assuan_sock_new (int domain, int type, int proto); -int _assuan_sock_connect (assuan_fd_t sockfd, +assuan_fd_t _assuan_sock_new (assuan_context_t ctx, int domain, int type, + int proto); +int _assuan_sock_connect (assuan_context_t ctx, assuan_fd_t sockfd, struct sockaddr *addr, int addrlen); -int _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen); -int _assuan_sock_get_nonce (struct sockaddr *addr, int addrlen, - assuan_sock_nonce_t *nonce); -int _assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce); +int _assuan_sock_bind (assuan_context_t ctx, assuan_fd_t sockfd, + struct sockaddr *addr, int addrlen); +int _assuan_sock_get_nonce (assuan_context_t ctx, struct sockaddr *addr, + int addrlen, assuan_sock_nonce_t *nonce); +int _assuan_sock_check_nonce (assuan_context_t ctx, assuan_fd_t fd, + assuan_sock_nonce_t *nonce); #ifdef HAVE_W32_SYSTEM int _assuan_sock_wsa2errno (int err); #endif Modified: trunk/src/assuan-error.c =================================================================== --- trunk/src/assuan-error.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-error.c 2009-10-16 18:24:46 UTC (rev 309) @@ -33,13 +33,13 @@ /* A small helper function to treat EAGAIN transparently to the caller. */ int -_assuan_error_is_eagain (gpg_error_t err) +_assuan_error_is_eagain (assuan_context_t ctx, gpg_error_t err) { if (gpg_err_code (err) == GPG_ERR_EAGAIN) { /* Avoid spinning by sleeping for one tenth of a second. */ - _assuan_usleep (100000); - return 1; + _assuan_usleep (ctx, 100000); + return 1; } else return 0; Modified: trunk/src/assuan-handler.c =================================================================== --- trunk/src/assuan-handler.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-handler.c 2009-10-16 18:24:46 UTC (rev 309) @@ -219,6 +219,7 @@ return PROCESS_DONE (ctx, 0); } + /* Format is OUTPUT FD= */ static gpg_error_t std_handler_output (assuan_context_t ctx, char *line) @@ -236,9 +237,6 @@ } - - - /* This is a table with the standard commands and handler for them. The table is used to initialize a new context and associate strings with default handlers */ @@ -592,7 +590,7 @@ required to write full lines without blocking long after starting a partial line. */ rc = _assuan_read_line (ctx); - if (_assuan_error_is_eagain (rc)) + if (_assuan_error_is_eagain (ctx, rc)) return 0; if (rc) return rc; @@ -670,7 +668,7 @@ { rc = _assuan_read_line (ctx); } - while (_assuan_error_is_eagain (rc)); + while (_assuan_error_is_eagain (ctx, rc)); if (rc) return rc; if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) Modified: trunk/src/assuan-inquire.c =================================================================== --- trunk/src/assuan-inquire.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-inquire.c 2009-10-16 18:24:46 UTC (rev 309) @@ -176,7 +176,7 @@ { do rc = _assuan_read_line (ctx); - while (_assuan_error_is_eagain (rc)); + while (_assuan_error_is_eagain (ctx, rc)); if (rc) goto leave; line = (unsigned char *) ctx->inbound.line; Deleted: trunk/src/assuan-io-pth.c Modified: trunk/src/assuan-io.c =================================================================== --- trunk/src/assuan-io.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-io.c 2009-10-16 18:24:46 UTC (rev 309) @@ -38,185 +38,15 @@ #include "assuan-defs.h" -#ifndef HAVE_W32_SYSTEM -pid_t -_assuan_waitpid (pid_t pid, int *status, int options) -{ - return waitpid (pid, status, options); -} -#endif - - -static ssize_t -do_io_read (assuan_fd_t fd, void *buffer, size_t size) -{ -#ifdef HAVE_W32_SYSTEM - /* Due to the peculiarities of the W32 API we can't use read for a - network socket and thus we try to use recv first and fallback to - read if recv detects that it is not a network socket. */ - int n; - - n = recv (HANDLE2SOCKET(fd), buffer, size, 0); - if (n == -1) - { - switch (WSAGetLastError ()) - { - case WSAENOTSOCK: - { - DWORD nread = 0; - - n = ReadFile (fd, buffer, size, &nread, NULL); - if (!n) - { - switch (GetLastError()) - { - case ERROR_BROKEN_PIPE: errno = EPIPE; break; - default: errno = EIO; - } - n = -1; - } - else - n = (int)nread; - } - break; - - case WSAEWOULDBLOCK: errno = EAGAIN; break; - case ERROR_BROKEN_PIPE: errno = EPIPE; break; - default: errno = EIO; break; - } - } - return n; -#else /*!HAVE_W32_SYSTEM*/ - return read (fd, buffer, size); -#endif /*!HAVE_W32_SYSTEM*/ -} - - ssize_t -_assuan_io_read (assuan_fd_t fd, void *buffer, size_t size) -{ - return do_io_read (fd, buffer, size); -} - -ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { - return do_io_read (ctx->inbound.fd, buffer, size); + return _assuan_read (ctx, ctx->inbound.fd, buffer, size); } - -static ssize_t -do_io_write (assuan_fd_t fd, const void *buffer, size_t size) -{ -#ifdef HAVE_W32_SYSTEM - /* Due to the peculiarities of the W32 API we can't use write for a - network socket and thus we try to use send first and fallback to - write if send detects that it is not a network socket. */ - int n; - - n = send (HANDLE2SOCKET(fd), buffer, size, 0); - if (n == -1 && WSAGetLastError () == WSAENOTSOCK) - { - DWORD nwrite; - - n = WriteFile (fd, buffer, size, &nwrite, NULL); - if (!n) - { - switch (GetLastError ()) - { - case ERROR_BROKEN_PIPE: - case ERROR_NO_DATA: errno = EPIPE; break; - default: errno = EIO; break; - } - n = -1; - } - else - n = (int)nwrite; - } - return n; -#else /*!HAVE_W32_SYSTEM*/ - return write (fd, buffer, size); -#endif /*!HAVE_W32_SYSTEM*/ -} - ssize_t -_assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size) -{ - return do_io_write (fd, buffer, size); -} - -ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) { - return do_io_write (ctx->outbound.fd, buffer, size); + return _assuan_write (ctx, ctx->outbound.fd, buffer, size); } - - -#ifdef HAVE_W32_SYSTEM -int -_assuan_simple_sendmsg (assuan_context_t ctx, void *msg) -#else -ssize_t -_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) -#endif -{ -#ifdef HAVE_W32_SYSTEM - errno = ENOSYS; - return -1; -#else - int ret; - while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR) - ; - return ret; -#endif -} - - -#ifdef HAVE_W32_SYSTEM -int -_assuan_simple_recvmsg (assuan_context_t ctx, void *msg) -#else -ssize_t -_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) -#endif -{ -#ifdef HAVE_W32_SYSTEM - errno = ENOSYS; - return -1; -#else - int ret; - while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR) - ; - return ret; -#endif -} - - -void -_assuan_usleep (unsigned int usec) -{ - if (usec) - { -#ifdef HAVE_NANOSLEEP - struct timespec req; - struct timespec rem; - - req.tv_sec = 0; - req.tv_nsec = usec * 1000; - - while (nanosleep (&req, &rem) < 0 && errno == EINTR) - req = rem; - -#elif defined(HAVE_W32_SYSTEM) - Sleep (usec / 1000); -#else - struct timeval tv; - - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; - select (0, NULL, NULL, NULL, &tv); -#endif - } -} - Modified: trunk/src/assuan-listen.c =================================================================== --- trunk/src/assuan-listen.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-listen.c 2009-10-16 18:24:46 UTC (rev 309) @@ -138,7 +138,7 @@ { if (!ctx || ctx->input_fd == ASSUAN_INVALID_FD) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - _assuan_close (ctx->input_fd); + _assuan_close (ctx, ctx->input_fd); ctx->input_fd = ASSUAN_INVALID_FD; return 0; } @@ -151,7 +151,7 @@ if (!ctx || ctx->output_fd == ASSUAN_INVALID_FD) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - _assuan_close (ctx->output_fd); + _assuan_close (ctx, ctx->output_fd); ctx->output_fd = ASSUAN_INVALID_FD; return 0; } Modified: trunk/src/assuan-pipe-connect.c =================================================================== --- trunk/src/assuan-pipe-connect.c 2009-10-14 11:27:08 UTC (rev 308) +++ trunk/src/assuan-pipe-connect.c 2009-10-16 18:24:46 UTC (rev 309) @@ -62,7 +62,6 @@ static void fix_signals (void) { -#ifndef _ASSUAN_NO_FIXED_SIGNALS #ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */ static int fixed_signals; @@ -82,58 +81,28 @@ /* FIXME: This is not MT safe */ } #endif /*HAVE_DOSISH_SYSTEM*/ -#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/ } -#ifndef HAVE_W32_SYSTEM -static int -writen (int fd, const char *buffer, size_t length) -{ - while (length) - { - int nwritten = write (fd, buffer, length); - - if (nwritten < 0) - { - if (errno == EINTR) - continue; - return -1; /* write error */ - } - length -= nwritten; - buffer += nwritten; - } - return 0; /* okay */ -} -#endif - static void do_finish (assuan_context_t ctx) { if (ctx->inbound.fd != ASSUAN_INVALID_FD) { - _assuan_close (ctx->inbound.fd); + _assuan_close (ctx, ctx->inbound.fd); if (ctx->inbound.fd == ctx->outbound.fd) ctx->outbound.fd = ASSUAN_INVALID_FD; ctx->inbound.fd = ASSUAN_INVALID_FD; } if (ctx->outbound.fd != ASSUAN_INVALID_FD) { - _assuan_close (ctx->outbound.fd); + _assuan_close (ctx, ctx->outbound.fd); ctx->outbound.fd = ASSUAN_INVALID_FD; } - if (ctx->pid != (pid_t)(-1) && ctx->pid) + if (ctx->pid != ASSUAN_INVALID_PID && ctx->pid) { -#ifndef HAVE_W32_SYSTEM -#ifndef _ASSUAN_USE_DOUBLE_FORK - if (!ctx->flags.no_waitpid) - _assuan_waitpid (ctx->pid, NULL, 0); - ctx->pid =(pid_t)(-1); -#endif -#else /*!HAVE_W32_SYSTEM*/ - CloseHandle ((HANDLE) ctx->pid); - ctx->pid = (pid_t) INVALID_HANDLE_VALUE; -#endif /*HAVE_W32_SYSTEM*/ + _assuan_waitpid (ctx, ctx->pid, ctx->flags.no_waitpid, NULL, 0); + ctx->pid = ASSUAN_INVALID_PID; } } @@ -166,178 +135,96 @@ return err; } + +struct at_pipe_fork +{ + void (*user_atfork) (void *opaque, int reserved); + void *user_atforkvalue; +}; + +static void +at_pipe_fork_cb (void *opaque, int reserved) +{ + struct at_pipe_fork *atp = opaque; + + if (atp->user_atfork) + atp->user_atfork (atp->user_atforkvalue, reserved); + #ifndef HAVE_W32_SYSTEM -#define pipe_connect pipe_connect_unix -/* Unix version of the pipe connection code. We use an extra macro to - make ChangeLog entries easier. */ + { + char mypidstr[50]; + + /* We store our parents pid in the environment so that the execed + assuan server is able to read the actual pid of the client. + The server can't use getppid because it might have been double + forked before the assuan server has been initialized. */ + sprintf (mypidstr, "%lu", (unsigned long) getpid ()); + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Make sure that we never pass a connection fd variable when + using a simple pipe. */ + unsetenv ("_assuan_connection_fd"); + } +#endif +} + + static gpg_error_t -pipe_connect_unix (assuan_context_t ctx, - const char *name, const char *const argv[], - int *fd_child_list, - void (*atfork) (void *opaque, int reserved), - void *atforkvalue, unsigned int flags) +pipe_connect (assuan_context_t ctx, + const char *name, const char **argv, + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue, unsigned int flags) { - int rp[2]; - int wp[2]; - pid_t pid; - char mypidstr[50]; gpg_error_t rc; - static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write, - 0, 0 }; + assuan_fd_t rp[2]; + assuan_fd_t wp[2]; + pid_t pid; + int res; + struct at_pipe_fork atp; - (void)flags; + atp.user_atfork = atfork; + atp.user_atforkvalue = atforkvalue; if (!ctx || !name || !argv || !argv[0]) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - fix_signals (); + if (! ctx->flags.no_fixsignals) + fix_signals (); - sprintf (mypidstr, "%lu", (unsigned long)getpid ()); - - if (pipe (rp) < 0) - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + if (_assuan_pipe (ctx, rp, 1) < 0) + return _assuan_error (ctx, gpg_err_code_from_syserror ()); - if (pipe (wp) < 0) + if (_assuan_pipe (ctx, wp, 0) < 0) { - close (rp[0]); - close (rp[1]); - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + _assuan_close (ctx, rp[0]); + _assuan_close (ctx, rp[1]); + return _assuan_error (ctx, gpg_err_code_from_syserror ()); } - /* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID - stored here is actually soon useless. */ - pid = fork (); - if (pid < 0) + /* FIXME: Use atfork handler that closes child fds on Unix. */ + res = _assuan_spawn (ctx, &pid, name, argv, wp[0], rp[1], + fd_child_list, at_pipe_fork_cb, &atp, flags); + if (res < 0) { - close (rp[0]); - close (rp[1]); - close (wp[0]); - close (wp[1]); - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + rc = gpg_err_code_from_syserror (); + _assuan_close (ctx, rp[0]); + _assuan_close (ctx, rp[1]); + _assuan_close (ctx, wp[0]); + _assuan_close (ctx, wp[1]); + return _assuan_error (ctx, rc); } - if (pid == 0) - { -#ifdef _ASSUAN_USE_DOUBLE_FORK - pid_t pid2; + /* Close the stdin/stdout child fds in the parent. */ + _assuan_close (ctx, rp[1]); + _assuan_close (ctx, wp[0]); - if ((pid2 = fork ()) == 0) -#endif - { - int i, n; - char errbuf[512]; - int *fdp; - - if (atfork) - atfork (atforkvalue, 0); - - /* Dup handles to stdin/stdout. */ - if (rp[1] != STDOUT_FILENO) - { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx, - "dup2 failed in child: %s", strerror (errno)); - _exit (4); - } - } - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx, - "dup2 failed in child: %s", strerror (errno)); - _exit (4); - } - } - - /* Dup stderr to /dev/null unless it is in the list of FDs to be - passed to the child. */ - fdp = fd_child_list; - if (fdp) - { - for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) - ; - } - if (!fdp || *fdp == -1) - { - int fd = open ("/dev/null", O_WRONLY); - if (fd == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx, - "can't open `/dev/null': %s", strerror (errno)); - _exit (4); - } - if (dup2 (fd, STDERR_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx, - "dup2(dev/null, 2) failed: %s", strerror (errno)); - _exit (4); - } - } - - - /* Close all files which will not be duped and are not in the - fd_child_list. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=0; i < n; i++) - { - if ( i == STDIN_FILENO || i == STDOUT_FILENO - || i == STDERR_FILENO) - continue; - fdp = fd_child_list; - if (fdp) - { - while (*fdp != -1 && *fdp != i) - fdp++; - } - - if (!(fdp && *fdp != -1)) - close(i); - } - errno = 0; - - /* We store our parents pid in the environment so that the - execed assuan server is able to read the actual pid of the - client. The server can't use getppid because it might have - been double forked before the assuan server has been - initialized. */ - setenv ("_assuan_pipe_connect_pid", mypidstr, 1); - - /* Make sure that we never pass a connection fd variable - when using a simple pipe. */ - unsetenv ("_assuan_connection_fd"); - - execv (name, (char *const *) argv); - /* oops - use the pipe to tell the parent about it */ - snprintf (errbuf, sizeof(errbuf)-1, - "ERR %d can't exec `%s': %.50s\n", - _assuan_error (ctx, GPG_ERR_ASS_SERVER_START), - name, strerror (errno)); - errbuf[sizeof(errbuf)-1] = 0; - writen (1, errbuf, strlen (errbuf)); - _exit (4); - } -#ifdef _ASSUAN_USE_DOUBLE_FORK - if (pid2 == -1) - _exit (1); - else - _exit (0); -#endif - } - -#ifdef _ASSUAN_USE_DOUBLE_FORK - _assuan_waitpid (pid, NULL, 0); - pid = -1; -#endif - - close (rp[1]); - close (wp[0]); - - ctx->io = &io; + ctx->engine.release = _assuan_disconnect; + ctx->engine.readfnc = _assuan_simple_read; + ctx->engine.writefnc = _assuan_simple_write; + ctx->engine.sendfd = NULL; + ctx->engine.receivefd = NULL; ctx->pipe_mode = 1; ctx->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ ctx->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ @@ -350,177 +237,134 @@ _assuan_reset (ctx); return rc; } -#endif /*!HAVE_W32_SYSTEM*/ +/* FIXME: For socketpair_connect, use spawn function and add atfork + handler to do the right thing. Instead of stdin and stdout, we + extend the fd_child_list by fds[1]. */ + #ifndef HAVE_W32_SYSTEM +struct at_socketpair_fork +{ + assuan_fd_t peer_fd; + void (*user_atfork) (void *opaque, int reserved); + void *user_atforkvalue; +}; + + +static void +at_socketpair_fork_cb (void *opaque, int reserved) +{ + struct at_socketpair_fork *atp = opaque; + + if (atp->user_atfork) + atp->user_atfork (atp->user_atforkvalue, reserved); + +#ifndef HAVE_W32_SYSTEM + { + char mypidstr[50]; + + /* We store our parents pid in the environment so that the execed + assuan server is able to read the actual pid of the client. + The server can't use getppid because it might have been double + forked before the assuan server has been initialized. */ + sprintf (mypidstr, "%lu", (unsigned long) getpid ()); + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Now set the environment variable used to convey the + connection's file descriptor. */ + sprintf (mypidstr, "%d", atp->peer_fd); + if (setenv ("_assuan_connection_fd", mypidstr, 1)) + _exit (4); + } +#endif +} + + /* This function is similar to pipe_connect but uses a socketpair and sets the I/O up to use sendmsg/recvmsg. */ static gpg_error_t socketpair_connect (assuan_context_t ctx, - const char *name, const char *argv[], + const char *name, const char **argv, int *fd_child_list, void (*atfork) (void *opaque, int reserved), void *atforkvalue) { gpg_error_t err; + int idx; int fds[2]; char mypidstr[50]; pid_t pid; + int *child_fds = NULL; + int child_fds_cnt = 0; + struct at_socketpair_fork atp; + int rc; + TRACE_BEG3 (ctx, ASSUAN_LOG_CTX, "socketpair_connect", ctx, + "name=%s,atfork=%p,atforkvalue=%p", name ? name : "(null)", + atfork, atforkvalue); + + atp.user_atfork = atfork; + atp.user_atforkvalue = atforkvalue; + if (!ctx || (name && (!argv || !argv[0])) || (!name && !argv)) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - fix_signals (); + if (! ctx->flags.no_fixsignals) + fix_signals (); sprintf (mypidstr, "%lu", (unsigned long)getpid ()); - if ( socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) ) + while (fd_child_list[child_fds_cnt] != ASSUAN_INVALID_FD) + child_fds_cnt++; + child_fds = _assuan_malloc (ctx, (child_fds_cnt + 2) * sizeof (int)); + if (! child_fds) + return TRACE_ERR (gpg_err_code_from_syserror ()); + memcpy (&child_fds[1], fd_child_list, (child_fds_cnt + 1) * sizeof (int)); + + if (_assuan_socketpair (ctx, AF_LOCAL, SOCK_STREAM, 0, fds)) { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx, - "socketpair failed: %s", strerror (errno)); - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + TRACE_LOG1 ("socketpair failed: %s", strerror (errno)); + _assuan_free (ctx, child_fds); + return TRACE_ERR (GPG_ERR_ASS_GENERAL); } + atp.peer_fd = fds[1]; + child_fds[0] = fds[1]; - pid = fork (); - if (pid < 0) + + rc = _assuan_spawn (ctx, &pid, name, argv, ASSUAN_INVALID_FD, + ASSUAN_INVALID_FD, child_fds, at_socketpair_fork_cb, + &atp, 0); + if (rc < 0) { - close (fds[0]); - close (fds[1]); - /* FIXME: cleanup ctx */ - return _assuan_error (ctx, GPG_ERR_ASS_GENERAL); + err = gpg_err_code_from_syserror (); + _assuan_close (ctx, fds[0]); + _assuan_close (ctx, fds[1]); + _assuan_free (ctx, child_fds); + return TRACE_ERR (err); } - if (pid == 0) - { -#ifdef _ASSUAN_USE_DOUBLE_FORK - pid_t pid2; + /* For W32, the user needs to know the server-local names of the + inherited handles. Return them here. Note that the translation + of the peer socketpair fd (fd_child_list[0]) must be done by the + wrapper program based on the environment variable + _assuan_connection_fd. */ + for (idx = 0; fd_child_list[idx] != -1; idx++) + /* We add 1 to skip over the socketpair end. */ + fd_child_list[idx] = child_fds[idx + 1]; - if ((pid2 = fork ()) == 0) -#endif - { - int fd, i, n; - char errbuf[512]; - int *fdp; - - if (atfork) - atfork (atforkvalue, 0); - - /* Connect stdin and stdout to /dev/null. */ - fd = open ("/dev/null", O_RDONLY); - if (fd == -1 || dup2 (fd, STDIN_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx, - "dup2(dev/null) failed: %s", strerror (errno)); - _exit (4); - } - fd = open ("/dev/null", O_WRONLY); - if (fd == -1 || dup2 (fd, STDOUT_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx, - "dup2(dev/null) failed: %s", strerror (errno)); - _exit (4); - } - - /* Dup stderr to /dev/null unless it is in the list of FDs to be - passed to the child. */ - fdp = fd_child_list; - if (fdp) - { - for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) - ; - } - if (!fdp || *fdp == -1) - { - fd = open ("/dev/null", O_WRONLY); - if (fd == -1 || dup2 (fd, STDERR_FILENO) == -1) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx, - "dup2(dev/null) failed: %s", strerror (errno)); - _exit (4); - } - } - - - /* Close all files which will not be duped, are not in the - fd_child_list and are not the connection fd. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=0; i < n; i++) - { - if ( i == STDIN_FILENO || i == STDOUT_FILENO - || i == STDERR_FILENO || i == fds[1]) - continue; - fdp = fd_child_list; - if (fdp) - { - while (*fdp != -1 && *fdp != i) - fdp++; - } - - if (!(fdp && *fdp != -1)) - close(i); - } - errno = 0; - - /* We store our parents pid in the environment so that the - execed assuan server is able to read the actual pid of the - client. The server can't use getppid becuase it might have - been double forked before the assuan server has been - initialized. */ - setenv ("_assuan_pipe_connect_pid", mypidstr, 1); - - /* Now set the environment variable used to convey the - connection's file descriptor. */ - sprintf (mypidstr, "%d", fds[1]); - if (setenv ("_assuan_connection_fd", mypidstr, 1)) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx, - "setenv failed: %s", strerror (errno)); - _exit (4); - } - - if (!name) - { - /* No name and no args given, thus we don't do an exec - but continue the forked process. */ - *argv = "server"; - - /* FIXME: Cleanup. */ - return 0; - } - - execv (name, (char *const *) argv); - /* oops - use the pipe to tell the parent about it */ - snprintf (errbuf, sizeof(errbuf)-1, - "ERR %d can't exec `%s': %.50s\n", - _assuan_error (ctx, GPG_ERR_ASS_SERVER_START), - name, strerror (errno)); - errbuf[sizeof(errbuf)-1] = 0; - writen (fds[1], errbuf, strlen (errbuf)); - _exit (4); - } -#ifdef _ASSUAN_USE_DOUBLE_FORK - if (pid2 == -1) - _exit (1); - else - _exit (0); -#endif + /* If this is the server child process, exit early. */ + if (! name && (*argv)[0] == 's') + { + _assuan_free (ctx, child_fds); + _assuan_close (ctx, fds[0]); + return 0; } - if (! name) - *argv = "client"; + _assuan_close (ctx, fds[1]); -#ifdef _ASSUAN_USE_DOUBLE_FORK - _assuan_waitpid (pid, NULL, 0); - pid = -1; -#endif - - close (fds[1]); - ctx->pipe_mode = 1; ctx->inbound.fd = fds[0]; ctx->outbound.fd = fds[0]; @@ -535,282 +379,6 @@ } #endif /*!HAVE_W32_SYSTEM*/ - - -#ifdef HAVE_W32_SYSTEM -/* Build a command line for use with W32's CreateProcess. On success - CMDLINE gets the address of a newly allocated string. */ -static int -build_w32_commandline (assuan_context_t ctx, const char * const *argv, char **cmdline) -{ - int i, n; - const char *s; - char *buf, *p; - - *cmdline = NULL; - n = 0; - for (i=0; (s=argv[i]); i++) - { - n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ - for (; *s; s++) - if (*s == '\"') - n++; /* Need to double inner quotes. */ - } - n++; - - buf = p = _assuan_malloc (ctx, n); - if (!buf) - return -1; - - for (i=0; argv[i]; i++) - { - if (i) - p = stpcpy (p, " "); - if (!*argv[i]) /* Empty string. */ - p = stpcpy (p, "\"\""); - else if (strpbrk (argv[i], " \t\n\v\f\"")) - { - p = stpcpy (p, "\""); - for (s=argv[i]; *s; s++) - { - *p++ = *s; - if (*s == '\"') - *p++ = *s; - } - *p++ = '\"'; - *p = 0; - } - else - p = stpcpy (p, argv[i]); - } - - *cmdline= buf; - return 0; -} -#endif /*HAVE_W32_SYSTEM*/ - - -#ifdef HAVE_W32_SYSTEM -/* Create pipe where one end end is inheritable. */ -static int -create_inheritable_pipe (assuan_context_t ctx, - assuan_fd_t filedes[2], int for_write) -{ - HANDLE r, w, h; - SECURITY_ATTRIBUTES sec_attr; - - memset (&sec_attr, 0, sizeof sec_attr ); - sec_attr.nLength = sizeof sec_attr; - sec_attr.bInheritHandle = FALSE; - - if (!CreatePipe (&r, &w, &sec_attr, 0)) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx, - "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1)); - return -1; - } - - if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w, - GetCurrentProcess(), &h, 0, - TRUE, DUPLICATE_SAME_ACCESS )) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx, - "DuplicateHandle failed: %s", _assuan_w32_strerror (ctx, -1)); - CloseHandle (r); - CloseHandle (w); - return -1; - } - if (for_write) - { - CloseHandle (r); - r = h; - } - else - { - CloseHandle (w); - w = h; - } - - filedes[0] = r; - filedes[1] = w; - return 0; -} -#endif /*HAVE_W32_SYSTEM*/ - - -#ifdef HAVE_W32_SYSTEM -#define pipe_connect pipe_connect_w32 -/* W32 version of the pipe connection code. */ -static gpg_error_t -pipe_connect_w32 (assuan_context_t ctx, - const char *name, const char *const argv[], - int *fd_child_list, - void (*atfork) (void *opaque, int reserved), - void *atforkvalue, unsigned int flags) -{ - gpg_error_t err; - assuan_fd_t rp[2]; - assuan_fd_t wp[2]; - char mypidstr[50]; - char *cmdline; - SECURITY_ATTRIBUTES sec_attr; - PROCESS_INFORMATION pi = - { - NULL, /* Returns process handle. */ - 0, /* Returns primary thread handle. */ - 0, /* Returns pid. */ - 0 /* Returns tid. */ - }; - STARTUPINFO si; - int fd, *fdp; - HANDLE nullfd = INVALID_HANDLE_VALUE; - static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write, - 0, 0 }; - - if (!ctx || !name || !argv || !argv[0]) - return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); - - fix_signals (); - - sprintf (mypidstr, "%lu", (unsigned long)getpid ()); - - /* Build the command line. */ - if (build_w32_commandline (ctx, argv, &cmdline)) - return _assuan_error (ctx, gpg_err_code_from_syserror ()); - - /* Create thew two pipes. */ - if (create_inheritable_pipe (ctx, rp, 0)) From cvs at cvs.gnupg.org Fri Oct 16 20:27:13 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 16 Oct 2009 20:27:13 +0200 Subject: [svn] dirmngr - r327 - in trunk: . src Message-ID: Author: marcus Date: 2009-10-16 20:27:13 +0200 (Fri, 16 Oct 2009) New Revision: 327 Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/dirmngr.c Log: 2009-10-16 Marcus Brinkmann * configure.ac: Test for libassuan instead of libassuan-pth. src/ 2009-10-16 Marcus Brinkmann * Makefile.am: (dirmngr_LDADD): Link to $(LIBASSUAN_LIBS) instead of $(LIBASSUAN_PTH_LIBS). * dirmngr.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. (main): Call assuan_set_system_hooks and assuan_sock_init. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-09-22 23:15:15 UTC (rev 326) +++ trunk/ChangeLog 2009-10-16 18:27:13 UTC (rev 327) @@ -1,3 +1,7 @@ +2009-10-16 Marcus Brinkmann + + * configure.ac: Test for libassuan instead of libassuan-pth. + 2009-09-22 Marcus Brinkmann * configure.ac (NEED_LIBASSUAN_API, NEED_LIBASSUAN_VERSION): Bump Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-09-22 23:15:15 UTC (rev 326) +++ trunk/src/ChangeLog 2009-10-16 18:27:13 UTC (rev 327) @@ -1,3 +1,10 @@ +2009-10-16 Marcus Brinkmann + + * Makefile.am: (dirmngr_LDADD): Link to $(LIBASSUAN_LIBS) instead + of $(LIBASSUAN_PTH_LIBS). + * dirmngr.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. + (main): Call assuan_set_system_hooks and assuan_sock_init. + 2009-09-22 Marcus Brinkmann * dirmngr.c (main): Update to new Assuan interface. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-09-22 23:15:15 UTC (rev 326) +++ trunk/configure.ac 2009-10-16 18:27:13 UTC (rev 327) @@ -236,8 +236,8 @@ have_libassuan=yes,have_libassuan=no) if test "$have_libassuan" = "yes"; then have_libassuan=no - AM_PATH_LIBASSUAN_PTH("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", - have_libassuan=yes,have_libassuan=no) + AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", + have_libassuan=yes,have_libassuan=no) fi Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-09-22 23:15:15 UTC (rev 326) +++ trunk/src/Makefile.am 2009-10-16 18:27:13 UTC (rev 327) @@ -47,7 +47,7 @@ estream-printf.h validate.c validate.h exechelp.h exechelp.c \ get-path.c -dirmngr_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_PTH_LIBS) \ +dirmngr_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV) if HAVE_W32_SYSTEM Modified: trunk/src/dirmngr.c =================================================================== --- trunk/src/dirmngr.c 2009-09-22 23:15:15 UTC (rev 326) +++ trunk/src/dirmngr.c 2009-10-16 18:27:13 UTC (rev 327) @@ -253,9 +253,10 @@ static void handle_connections (assuan_fd_t listen_fd); /* Pth wrapper function definitions. */ +ASSUAN_SYSTEM_PTH_IMPL; + GCRY_THREAD_OPTION_PTH_IMPL; - static const char * my_strusage( int level ) { @@ -661,6 +662,8 @@ assuan_set_malloc_hooks (&malloc_hooks); assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_sock_init (); /* Setup I18N. */ i18n_init(); From cvs at cvs.gnupg.org Fri Oct 16 20:29:01 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 16 Oct 2009 20:29:01 +0200 Subject: [svn] GnuPG - r5180 - trunk/tools Message-ID: Author: marcus Date: 2009-10-16 20:29:01 +0200 (Fri, 16 Oct 2009) New Revision: 5180 Modified: trunk/tools/gpg-connect-agent.c Log: Somehow this slipped through. Really commit this time. 2009-09-23 Marcus Brinkmann * gpg-connect-agent.c (getinfo_pid_cb, read_and_print_response) (main): Update to new Assuan API. Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2009-10-16 13:13:00 UTC (rev 5179) +++ trunk/tools/gpg-connect-agent.c 2009-10-16 18:29:01 UTC (rev 5180) @@ -1224,7 +1224,15 @@ no_close[0] = fileno (stderr); no_close[1] = log_get_fd (); no_close[2] = -1; - rc = assuan_pipe_connect_ext (&ctx, *argv, (const char **)argv, + + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + + rc = assuan_pipe_connect_ext (ctx, *argv, argv, no_close, NULL, NULL, opt.connect_flags); if (rc) @@ -1240,7 +1248,14 @@ } else if (opt.raw_socket) { - rc = assuan_socket_connect_ext (&ctx, opt.raw_socket, 0, + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + + rc = assuan_socket_connect_ext (ctx, opt.raw_socket, 0, opt.connect_flags); if (rc) { @@ -2086,9 +2101,16 @@ { char *sockname; + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + /* Check whether we can connect at the standard socket. */ sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); - rc = assuan_socket_connect (&ctx, sockname, 0); + rc = assuan_socket_connect (ctx, sockname, 0); #ifdef HAVE_W32_SYSTEM /* If we failed to connect under Windows, we fire up the agent. */ @@ -2115,7 +2137,14 @@ /* Give the agent some time to prepare itself. */ gnupg_sleep (3); /* Now try again to connect the agent. */ - rc = assuan_socket_connect (&ctx, sockname, 0); + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + + rc = assuan_socket_connect (ctx, sockname, 0); } if (rc) rc = save_rc; @@ -2148,7 +2177,14 @@ exit (1); } - rc = assuan_socket_connect (&ctx, infostr, pid); + rc = assuan_new (&ctx); + if (rc) + { + log_error ("assuan_new failed: %s\n", gpg_strerror (rc)); + exit (1); + } + + rc = assuan_socket_connect (ctx, infostr, pid); xfree (infostr); } From cvs at cvs.gnupg.org Fri Oct 16 20:35:04 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 16 Oct 2009 20:35:04 +0200 Subject: [svn] GnuPG - r5181 - in trunk: . agent common g13 scd Message-ID: Author: marcus Date: 2009-10-16 20:35:03 +0200 (Fri, 16 Oct 2009) New Revision: 5181 Modified: trunk/ChangeLog trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/Makefile.am trunk/configure.ac trunk/g13/ChangeLog trunk/g13/Makefile.am trunk/g13/g13.c trunk/scd/ChangeLog trunk/scd/Makefile.am trunk/scd/scdaemon.c Log: 2009-10-16 Marcus Brinkmann * configure.ac: Check for libassuan instead of libassuan-pth. common/ 2009-10-16 Marcus Brinkmann * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead of LIBASSUAN_PTH_CFLAGS. scd/ 2009-10-16 Marcus Brinkmann * AM_CFLAGS, scdaemon_LDADD: Use libassuan instead of libassuan-pth. * scdaemon.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. (main): Call assuan_set_system_hooks and assuan_sock_init. g13/ 2009-10-16 Marcus Brinkmann * AM_CFLAGS, g13_LDADD: Use libassuan instead of libassuan-pth. * g13.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. (main): Call assuan_set_system_hooks. agent/ 2009-10-16 Marcus Brinkmann * gpg_agent_CFLAGS, gpg_agent_LDADD: Use libassuan instead of libassuan-pth. * gpg-agent.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. (main): Call assuan_set_system_hooks and assuan_sock_init. Fix invocation of assuan_socket_connect. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) @@ -1,3 +1,7 @@ +2009-10-16 Marcus Brinkmann + + * configure.ac: Check for libassuan instead of libassuan-pth. + 2009-10-12 Werner Koch * configure.ac: Use -O3 because newer gcc versions require that Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/agent/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) @@ -1,3 +1,11 @@ +2009-10-16 Marcus Brinkmann + + * gpg_agent_CFLAGS, gpg_agent_LDADD: Use libassuan instead of + libassuan-pth. + * gpg-agent.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. + (main): Call assuan_set_system_hooks and assuan_sock_init. + Fix invocation of assuan_socket_connect. + 2009-09-23 Werner Koch * command.c (register_commands) [HAVE_ASSUAN_SET_IO_MONITOR]: Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/common/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) @@ -1,3 +1,8 @@ +2009-10-16 Marcus Brinkmann + + * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead + of LIBASSUAN_PTH_CFLAGS. + 2009-10-13 Werner Koch * exechelp.c (gnupg_kill_process): New. Modified: trunk/g13/ChangeLog =================================================================== --- trunk/g13/ChangeLog 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/g13/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) @@ -1,5 +1,11 @@ 2009-10-16 Marcus Brinkmann + * AM_CFLAGS, g13_LDADD: Use libassuan instead of libassuan-pth. + * g13.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. + (main): Call assuan_set_system_hooks. + +2009-10-16 Marcus Brinkmann + * Makefile.am (AM_CFLAGS): Add $(KSBA_CFLAGS). (g13_LDADD): Add $(KSBA_LIBS). Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/scd/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) @@ -1,3 +1,9 @@ +2009-10-16 Marcus Brinkmann + + * AM_CFLAGS, scdaemon_LDADD: Use libassuan instead of libassuan-pth. + * scdaemon.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. + (main): Call assuan_set_system_hooks and assuan_sock_init. + 2009-09-23 Marcus Brinkmann * command.c: Include "scdaemon.h" before because of Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/agent/Makefile.am 2009-10-16 18:35:03 UTC (rev 5181) @@ -62,9 +62,9 @@ #endif -gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) +gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) gpg_agent_LDADD = $(commonpth_libs) \ - $(LIBGCRYPT_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpg_agent_LDFLAGS = $(gpg_agent_res_ldflags) gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/agent/gpg-agent.c 2009-10-16 18:35:03 UTC (rev 5181) @@ -50,7 +50,6 @@ #include "gc-opt-flags.h" #include "exechelp.h" - enum cmd_and_opt_values { aNull = 0, oCsh = 'c', @@ -276,6 +275,8 @@ static int check_for_running_agent (int silent, int mode); /* Pth wrapper function definitions. */ +ASSUAN_SYSTEM_PTH_IMPL; + GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { @@ -593,6 +594,8 @@ assuan_set_malloc_hooks (&malloc_hooks); assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_sock_init (); setup_libgcrypt_logging (); gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); @@ -2217,7 +2220,7 @@ rc = assuan_new (&ctx); if (! rc) - rc = assuan_socket_connect (&ctx, infostr, pid); + rc = assuan_socket_connect (ctx, infostr, pid); xfree (infostr); if (rc) { Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/common/Makefile.am 2009-10-16 18:35:03 UTC (rev 5181) @@ -87,7 +87,7 @@ if USE_DNS_SRV libcommonpth_a_SOURCES += srv.c endif -libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) +libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) libsimple_pwquery_a_SOURCES = \ simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/configure.ac 2009-10-16 18:35:03 UTC (rev 5181) @@ -612,8 +612,8 @@ have_libassuan=yes,have_libassuan=no) if test "$have_libassuan" = "yes"; then have_libassuan=no - AM_PATH_LIBASSUAN_PTH("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", - have_libassuan=yes,have_libassuan=no) + AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", + have_libassuan=yes,have_libassuan=no) AC_DEFINE_UNQUOTED(GNUPG_LIBASSUAN_VERSION, "$libassuan_version", [version of the libassuan library]) fi @@ -1384,7 +1384,7 @@ die=yes AC_MSG_NOTICE([[ *** -*** You need libassuan with Pth support to build this program. +*** You need libassuan to build this program. *** This library is for example available at *** ftp://ftp.gnupg.org/gcrypt/libassuan/ *** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/g13/Makefile.am 2009-10-16 18:35:03 UTC (rev 5181) @@ -25,7 +25,7 @@ include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) \ - $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) + $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) g13_SOURCES = \ g13.c g13.h \ @@ -42,6 +42,6 @@ be-truecrypt.c be-truecrypt.h g13_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/g13/g13.c 2009-10-16 18:35:03 UTC (rev 5181) @@ -204,6 +204,8 @@ /* Begin Pth wrapper functions. */ +ASSUAN_SYSTEM_PTH_IMPL; + GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { @@ -441,6 +443,7 @@ /* Prepare libassuan. */ assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); /* Setup a default control structure for command line mode. */ Modified: trunk/scd/Makefile.am =================================================================== --- trunk/scd/Makefile.am 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/scd/Makefile.am 2009-10-16 18:35:03 UTC (rev 5181) @@ -27,7 +27,7 @@ include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) \ - $(KSBA_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) + $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c @@ -42,7 +42,7 @@ scdaemon_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) @@ -60,7 +60,7 @@ #sc_copykeys_LDADD = \ # ../jnlib/libjnlib.a ../common/libcommon.a \ # ../common/libsimple-pwquery.a \ -# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ +# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ # $(LIBUSB_LIBS) \ # -lgpg-error @LIBINTL@ @DL_LIBS@ # Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-10-16 18:29:01 UTC (rev 5180) +++ trunk/scd/scdaemon.c 2009-10-16 18:35:03 UTC (rev 5181) @@ -53,7 +53,6 @@ #include "mkdtemp.h" #include "gc-opt-flags.h" - enum cmd_and_opt_values { aNull = 0, oCsh = 'c', @@ -204,6 +203,8 @@ static void handle_connections (int listen_fd); /* Pth wrapper function definitions. */ +ASSUAN_SYSTEM_PTH_IMPL; + GCRY_THREAD_OPTION_PTH_IMPL; static int fixed_gcry_pth_init (void) { @@ -410,6 +411,8 @@ assuan_set_malloc_hooks (&malloc_hooks); assuan_set_assuan_log_prefix (log_get_prefix (NULL)); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_sock_init (); setup_libgcrypt_logging (); gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); From cvs at cvs.gnupg.org Sat Oct 17 21:15:16 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Sat, 17 Oct 2009 21:15:16 +0200 Subject: [svn] GnuPG - r5182 - trunk/g13 Message-ID: Author: wk Date: 2009-10-17 21:15:15 +0200 (Sat, 17 Oct 2009) New Revision: 5182 Modified: trunk/g13/ChangeLog trunk/g13/Makefile.am trunk/g13/call-gpg.c trunk/g13/g13.c trunk/g13/g13.h trunk/g13/server.c Log: Removed audit.h cruft which forced us to link against libksba. There is no need for an audit file. Modified: trunk/g13/ChangeLog =================================================================== --- trunk/g13/ChangeLog 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/ChangeLog 2009-10-17 19:15:15 UTC (rev 5182) @@ -1,11 +1,3 @@ -2009-10-16 Marcus Brinkmann - * AM_CFLAGS, g13_LDADD: Use libassuan instead of libassuan-pth. - * g13.c: Invoke ASSUAN_SYSTEM_PTH_IMPL. - (main): Call assuan_set_system_hooks. + Under initial development - no need for a ChangeLog. -2009-10-16 Marcus Brinkmann - - * Makefile.am (AM_CFLAGS): Add $(KSBA_CFLAGS). - (g13_LDADD): Add $(KSBA_LIBS). - Modified: trunk/g13/Makefile.am =================================================================== --- trunk/g13/Makefile.am 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/Makefile.am 2009-10-17 19:15:15 UTC (rev 5182) @@ -24,8 +24,7 @@ include $(top_srcdir)/am/cmacros.am -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) \ - $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) g13_SOURCES = \ g13.c g13.h \ @@ -42,6 +41,6 @@ be-truecrypt.c be-truecrypt.h g13_LDADD = $(libcommonpth) ../jnlib/libjnlib.a ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) Modified: trunk/g13/call-gpg.c =================================================================== --- trunk/g13/call-gpg.c 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/call-gpg.c 2009-10-17 19:15:15 UTC (rev 5182) @@ -100,12 +100,6 @@ /* Connect to GPG and perform initial handshaking. */ err = assuan_pipe_connect (ctx, opt.gpg_program, argv, no_close_list); - - /* if (!err) */ - /* err = assuan_transact (ctx, "OPTION audit-events=1", */ - /* NULL, NULL, NULL, NULL, NULL, NULL); */ - /* audit_log_ok (ctrl->audit, AUDIT_GPG_READY, err); */ - if (err) { assuan_release (ctx); Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/g13.c 2009-10-17 19:15:15 UTC (rev 5182) @@ -123,8 +123,6 @@ ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), - ARGPARSE_s_s (oAuditLog, "audit-log", - N_("|FILE|write an audit log to FILE")), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")), @@ -350,7 +348,6 @@ int no_more_options = 0; int default_config =1; char *logfile = NULL; - char *auditlog = NULL; int greeting = 0; int nogreeting = 0; int debug_wait = 0; @@ -359,7 +356,6 @@ int nokeysetup = 0; enum cmd_and_opt_values cmd = 0; struct server_control_s ctrl; - estream_t auditfp = NULL; strlist_t recipients = NULL; /*mtrace();*/ @@ -526,8 +522,6 @@ case oLogFile: logfile = pargs.r.ret_str; break; case oNoLogFile: logfile = NULL; break; - case oAuditLog: auditlog = pargs.r.ret_str; break; - case oNoDetach: nodetach = 1; break; case oDebug: debug_value |= pargs.r.ret_ulong; break; @@ -750,15 +744,6 @@ if (!err) join_idle_task (); - /* 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. */ g13_exit (0); return 8; /*NOTREACHED*/ Modified: trunk/g13/g13.h =================================================================== --- trunk/g13/g13.h 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/g13.h 2009-10-17 19:15:15 UTC (rev 5182) @@ -29,7 +29,6 @@ #include "../common/util.h" #include "../common/status.h" #include "../common/estream.h" -#include "../common/audit.h" #include "../common/session-env.h" /* A large struct named "opt" to keep global flags. */ @@ -91,7 +90,6 @@ int status_fd; /* Only for non-server mode */ 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. */ Modified: trunk/g13/server.c =================================================================== --- trunk/g13/server.c 2009-10-16 18:35:03 UTC (rev 5181) +++ trunk/g13/server.c 2009-10-17 19:15:15 UTC (rev 5182) @@ -167,12 +167,6 @@ { err = session_env_setenv (opt.session_env, "PINENTRY_USER_DATA", value); } - else if (!strcmp (key, "enable-audit-log")) - { - /* This is not yet used. */ - /* int i = *value? atoi (value) : 0; */ - /* ctrl->server_local->enable_audit_log = i; */ - } else if (!strcmp (key, "allow-pinentry-notify")) { ; /* We always allow it. */ From cvs at cvs.gnupg.org Mon Oct 19 11:18:47 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 19 Oct 2009 11:18:47 +0200 Subject: [svn] GnuPG - r5183 - in trunk: doc g10 g13 jnlib sm Message-ID: Author: wk Date: 2009-10-19 11:18:46 +0200 (Mon, 19 Oct 2009) New Revision: 5183 Modified: trunk/doc/gpgsm.texi trunk/g10/ChangeLog trunk/g10/mainproc.c trunk/g10/options.h trunk/g10/server.c trunk/g13/call-gpg.c trunk/g13/call-gpg.h trunk/g13/create.c trunk/g13/create.h trunk/g13/g13.c trunk/g13/server.c trunk/jnlib/ChangeLog trunk/jnlib/strlist.c trunk/jnlib/strlist.h trunk/sm/ChangeLog trunk/sm/gpgsm.c Log: [g13] Add RECIPEINT and CREATE command. [sm] Chnage --include-certs default Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g10/ChangeLog 2009-10-19 09:18:46 UTC (rev 5183) @@ -1,3 +1,9 @@ +2009-10-19 Werner Koch + + * options.h (glo_ctrl): Add field LASTERR. + * mainproc.c (proc_encrypted): Set LASTERR. + * server.c (cmd_decrypt): Check LASTERR. + 2009-10-02 Werner Koch * server.c (cmd_encrypt, cmd_decrypt): Implement. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/jnlib/ChangeLog 2009-10-19 09:18:46 UTC (rev 5183) @@ -1,3 +1,7 @@ +2009-10-19 Werner Koch + + * strlist.c (add_to_strlist_try): New. + 2009-09-22 Werner Koch * dotlock.h (DOTLOCK): Rename to dotlock_t. Change all users. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/sm/ChangeLog 2009-10-19 09:18:46 UTC (rev 5183) @@ -1,3 +1,9 @@ +2009-10-16 Werner Koch + + * gpgsm.c (default_include_certs): Change to -2. + (DEFAULT_INCLUDE_CERTS): New. + (DEFAULT_CIPHER_ALGO): New. Use instead of hardcoded "3DES". + 2009-09-30 Werner Koch * gpgsm.c (main): Remove obsolete GCRYCTL_DISABLE_INTERNAL_LOCKING. Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/doc/gpgsm.texi 2009-10-19 09:18:46 UTC (rev 5183) @@ -560,8 +560,8 @@ -1 includes all certs, 0 does not include any certs, 1 includes only the signers cert (this is the default) and all other positive values include up to @var{n} certificates starting with the signer cert. +The default is -2. - @item --cipher-algo @var{oid} @opindex cipher-algo Use the cipher algorithm with the ASN.1 object identifier @var{oid} for Modified: trunk/g10/mainproc.c =================================================================== --- trunk/g10/mainproc.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g10/mainproc.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -581,6 +581,7 @@ } } else if( result == G10ERR_BAD_SIGN ) { + glo_ctrl.lasterr = result; log_error(_("WARNING: encrypted message has been manipulated!\n")); write_status( STATUS_BADMDC ); write_status( STATUS_DECRYPTION_FAILED ); @@ -593,6 +594,7 @@ c->dek->s2k_cacheid); passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0); } + glo_ctrl.lasterr = result; write_status( STATUS_DECRYPTION_FAILED ); log_error(_("decryption failed: %s\n"), g10_errstr(result)); /* Hmmm: does this work when we have encrypted using multiple Modified: trunk/g10/options.h =================================================================== --- trunk/g10/options.h 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g10/options.h 2009-10-19 09:18:46 UTC (rev 5183) @@ -257,6 +257,11 @@ struct { int in_auto_key_retrieve; /* True if we are doing an auto_key_retrieve. */ + /* Hack to store the last error. We currently need it because the + proc_packet machinery is not able to reliabale return error + codes. Thus for the --server purposes we store some of the error + codes here. FIXME! */ + gpg_error_t lasterr; } glo_ctrl; #define DBG_PACKET_VALUE 1 /* debug packet reading/writing */ Modified: trunk/g10/server.c =================================================================== --- trunk/g10/server.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g10/server.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -362,7 +362,10 @@ if (out_fd == -1) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); + glo_ctrl.lasterr = 0; err = decrypt_message_fd (inp_fd, out_fd); + if (!err) + err = glo_ctrl.lasterr; /* Close and reset the fds. */ close_message_fd (ctrl); Modified: trunk/g13/call-gpg.c =================================================================== --- trunk/g13/call-gpg.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/call-gpg.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -43,7 +43,7 @@ gpg_error_t err; assuan_context_t ctx = NULL; const char *pgmname; - const char *argv[7]; + const char *argv[10]; int no_close_list[5]; int i; char line[ASSUAN_LINELENGTH]; @@ -86,6 +86,8 @@ argv[i++] = "--debug=1024"; argv[i++] = "-z"; argv[i++] = "0"; + argv[i++] = "--trust-model"; + argv[i++] = "always"; argv[i++] = NULL; i = 0; @@ -326,7 +328,7 @@ */ gpg_error_t gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, - void **r_ciph, size_t *r_ciphlen) + strlist_t keys, void **r_ciph, size_t *r_ciphlen) { gpg_error_t err; assuan_context_t ctx; @@ -336,6 +338,8 @@ pth_t reader_tid = NULL; gpg_error_t writer_err, reader_err; membuf_t reader_mb; + char line[ASSUAN_LINELENGTH]; + strlist_t sl; *r_ciph = NULL; *r_ciphlen = 0; @@ -376,13 +380,16 @@ outbound_fds[0] = -1; /* The thread owns the FD now. */ /* Run the encryption. */ - err = assuan_transact (ctx, "RECIPIENT alpha at example.net", - NULL, NULL, NULL, NULL, NULL, NULL); - if (err) + for (sl = keys; sl; sl = sl->next) { - log_error ("the engine's RECIPIENT command failed: %s <%s>\n", + snprintf (line, sizeof line, "RECIPIENT -- %s", sl->d); + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + { + log_error ("the engine's RECIPIENT command failed: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); - goto leave; + goto leave; + } } err = assuan_transact (ctx, "ENCRYPT", NULL, NULL, NULL, NULL, NULL, NULL); Modified: trunk/g13/call-gpg.h =================================================================== --- trunk/g13/call-gpg.h 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/call-gpg.h 2009-10-19 09:18:46 UTC (rev 5183) @@ -22,6 +22,7 @@ gpg_error_t gpg_encrypt_blob (ctrl_t ctrl, const void *plain, size_t plainlen, + strlist_t keys, void **r_ciph, size_t *r_ciphlen); gpg_error_t gpg_decrypt_blob (ctrl_t ctrl, const void *ciph, size_t ciphlen, void **r_plain, size_t *r_plainlen); Modified: trunk/g13/create.c =================================================================== --- trunk/g13/create.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/create.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -106,12 +106,13 @@ concatenation of both with the CMS packet being the last. */ static gpg_error_t encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen, + strlist_t keys, void **r_encblob, size_t *r_encbloblen) { gpg_error_t err; /* FIXME: For now we only implement OpenPGP. */ - err = gpg_encrypt_blob (ctrl, keyblob, keybloblen, + err = gpg_encrypt_blob (ctrl, keyblob, keybloblen, keys, r_encblob, r_encbloblen); return err; @@ -217,10 +218,11 @@ /* Create a new container under the name FILENAME and intialize it - using the current settings. If the file already exists an error is - returned. */ + using the current settings. KEYS is a list of public keys to which + the container will be encrypted. If the file already exists an + error is returned. */ gpg_error_t -g13_create_container (ctrl_t ctrl, const char *filename) +g13_create_container (ctrl_t ctrl, const char *filename, strlist_t keys) { gpg_error_t err; dotlock_t lock; @@ -233,6 +235,9 @@ tupledesc_t tuples = NULL; unsigned int dummy_rid; + if (!keys) + return gpg_error (GPG_ERR_NO_PUBKEY); + /* A quick check to see that no container with that name already exists. */ if (!access (filename, F_OK)) @@ -284,7 +289,7 @@ goto leave; /* Encrypt that keyblob. */ - err = encrypt_keyblob (ctrl, keyblob, keybloblen, + err = encrypt_keyblob (ctrl, keyblob, keybloblen, keys, &enckeyblob, &enckeybloblen); if (err) goto leave; Modified: trunk/g13/create.h =================================================================== --- trunk/g13/create.h 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/create.h 2009-10-19 09:18:46 UTC (rev 5183) @@ -20,7 +20,8 @@ #ifndef G13_CREATE_H #define G13_CREATE_H -gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename); +gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename, + strlist_t keys); #endif /*G13_CREATE_H*/ Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/g13.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -47,6 +47,7 @@ aNull = 0, oQuiet = 'q', oVerbose = 'v', + oRecipient = 'r', aGPGConfList = 500, aGPGConfTest, @@ -91,8 +92,6 @@ oDryRun, oNoDetach, - oRecipient, - oNoRandomSeedFile, oFakedSystemTime }; @@ -308,30 +307,6 @@ } -/* Helper to add recipients to a list. */ -static int -add_encryption_key (ctrl_t ctrl, const char *name, - void /*FIXME*/ *keylist, int is_cms) -{ - /* FIXME: Decide whether to add a CMS or OpenPGP key and then add - the key to a list. */ - /* int rc = foo_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to); */ - /* if (rc) */ - /* { */ - /* if (recp_required) */ - /* { */ - /* log_error ("can't encrypt to `%s': %s\n", name, gpg_strerror (rc)); */ - /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ - /* get_inv_recpsgnr_code (rc), name, NULL); */ - /* } */ - /* else */ - /* log_info (_("NOTE: won't be able to encrypt to `%s': %s\n"), */ - /* name, gpg_strerror (rc)); */ - /* } */ - return 0; /* Key is good. */ -} - - int main ( int argc, char **argv) { @@ -664,18 +639,20 @@ /* Parse all given encryption keys. This does a lookup of the keys and stops if any of the given keys was not found. */ +#if 0 /* Currently not implemented. */ if (!nokeysetup) { strlist_t sl; int failed = 0; for (sl = recipients; sl; sl = sl->next) - if (add_encryption_key (&ctrl, sl->d, NULL /* FIXME*/, 0)) + if (check_encryption_key ()) failed = 1; if (failed) g13_exit (1); } - +#endif /*0*/ + /* Dispatch command. */ switch (cmd) { @@ -715,7 +692,7 @@ if (argc != 1) wrong_args ("--create filename"); start_idle_task (); - err = g13_create_container (&ctrl, argv[0]); + err = g13_create_container (&ctrl, argv[0], recipients); if (err) log_error ("error creating a new container: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); Modified: trunk/g13/server.c =================================================================== --- trunk/g13/server.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/g13/server.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -29,10 +29,10 @@ #include #include "i18n.h" #include "keyblob.h" -#include "./server.h" -#include "./mount.h" +#include "server.h" +#include "mount.h" +#include "create.h" - /* Local data for this server module. A pointer to this is stored in the CTRL object of each connection. */ struct server_local_s @@ -42,6 +42,7 @@ char *containername; /* Malloced active containername. */ + strlist_t recipients; /* List of recipients. */ }; @@ -187,6 +188,8 @@ xfree (ctrl->server_local->containername); ctrl->server_local->containername = NULL; + FREE_STRLIST (ctrl->server_local->recipients); + assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); } @@ -359,18 +362,13 @@ cmd_recipient (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; + gpg_error_t err = 0; - (void)ctrl; - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ - /* &ctrl->server_local->recplist, 0); */ - /* if (err) */ - /* { */ - /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ - /* get_inv_recpsgnr_code (rc), line, NULL); */ - /* } */ + line = skip_options (line); + if (!add_to_strlist_try (&ctrl->server_local->recipients, line)) + err = gpg_error_from_syserror (); + return leave_cmd (ctx, err); } @@ -386,6 +384,7 @@ gpg_error_t err; (void)ctrl; + (void)line; err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); return leave_cmd (ctx, err); @@ -402,16 +401,50 @@ { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; + char *p, *pend; + size_t len; - (void)ctrl; - /* First we close the active container. */ xfree (ctrl->server_local->containername); ctrl->server_local->containername = NULL; + /* Parse the line. */ + line = skip_options (line); + for (p=line; *p && !spacep (p); p++) + ; + pend = p; + while (spacep(p)) + p++; + if (*p || pend == line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + *pend = 0; + /* Unescape the line and check for embedded Nul bytes. */ + len = percent_plus_unescape_inplace (line, 0); + line[len] = 0; + if (!len || memchr (line, 0, len)) + { + err = gpg_error (GPG_ERR_INV_NAME); + goto leave; + } - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* Create container. */ + err = g13_create_container (ctrl, line, ctrl->server_local->recipients); + + if (!err) + { + FREE_STRLIST (ctrl->server_local->recipients); + + /* Store the filename. */ + ctrl->server_local->containername = xtrystrdup (line); + if (!ctrl->server_local->containername) + err = gpg_error_from_syserror (); + + } + leave: return leave_cmd (ctx, err); } @@ -617,6 +650,7 @@ log_info ("Assuan accept problem: %s\n", gpg_strerror (err)); leave: + reset_notify (ctx); /* Release all items hold by SERVER_LOCAL. */ if (ctrl->server_local) { xfree (ctrl->server_local); Modified: trunk/jnlib/strlist.c =================================================================== --- trunk/jnlib/strlist.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/jnlib/strlist.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -57,6 +57,25 @@ } +/* Add STRING to the LIST at the front. This function returns NULL + and sets ERRNO on memory shortage. */ +strlist_t +add_to_strlist_try (strlist_t *list, const char *string) +{ + strlist_t sl; + + sl = jnlib_malloc (sizeof *sl + strlen (string)); + if (sl) + { + sl->flags = 0; + strcpy (sl->d, string); + sl->next = *list; + *list = sl; + } + return sl; +} + + /* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion to UTF-8 is done. This function terminates the process on memory shortage. */ Modified: trunk/jnlib/strlist.h =================================================================== --- trunk/jnlib/strlist.h 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/jnlib/strlist.h 2009-10-19 09:18:46 UTC (rev 5183) @@ -30,6 +30,7 @@ void free_strlist (strlist_t sl); strlist_t add_to_strlist (strlist_t *list, const char *string); +strlist_t add_to_strlist_try (strlist_t *list, const char *string); strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2009-10-17 19:15:15 UTC (rev 5182) +++ trunk/sm/gpgsm.c 2009-10-19 09:18:46 UTC (rev 5183) @@ -402,13 +402,26 @@ /* Option --enable-special-filenames */ static int allow_special_filenames; -/* Default value for include-certs. */ -static int default_include_certs = 1; /* Only include the signer's cert. */ +/* Default value for include-certs. We need an extra macro for + gpgconf-list because the variable will be changed by the command + line option. + It is often cumbersome to locate intermediate certificates, thus by + default we include all certificates in the chain. However we leave + out the root certificate because that would make it too easy for + the recipient to import that root certificate. A root certificate + should be installed only after due checks and thus it won't help to + send it along with each message. */ +#define DEFAULT_INCLUDE_CERTS -2 /* Include all certs but root. */ +static int default_include_certs = DEFAULT_INCLUDE_CERTS; + /* Whether the chain mode shall be used for validation. */ static int default_validation_model; +/* The default cipher algo. */ +#define DEFAULT_CIPHER_ALGO "3DES" /*des-EDE3-CBC*/ + static char *build_list (const char *text, const char *(*mapf)(int), int (*chkf)(int)); static void set_cmd (enum cmd_and_opt_values *ret_cmd, @@ -897,7 +910,7 @@ /* Note: If you change this default cipher algorithm , please remember to update the Gpgconflist entry as well. */ - opt.def_cipher_algoid = "3DES"; /*des-EDE3-CBC*/ + opt.def_cipher_algoid = DEFAULT_CIPHER_ALGO; opt.homedir = default_homedir (); @@ -1606,14 +1619,16 @@ printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE); printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE); printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE); - printf ("include-certs:%lu:1:\n", GC_OPT_FLAG_DEFAULT); + printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, + DEFAULT_INCLUDE_CERTS); printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #ifndef HAVE_W32_SYSTEM printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #endif - printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT); + printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, + DEFAULT_CIPHER_ALGO); printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); From cvs at cvs.gnupg.org Mon Oct 19 19:36:24 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 19 Oct 2009 19:36:24 +0200 Subject: [svn] assuan - r310 - trunk/src Message-ID: Author: marcus Date: 2009-10-19 19:36:24 +0200 (Mon, 19 Oct 2009) New Revision: 310 Modified: trunk/src/ChangeLog trunk/src/system.c Log: 2009-10-19 Marcus Brinkmann * system.c (__assuan_waitpid): Return something. (_assuan_usleep): Don't return value in void function. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-16 18:24:46 UTC (rev 309) +++ trunk/src/ChangeLog 2009-10-19 17:36:24 UTC (rev 310) @@ -1,3 +1,8 @@ +2009-10-19 Marcus Brinkmann + + * system.c (__assuan_waitpid): Return something. + (_assuan_usleep): Don't return value in void function. + 2009-10-16 Marcus Brinkmann * conversion.c: Do not include and . Modified: trunk/src/system.c =================================================================== --- trunk/src/system.c 2009-10-16 18:24:46 UTC (rev 309) +++ trunk/src/system.c 2009-10-19 17:36:24 UTC (rev 310) @@ -158,7 +158,7 @@ TRACE1 (ctx, ASSUAN_LOG_SYSIO, "_assuan_usleep", ctx, "usec=%u", usec); - return (ctx->system.usleep) (ctx, usec); + (ctx->system.usleep) (ctx, usec); } @@ -820,6 +820,7 @@ #else /* ! HAVE_W32_SYSTEM */ CloseHandle ((HANDLE) pid); #endif /* HAVE_W32_SYSTEM */ + return 0; } From cvs at cvs.gnupg.org Tue Oct 20 07:03:19 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 20 Oct 2009 07:03:19 +0200 Subject: [svn] GnuPG - r5184 - trunk/doc Message-ID: Author: dshaw Date: 2009-10-20 07:03:16 +0200 (Tue, 20 Oct 2009) New Revision: 5184 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi Log: * gpg.texi (GPG Configuration Options): Clarify that ca-cert-file is a generic store, the details of which depend on the underlying libraries. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-10-19 09:18:46 UTC (rev 5183) +++ trunk/doc/ChangeLog 2009-10-20 05:03:16 UTC (rev 5184) @@ -1,3 +1,9 @@ +2009-10-19 David Shaw + + * gpg.texi (GPG Configuration Options): Clarify that ca-cert-file + is a generic store, the details of which depend on the underlying + libraries. + 2009-08-24 David Shaw * gpg.texi: Suggested new ordering for --edit-key. Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-10-19 09:18:46 UTC (rev 5183) +++ trunk/doc/gpg.texi 2009-10-20 05:03:16 UTC (rev 5184) @@ -1522,10 +1522,12 @@ ldaps). Defaults to on. @item ca-cert-file -Provide a certificate file to override the system default. Only +Provide a certificate store to override the system default. Only necessary if check-cert is enabled, and the keyserver is using a certificate that is not present in a system default certificate list. +Note that depending on the SSL library that the keyserver helper is +built with, this may actually be a directory or a file. @end table @item --completes-needed @code{n} From cvs at cvs.gnupg.org Tue Oct 20 16:30:35 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 16:30:35 +0200 Subject: [svn] GnuPG - r5185 - in trunk: . g13 Message-ID: Author: marcus Date: 2009-10-20 16:30:35 +0200 (Tue, 20 Oct 2009) New Revision: 5185 Modified: trunk/ChangeLog trunk/g13/be-encfs.c Log: 2009-10-20 Marcus Brinkmann * configure.ac: Check for fusermount and encfs. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-20 05:03:16 UTC (rev 5184) +++ trunk/ChangeLog 2009-10-20 14:30:35 UTC (rev 5185) @@ -1,3 +1,7 @@ +2009-10-20 Marcus Brinkmann + + * configure.ac: Check for fusermount and encfs. + 2009-10-16 Marcus Brinkmann * configure.ac: Check for libassuan instead of libassuan-pth. Modified: trunk/g13/be-encfs.c =================================================================== --- trunk/g13/be-encfs.c 2009-10-20 05:03:16 UTC (rev 5184) +++ trunk/g13/be-encfs.c 2009-10-20 14:30:35 UTC (rev 5185) @@ -73,7 +73,7 @@ run_umount_helper (const char *mountpoint) { gpg_error_t err; - const char pgmname[] = "/usr/bin/fusermount"; + const char pgmname[] = FUSERMOUNT; const char *args[3]; args[0] = "-u"; @@ -254,7 +254,7 @@ goto leave; } - pgmname = "/usr/bin/encfs"; + pgmname = ENCFS; idx = 0; argv[idx++] = "-f"; if (opt.verbose) From cvs at cvs.gnupg.org Tue Oct 20 16:30:47 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 16:30:47 +0200 Subject: [svn] GnuPG - r5186 - trunk Message-ID: Author: marcus Date: 2009-10-20 16:30:47 +0200 (Tue, 20 Oct 2009) New Revision: 5186 Modified: trunk/configure.ac Log: 2009-10-20 Marcus Brinkmann * configure.ac: Check for fusermount and encfs. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-20 14:30:35 UTC (rev 5185) +++ trunk/configure.ac 2009-10-20 14:30:47 UTC (rev 5186) @@ -649,6 +649,16 @@ AC_SUBST(DL_LIBS) LIBS="$gnupg_dlopen_save_libs" +# Checks for g13 + +AC_PATH_PROG(ENCFS, encfs, /usr/bin/encfs) +AC_DEFINE_UNQUOTED(ENCFS, + "${ENCFS}", [defines the filename of the encfs program]) + +AC_PATH_PROG(FUSERMOUNT, fusermount, /usr/bin/fusermount) +AC_DEFINE_UNQUOTED(FUSERMOUNT, + "${FUSERMOUNT}", [defines the filename of the fusermount program]) + # # Checks for symcryptrun: # @@ -667,7 +677,6 @@ "${SHRED}", [defines the filename of the shred program]) - # # Check whether the GNU Pth library is available # Note, that we include a Pth emulation for W32. From cvs at cvs.gnupg.org Tue Oct 20 17:39:16 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 17:39:16 +0200 Subject: [svn] gpgme - r1398 - in trunk: . m4 src Message-ID: Author: marcus Date: 2009-10-20 17:39:15 +0200 (Tue, 20 Oct 2009) New Revision: 1398 Added: trunk/m4/libassuan.m4 Removed: trunk/assuan/ Modified: trunk/ChangeLog trunk/Makefile.am trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/engine-assuan.c trunk/src/engine-backend.h trunk/src/engine-gpgsm.c trunk/src/posix-io.c trunk/src/priv-io.h trunk/src/util.h Log: 2009-10-20 Marcus Brinkmann * configure.ac: Replace internal libassuan by external libassuan. * m4/libassuan.m4: New file. * Makefile.am (assuan): Remove variable. (SUBDIRS): Remove ${assuan}. * assuan/: Removed. src/ 2009-10-20 Marcus Brinkmann * Makefile.am (assuan_cppflags, assuan_libobjs): Removed. (gpgsm_components): Move engine-assuan.c to ... (assuan_components): ... this new variable. (main_sources): Add this new variable. (AM_CPPFLAGS): Remove $(assuan_cppflags). (AM_CFLAGS): Add @LIBASSUAN_CFLAGS at . (libgpgme_la_DEPENDENCIES, libgpgme_pth_la_DEPENDENCIES) (libgpgme_glib_la_DEPENDENCIES, libgpgme_qt_la_DEPENDENCIES) (libgpgme_pthread_la_DEPENDENCIES): Remove $(assuan_libobjs). (libgpgme_la_LIBADD, libgpgme_pth_la_LIBADD) (libgpgme_glib_la_LIBADD, libgpgme_qt_la_LIBADD)) (libgpgme_pthread_la_LIBADD): Replace $(assuan_libobjs) by @LIBASSUAN_LIBS at . * priv-io.h [!HAVE_W32_SYSTEM]: Declare _gpgme_io_recvmsg, _gpgme_io_sendmsg, _gpgme_io_waitpid. * engine-backend.h: Define with [ENABLE_ASSUAN] instead of [ENABLE_GPGSM]. * posix-io.c (_gpgme_io_waitpid): Make non-static. * util.h (ENABLE_ASSUAN): Declar _gpgme_assuan_system_hooks, _gpgme_assuan_malloc_hooks, _gpgme_assuan_log_cb. * engine-gpgsm.c: Don't map assuan error codes. Use assuan_release instead of assuan_disconnect. (map_assuan_error): Remove function. (gpgsm_new): Use new assuan context interface. * engine-assuan.c: Use assuan_release instead of assuan_disconnect. (llass_new): Use new assuan context interface. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/ChangeLog 2009-10-20 15:39:15 UTC (rev 1398) @@ -1,3 +1,11 @@ +2009-10-20 Marcus Brinkmann + + * configure.ac: Replace internal libassuan by external libassuan. + * m4/libassuan.m4: New file. + * Makefile.am (assuan): Remove variable. + (SUBDIRS): Remove ${assuan}. + * assuan/: Removed. + 2009-06-22 Marcus Brinkmann * configure.ac: Add AC_TYPE_UINTPTR_T. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/ChangeLog 2009-10-20 15:39:15 UTC (rev 1398) @@ -1,3 +1,33 @@ +2009-10-20 Marcus Brinkmann + + * Makefile.am (assuan_cppflags, assuan_libobjs): Removed. + (gpgsm_components): Move engine-assuan.c to ... + (assuan_components): ... this new variable. + (main_sources): Add this new variable. + (AM_CPPFLAGS): Remove $(assuan_cppflags). + (AM_CFLAGS): Add @LIBASSUAN_CFLAGS at . + (libgpgme_la_DEPENDENCIES, libgpgme_pth_la_DEPENDENCIES) + (libgpgme_glib_la_DEPENDENCIES, libgpgme_qt_la_DEPENDENCIES) + (libgpgme_pthread_la_DEPENDENCIES): Remove $(assuan_libobjs). + (libgpgme_la_LIBADD, libgpgme_pth_la_LIBADD) + (libgpgme_glib_la_LIBADD, libgpgme_qt_la_LIBADD)) + (libgpgme_pthread_la_LIBADD): Replace $(assuan_libobjs) by + @LIBASSUAN_LIBS at . + * priv-io.h [!HAVE_W32_SYSTEM]: Declare _gpgme_io_recvmsg, + _gpgme_io_sendmsg, _gpgme_io_waitpid. + * engine-backend.h: Define with [ENABLE_ASSUAN] instead + of [ENABLE_GPGSM]. + * posix-io.c (_gpgme_io_waitpid): Make non-static. + * util.h (ENABLE_ASSUAN): Declar _gpgme_assuan_system_hooks, + _gpgme_assuan_malloc_hooks, _gpgme_assuan_log_cb. + * engine-gpgsm.c: Don't map assuan error codes. Use + assuan_release instead of assuan_disconnect. + (map_assuan_error): Remove function. + (gpgsm_new): Use new assuan context interface. + * engine-assuan.c: Use assuan_release instead of + assuan_disconnect. + (llass_new): Use new assuan context interface. + 2009-10-07 * priv-io.h [W32]: Include windows.h instead of sys/socket.h. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/Makefile.am 2009-10-20 15:39:15 UTC (rev 1398) @@ -26,11 +26,6 @@ EXTRA_DIST = gpgme.spec.in autogen.sh -if BUILD_ASSUAN -assuan = assuan -else -assuan = -endif if BUILD_COMPLUS complus = complus @@ -44,7 +39,7 @@ tests = endif -SUBDIRS = ${assuan} src ${tests} doc ${complus} lang +SUBDIRS = src ${tests} doc ${complus} lang # Fix the version of the spec file and create a file named VERSION # to be used for patch's Prereq: feature. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/configure.ac 2009-10-20 15:39:15 UTC (rev 1398) @@ -188,8 +188,10 @@ AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes") + # Checks for header files. AC_CHECK_HEADERS(sys/select.h) +AC_CHECK_HEADERS([sys/uio.h]) # Type checks. @@ -219,13 +221,6 @@ fi fi -# Network library fun. -AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname, - [NETLIBS="-lnsl $NETLIBS"])) -AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt, - [NETLIBS="-lsocket $NETLIBS"])) -AC_SUBST(NETLIBS) - # Checks for library functions. AC_FUNC_FSEEKO @@ -277,8 +272,16 @@ AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME, [The default error source for GPGME.]) +# And for libassuan. +NEED_LIBASSUAN_VERSION=1.1.0 +have_libassuan=no +AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_VERSION", + have_libassuan=yes, have_libassuan=no) +AM_CONDITIONAL(HAVE_ASSUAN, test "$have_libassuan" = "yes") +if test "$have_libassuan" = "yes"; then + AC_DEFINE(ENABLE_ASSUAN,1,[Whether Assuan support is enabled]) +fi - # Checks for system services NEED_GPG_VERSION_DEFAULT=1.3.0 NEED_GPGSM_VERSION_DEFAULT=1.9.6 @@ -510,7 +513,13 @@ run_gpgsm_test=$enableval) AM_CONDITIONAL(RUN_GPGSM_TESTS, test "$run_gpgsm_test" = "yes") +# Require libassuan if GPGSM is here. +require_libassuan=no +if test "$GPGSM" != "no"; then + require_libassuan=yes +fi + NO_OVERRIDE=no AC_ARG_WITH(gpgconf, AC_HELP_STRING([--with-gpgconf=PATH], @@ -614,13 +623,6 @@ fi -# FIXME: Only build if supported. -AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no") -if test "$GPGSM" != "no"; then - AC_DEFINE(HAVE_ASSUAN_H, 1, - [Defined if we are building with assuan support.]) -fi - # Check for funopen AC_CHECK_FUNCS(funopen) if test $ac_cv_func_funopen != yes; then @@ -636,18 +638,12 @@ fi fi -# More assuan replacement functions. -AC_REPLACE_FUNCS(isascii) -AC_REPLACE_FUNCS(putc_unlocked) -AC_REPLACE_FUNCS(memrchr) +# Replacement functions. AC_REPLACE_FUNCS(stpcpy) # Check for unistd.h for setenv replacement function. AC_CHECK_HEADERS(unistd.h) AC_REPLACE_FUNCS(setenv) -# More assuan checks. -AC_CHECK_HEADERS([sys/uio.h]) - # Assuan check for descriptor passing. AC_CHECK_MEMBER(struct cmsghdr.cmsg_len, [supports_descriptor_passing=yes], @@ -684,28 +680,7 @@ AM_CONDITIONAL(USE_DESCRIPTOR_PASSING, test "$use_descriptor_passing" = "yes") -# Assuan check for the getsockopt SO_PEERCRED -AC_MSG_CHECKING(for SO_PEERCRED) -AC_CACHE_VAL(assuan_cv_sys_so_peercred, - [AC_TRY_COMPILE([#include ], - [struct ucred cr; - int cl = sizeof cr; - getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);], - assuan_cv_sys_so_peercred=yes, - assuan_cv_sys_so_peercred=no) - ]) -AC_MSG_RESULT($assuan_cv_sys_so_peercred) -if test $assuan_cv_sys_so_peercred = yes; then - AC_DEFINE(HAVE_SO_PEERCRED, 1, - [Defined if SO_PEERCRED is supported (Linux specific)]) -fi -if test "$have_w32_system" = yes; then - NETLIBS="-lws2_32 $NETLIBS" -fi - -# End of assuan checks. - AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+") # Generate values for the DLL version info @@ -753,6 +728,28 @@ sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'` AC_SUBST(LTLIBOBJS) +# Last check. +die=no +if test "$require_libassuan" = "no"; then + die=yes + AC_MSG_NOTICE([[ +*** +*** You need libassuan to build this program with GPGSM support. +*** This library is for example available at +*** ftp://ftp.gnupg.org/pub/gcrypt/alpha/libassuan/ +*** (at least version $NEED_LIBASSUAN_VERSION is required). +***]]) +fi + +if test "$die" = "yes"; then + AC_MSG_ERROR([[ +*** +*** Required libraries not found. Please consult the above messages +*** and install them before running configure again. +***]]) +fi + + # # Create config files @@ -780,6 +777,8 @@ GpgConf path: $GPGCONF GpgConf version: $GPGCONF_VERSION, min. $NEED_GPGCONF_VERSION + Assuan version: $LIBASSUAN_VERSION + GPGME Pthread: $have_pthread GPGME Pth: $have_pth " Added: trunk/m4/libassuan.m4 =================================================================== --- trunk/m4/libassuan.m4 (rev 0) +++ trunk/m4/libassuan.m4 2009-10-20 15:39:15 UTC (rev 1398) @@ -0,0 +1,79 @@ +dnl Autoconf macros for libassuan +dnl Copyright (C) 2002, 2003 Free Software Foundation, Inc. +dnl +dnl This file is free software; as a special exception the author gives +dnl unlimited permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl +dnl This file is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + +dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, +dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS +dnl +AC_DEFUN([AM_PATH_LIBASSUAN], +[ AC_ARG_WITH(libassuan-prefix, + AC_HELP_STRING([--with-libassuan-prefix=PFX], + [prefix where LIBASSUAN is installed (optional)]), + libassuan_config_prefix="$withval", libassuan_config_prefix="") + if test x$libassuan_config_prefix != x ; then + libassuan_config_args="$libassuan_config_args --prefix=$libassuan_config_prefix" + if test x${LIBASSUAN_CONFIG+set} != xset ; then + LIBASSUAN_CONFIG=$libassuan_config_prefix/bin/libassuan-config + fi + fi + + AC_PATH_PROG(LIBASSUAN_CONFIG, libassuan-config, no) + min_libassuan_version=ifelse([$1], ,0.0.1,$1) + AC_MSG_CHECKING(for LIBASSUAN - version >= $min_libassuan_version) + ok=no + if test "$LIBASSUAN_CONFIG" != "no" ; then + req_major=`echo $min_libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $min_libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $min_libassuan_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + libassuan_config_version=`$LIBASSUAN_CONFIG $libassuan_config_args --version` + major=`echo $libassuan_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $libassuan_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + micro=`echo $libassuan_config_version | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + fi + if test $ok = yes; then + LIBASSUAN_CFLAGS=`$LIBASSUAN_CONFIG $libassuan_config_args --cflags` + LIBASSUAN_LIBS=`$LIBASSUAN_CONFIG $libassuan_config_args --libs` + LIBASSUAN_VERSION="$LIBASSUAN_CONFIG_VERSION" + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + LIBASSUAN_CFLAGS="" + LIBASSUAN_LIBS="" + LIBASSUAN_VERSION="" + AC_MSG_RESULT(no) + ifelse([$3], , :, [$3]) + fi + AC_SUBST(LIBASSUAN_CFLAGS) + AC_SUBST(LIBASSUAN_LIBS) + AC_SUBST(LIBASSUAN_VERSION) +]) Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/Makefile.am 2009-10-20 15:39:15 UTC (rev 1398) @@ -60,14 +60,6 @@ libgpgme_version_script_cmd = endif -if BUILD_ASSUAN -assuan_cppflags = -I$(top_srcdir)/assuan -assuan_libobjs = ../assuan/libassuan.la -else -assuan_cppflags = -assuan_libobjs = -endif - if HAVE_DOSISH_SYSTEM system_components = w32-util.c w32-sema.c system_components_not_extra = w32-io.c @@ -77,11 +69,17 @@ endif if HAVE_GPGSM -gpgsm_components = engine-gpgsm.c engine-assuan.c +gpgsm_components = engine-gpgsm.c else gpgsm_components = endif +if HAVE_ASSUAN +assuan_components = assuan-support.c engine-assuan.c +else +assuan_components = +endif + if HAVE_GPGCONF gpgconf_components = engine-gpgconf.c else @@ -106,7 +104,8 @@ import.c export.c genkey.c delete.c edit.c getauditlog.c \ opassuan.c \ engine.h engine-backend.h engine.c engine-gpg.c status-table.h \ - $(gpgsm_components) $(gpgconf_components) gpgconf.c \ + $(gpgsm_components) $(assuan_components) $(gpgconf_components) \ + gpgconf.c \ sema.h priv-io.h $(system_components) dirinfo.c \ debug.c debug.h gpgme.c version.c error.c @@ -136,9 +135,9 @@ # We use a global CFLAGS and CPPFLAGS setting for all library # versions, because then every object file is only compiled once. -AM_CPPFLAGS = $(assuan_cppflags) @GPG_ERROR_CFLAGS@ @PTH_CPPFLAGS@ \ +AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ @PTH_CPPFLAGS@ \ @QT4_CORE_CFLAGS@ -AM_CFLAGS = @PTH_CFLAGS@ @GLIB_CFLAGS@ @QT4_CORE_CFLAGS@ +AM_CFLAGS = @LIBASSUAN_CFLAGS@ @PTH_CFLAGS@ @GLIB_CFLAGS@ @QT4_CORE_CFLAGS@ if HAVE_W32_SYSTEM @@ -185,33 +184,30 @@ libgpgme_la_LDFLAGS = $(gpgme_res_ldflag) $(no_undefined) $(export_symbols) \ $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_la_DEPENDENCIES = $(assuan_libobjs) \ - @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) -libgpgme_la_LIBADD = $(assuan_libobjs) @LTLIBOBJS@ \ +libgpgme_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) +libgpgme_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ @GPG_ERROR_LIBS@ @NETLIBS@ libgpgme_pthread_la_LDFLAGS = $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_pthread_la_DEPENDENCIES = $(assuan_libobjs) \ - @LTLIBOBJS@ $(srcdir)/libgpgme.vers -libgpgme_pthread_la_LIBADD = $(assuan_libobjs) @LTLIBOBJS@ \ +libgpgme_pthread_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers +libgpgme_pthread_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ -lpthread @GPG_ERROR_LIBS@ @NETLIBS@ libgpgme_pth_la_LDFLAGS = @PTH_LDFLAGS@ \ $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_pth_la_DEPENDENCIES = $(assuan_libobjs) \ - @LTLIBOBJS@ $(srcdir)/libgpgme.vers -libgpgme_pth_la_LIBADD = $(assuan_libobjs) @LTLIBOBJS@ \ +libgpgme_pth_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers +libgpgme_pth_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ @PTH_LIBS@ @GPG_ERROR_LIBS@ @NETLIBS@ if BUILD_W32_GLIB libgpgme_glib_la_LDFLAGS = $(gpgme_res_ldflag) $(no_undefined) \ $(export_symbols) $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_glib_la_DEPENDENCIES = $(assuan_libobjs) \ - @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) -libgpgme_glib_la_LIBADD = $(assuan_libobjs) @LTLIBOBJS@ \ +libgpgme_glib_la_DEPENDENCIES = @LTLIBOBJS@ \ + $(srcdir)/libgpgme.vers $(gpgme_deps) +libgpgme_glib_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ @GPG_ERROR_LIBS@ @GLIB_LIBS@ @NETLIBS@ endif @@ -219,9 +215,8 @@ libgpgme_qt_la_LDFLAGS = $(gpgme_res_ldflag) $(no_undefined) \ $(export_symbols) $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_qt_la_DEPENDENCIES = $(assuan_libobjs) \ - @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) -libgpgme_qt_la_LIBADD = $(assuan_libobjs) @LTLIBOBJS@ \ +libgpgme_qt_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) +libgpgme_qt_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ @GPG_ERROR_LIBS@ @QT4_CORE_LIBS@ @NETLIBS@ endif Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/engine-assuan.c 2009-10-20 15:39:15 UTC (rev 1398) @@ -161,7 +161,7 @@ if (llass->assuan_ctx) { - assuan_disconnect (llass->assuan_ctx); + assuan_release (llass->assuan_ctx); llass->assuan_ctx = NULL; } @@ -213,9 +213,12 @@ llass->opt.gpg_agent = 1; } - err = assuan_socket_connect (&llass->assuan_ctx, file_name, 0); + err = assuan_new (&llass->assuan_ctx); if (err) goto leave; + err = assuan_socket_connect (llass->assuan_ctx, file_name, 0); + if (err) + goto leave; if (llass->opt.gpg_agent) { Modified: trunk/src/engine-backend.h =================================================================== --- trunk/src/engine-backend.h 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/engine-backend.h 2009-10-20 15:39:15 UTC (rev 1398) @@ -129,7 +129,7 @@ #ifdef ENABLE_GPGCONF extern struct engine_ops _gpgme_engine_ops_gpgconf; /* gpg-conf. */ #endif -#ifdef ENABLE_GPGSM /* If this is enabled we also have assuan support. */ +#ifdef ENABLE_ASSUAN extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */ #endif Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/engine-gpgsm.c 2009-10-20 15:39:15 UTC (rev 1398) @@ -171,132 +171,6 @@ } -static gpgme_error_t -map_assuan_error (gpg_error_t err) -{ - if (!err) - return 0; - - if (err == -1) - return gpg_error (GPG_ERR_INV_ENGINE); - - /* New code will use gpg_error_t values. */ - if (gpg_err_source (err)) - return (gpgme_error_t) err; - - /* Legacy code will use old values. */ - switch (err) - { - case ASSUAN_No_Error: - return gpg_error (GPG_ERR_NO_ERROR); - case ASSUAN_General_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Out_Of_Core: - return gpg_error (GPG_ERR_ENOMEM); - case ASSUAN_Invalid_Value: - return gpg_error (GPG_ERR_INV_VALUE); - case ASSUAN_Timeout: - return gpg_error (GPG_ERR_ETIMEDOUT); - case ASSUAN_Read_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Write_Error: - return gpg_error (GPG_ERR_GENERAL); - - case ASSUAN_Problem_Starting_Server: - case ASSUAN_Not_A_Server: - case ASSUAN_Not_A_Client: - case ASSUAN_Nested_Commands: - case ASSUAN_No_Data_Callback: - case ASSUAN_No_Inquire_Callback: - case ASSUAN_Connect_Failed: - case ASSUAN_Accept_Failed: - case ASSUAN_Invalid_Command: - case ASSUAN_Unknown_Command: - case ASSUAN_Syntax_Error: - case ASSUAN_Parameter_Error: - case ASSUAN_Parameter_Conflict: - case ASSUAN_No_Input: - case ASSUAN_No_Output: - case ASSUAN_No_Data_Available: - case ASSUAN_Too_Much_Data: - case ASSUAN_Inquire_Unknown: - case ASSUAN_Inquire_Error: - case ASSUAN_Invalid_Option: - case ASSUAN_Unexpected_Status: - case ASSUAN_Unexpected_Data: - case ASSUAN_Invalid_Status: - return gpg_error (GPG_ERR_ASSUAN); - - case ASSUAN_Invalid_Response: - return gpg_error (GPG_ERR_INV_RESPONSE); - - case ASSUAN_Not_Implemented: - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - case ASSUAN_Line_Too_Long: - return gpg_error (GPG_ERR_LINE_TOO_LONG); - case ASSUAN_Line_Not_Terminated: - return gpg_error (GPG_ERR_INCOMPLETE_LINE); - case ASSUAN_Canceled: - return gpg_error (GPG_ERR_CANCELED); - - case ASSUAN_Unsupported_Algorithm: - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - case ASSUAN_Server_Resource_Problem: - return gpg_error (GPG_ERR_RESOURCE_LIMIT); - case ASSUAN_Server_IO_Error: - return gpg_error (GPG_ERR_GENERAL); - case ASSUAN_Server_Bug: - return gpg_error (GPG_ERR_BUG); - case ASSUAN_Invalid_Data: - return gpg_error (GPG_ERR_INV_DATA); - case ASSUAN_Invalid_Index: - return gpg_error (GPG_ERR_INV_INDEX); - case ASSUAN_Not_Confirmed: - return gpg_error (GPG_ERR_NOT_CONFIRMED); - case ASSUAN_Bad_Certificate: - return gpg_error (GPG_ERR_BAD_CERT); - case ASSUAN_Bad_Certificate_Chain: - return gpg_error (GPG_ERR_BAD_CERT_CHAIN); - case ASSUAN_Missing_Certificate: - return gpg_error (GPG_ERR_MISSING_CERT); - case ASSUAN_Bad_Signature: - return gpg_error (GPG_ERR_BAD_SIGNATURE); - case ASSUAN_No_Agent: - return gpg_error (GPG_ERR_NO_AGENT); - case ASSUAN_Agent_Error: - return gpg_error (GPG_ERR_AGENT); - case ASSUAN_No_Public_Key: - return gpg_error (GPG_ERR_NO_PUBKEY); - case ASSUAN_No_Secret_Key: - return gpg_error (GPG_ERR_NO_SECKEY); - case ASSUAN_Invalid_Name: - return gpg_error (GPG_ERR_INV_NAME); - - case ASSUAN_Cert_Revoked: - return gpg_error (GPG_ERR_CERT_REVOKED); - case ASSUAN_No_CRL_For_Cert: - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - case ASSUAN_CRL_Too_Old: - return gpg_error (GPG_ERR_CRL_TOO_OLD); - case ASSUAN_Not_Trusted: - return gpg_error (GPG_ERR_NOT_TRUSTED); - - case ASSUAN_Card_Error: - return gpg_error (GPG_ERR_CARD); - case ASSUAN_Invalid_Card: - return gpg_error (GPG_ERR_INV_CARD); - case ASSUAN_No_PKCS15_App: - return gpg_error (GPG_ERR_NO_PKCS15_APP); - case ASSUAN_Card_Not_Present: - return gpg_error (GPG_ERR_CARD_NOT_PRESENT); - case ASSUAN_Invalid_Id: - return gpg_error (GPG_ERR_INV_ID); - default: - return gpg_error (GPG_ERR_GENERAL); - } -} - - /* This is the default inquiry callback. We use it to handle the Pinentry notifications. */ static gpgme_error_t @@ -330,7 +204,7 @@ if (gpgsm->assuan_ctx) { - assuan_disconnect (gpgsm->assuan_ctx); + assuan_release (gpgsm->assuan_ctx); gpgsm->assuan_ctx = NULL; } @@ -450,13 +324,20 @@ argv[argc++] = "--server"; argv[argc++] = NULL; + err = assuan_new_ext (&gpgsm->assuan_ctx, GPG_ERR_SOURCE_GPGME, + &_gpgme_assuan_malloc_hooks, _gpgme_assuan_log_cb, + NULL); + if (err) + goto leave; + assuan_ctx_set_system_hooks (gpgsm->assuan_ctx, &_gpgme_assuan_system_hooks); + #if USE_DESCRIPTOR_PASSING err = assuan_pipe_connect_ext - (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), + (gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), argv, NULL, NULL, NULL, 1); #else err = assuan_pipe_connect - (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), + (gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), argv, child_fds); /* On Windows, handles are inserted in the spawned process with @@ -504,10 +385,7 @@ NULL, NULL, NULL); free (optstr); if (err) - { - err = map_assuan_error (err); - goto leave; - } + goto leave; } if (isatty (1)) @@ -531,10 +409,7 @@ NULL, NULL, NULL); free (optstr); if (err) - { - err = map_assuan_error (err); - goto leave; - } + goto leave; err = _gpgme_getenv ("TERM", &dft_ttytype); if (err) @@ -553,10 +428,7 @@ NULL, NULL, NULL, NULL); free (optstr); if (err) - { - err = map_assuan_error (err); - goto leave; - } + goto leave; } } } @@ -662,8 +534,6 @@ err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); free (optstr); - if (err) - err = map_assuan_error (err); } return err; @@ -684,13 +554,13 @@ err = assuan_write_line (ctx, cmd); if (err) - return map_assuan_error (err); + return err; do { err = assuan_read_line (ctx, &line, &linelen); if (err) - return map_assuan_error (err); + return err; if (*line == '#' || !linelen) continue; @@ -702,7 +572,7 @@ else if (linelen >= 4 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' && line[3] == ' ') - err = map_assuan_error (atoi (&line[4])); + err = atoi (&line[4]); else if (linelen >= 2 && line[0] == 'S' && line[1] == ' ') { @@ -891,7 +761,6 @@ static gpgme_error_t status_handler (void *opaque, int fd) { - gpg_error_t assuan_err; gpgme_error_t err = 0; engine_gpgsm_t gpgsm = opaque; char *line; @@ -899,23 +768,22 @@ do { - assuan_err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen); - if (assuan_err) + err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen); + if (err) { /* Try our best to terminate the connection friendly. */ /* assuan_write_line (gpgsm->assuan_ctx, "BYE"); */ - err = map_assuan_error (assuan_err); TRACE3 (DEBUG_CTX, "gpgme:status_handler", gpgsm, "fd 0x%x: error from assuan (%d) getting status line : %s", - fd, assuan_err, gpg_strerror (err)); + fd, err, gpg_strerror (err)); } else if (linelen >= 3 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' && (line[3] == '\0' || line[3] == ' ')) { if (line[3] == ' ') - err = map_assuan_error (atoi (&line[4])); - else + err = atoi (&line[4]); + if (! err) err = gpg_error (GPG_ERR_GENERAL); TRACE2 (DEBUG_CTX, "gpgme:status_handler", gpgsm, "fd 0x%x: ERR line - mapped to: %s", @@ -1174,7 +1042,7 @@ err = add_io_cb (gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler); if (!err) - err = map_assuan_error (assuan_write_line (gpgsm->assuan_ctx, command)); + err = assuan_write_line (gpgsm->assuan_ctx, command); if (!err) gpgsm_io_event (gpgsm, GPGME_EVENT_START, NULL); Modified: trunk/src/posix-io.c =================================================================== --- trunk/src/posix-io.c 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/posix-io.c 2009-10-20 15:39:15 UTC (rev 1398) @@ -278,7 +278,7 @@ } -static int +int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal) { int status; Modified: trunk/src/priv-io.h =================================================================== --- trunk/src/priv-io.h 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/priv-io.h 2009-10-20 15:39:15 UTC (rev 1398) @@ -92,4 +92,10 @@ (in engine-gpgsm.c). */ int _gpgme_io_dup (int fd); +#ifndef HAVE_W32_SYSTEM +int _gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags); +int _gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags); +int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal); +#endif + #endif /* IO_H */ Modified: trunk/src/util.h =================================================================== --- trunk/src/util.h 2009-10-15 20:54:25 UTC (rev 1397) +++ trunk/src/util.h 2009-10-20 15:39:15 UTC (rev 1398) @@ -124,4 +124,14 @@ #define GPG_ERR_NOT_OPERATIONAL 176 #endif + +#ifdef ENABLE_ASSUAN +#include +/* System hooks for assuan integration. */ +extern struct assuan_system_hooks _gpgme_assuan_system_hooks; +extern struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks; +int _gpgme_assuan_log_cb (assuan_context_t ctx, void *hook, + unsigned int cat, const char *msg); +#endif + #endif /* UTIL_H */ From cvs at cvs.gnupg.org Tue Oct 20 17:51:00 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 17:51:00 +0200 Subject: [svn] assuan - r311 - trunk/src Message-ID: Author: marcus Date: 2009-10-20 17:50:59 +0200 (Tue, 20 Oct 2009) New Revision: 311 Modified: trunk/src/ChangeLog trunk/src/assuan.h trunk/src/libassuan.def trunk/src/libassuan.vers trunk/src/system.c Log: 2009-10-20 Marcus Brinkmann * assuan.h (__assuan_usleep): Add declaration. * system.c (__assuan_usleep): Make non-static. * libassuan.vers, libassuan.defs: Sort lexicographically. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-19 17:36:24 UTC (rev 310) +++ trunk/src/ChangeLog 2009-10-20 15:50:59 UTC (rev 311) @@ -1,3 +1,9 @@ +2009-10-20 Marcus Brinkmann + + * assuan.h (__assuan_usleep): Add declaration. + * system.c (__assuan_usleep): Make non-static. + * libassuan.vers, libassuan.defs: Sort lexicographically. + 2009-10-19 Marcus Brinkmann * system.c (__assuan_waitpid): Return something. Modified: trunk/src/assuan.h =================================================================== --- trunk/src/assuan.h 2009-10-19 17:36:24 UTC (rev 310) +++ trunk/src/assuan.h 2009-10-20 15:50:59 UTC (rev 311) @@ -459,6 +459,7 @@ void assuan_ctx_set_system_hooks (assuan_context_t ctx, assuan_system_hooks_t system_hooks); +void __assuan_usleep (assuan_context_t ctx, unsigned int usec); int __assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx); int __assuan_close (assuan_context_t ctx, assuan_fd_t fd); int __assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name, Modified: trunk/src/libassuan.def =================================================================== --- trunk/src/libassuan.def 2009-10-19 17:36:24 UTC (rev 310) +++ trunk/src/libassuan.def 2009-10-20 15:50:59 UTC (rev 311) @@ -24,76 +24,76 @@ assuan_close_input_fd @3 assuan_close_output_fd @4 assuan_command_parse_fd @5 - assuan_end_confidential @6 - assuan_get_active_fds @7 - assuan_get_assuan_log_prefix @8 - assuan_get_data_fp @9 - assuan_get_flag @10 - assuan_get_gpg_err_source @11 - assuan_get_input_fd @12 - assuan_get_log_cb @13 - assuan_get_malloc_hooks @14 - assuan_get_output_fd @15 - assuan_get_pid @16 - assuan_get_pointer @17 - assuan_init_pipe_server @18 - assuan_init_socket_server @19 - assuan_init_socket_server_ext @20 - assuan_inquire @21 - assuan_inquire_ext @22 - assuan_new @23 - assuan_new_ext @24 - assuan_pending_line @25 - assuan_pipe_connect @26 - assuan_pipe_connect_ext @27 - assuan_process @28 - assuan_process_done @29 - assuan_process_next @30 - assuan_read_line @31 - assuan_receivefd @32 - assuan_register_bye_notify @33 - assuan_register_cancel_notify @34 - assuan_register_command @35 - assuan_register_input_notify @36 - assuan_register_option_handler @37 - assuan_register_output_notify @38 - assuan_register_post_cmd_notify @39 - assuan_register_reset_notify @40 - assuan_release @41 - assuan_send_data @42 - assuan_sendfd @43 - assuan_set_assuan_log_prefix @44 - assuan_set_error @45 - assuan_set_flag @46 - assuan_set_gpg_err_source @47 - assuan_set_hello_line @48 - assuan_set_io_monitor @49 - assuan_set_log_cb @50 - assuan_set_log_stream @51 - assuan_set_malloc_hooks @52 - assuan_set_okay_line @53 - assuan_set_pointer @54 - assuan_sock_bind @55 - assuan_sock_check_nonce @56 - assuan_sock_close @57 - assuan_sock_connect @58 - assuan_sock_get_nonce @59 - assuan_sock_new @60 - assuan_socket_connect @61 - assuan_socket_connect_ext @62 - assuan_transact @63 - assuan_write_line @64 - assuan_write_status @65 - assuan_sock_init - assuan_sock_deinit - assuan_get_command_name @66 + assuan_ctx_set_system_hooks @6 + assuan_end_confidential @7 + assuan_get_active_fds @8 + assuan_get_assuan_log_prefix @9 + assuan_get_command_name @10 + assuan_get_data_fp @11 + assuan_get_flag @12 + assuan_get_gpg_err_source @13 + assuan_get_input_fd @14 + assuan_get_log_cb @15 + assuan_get_malloc_hooks @16 + assuan_get_output_fd @17 + assuan_get_pid @18 + assuan_get_pointer @19 + assuan_init_pipe_server @20 + assuan_init_socket_server @21 + assuan_init_socket_server_ext @22 + assuan_inquire @23 + assuan_inquire_ext @24 + assuan_new @25 + assuan_new_ext @26 + assuan_pending_line @27 + assuan_pipe_connect @28 + assuan_pipe_connect_ext @29 + assuan_process @30 + assuan_process_done @31 + assuan_process_next @32 + assuan_read_line @33 + assuan_receivefd @34 + assuan_register_bye_notify @35 + assuan_register_cancel_notify @36 + assuan_register_command @37 + assuan_register_input_notify @38 + assuan_register_option_handler @39 + assuan_register_output_notify @40 + assuan_register_post_cmd_notify @41 + assuan_register_reset_notify @42 + assuan_release @43 + assuan_send_data @44 + assuan_sendfd @45 + assuan_set_assuan_log_prefix @46 + assuan_set_error @47 + assuan_set_flag @48 + assuan_set_gpg_err_source @49 + assuan_set_hello_line @50 + assuan_set_io_monitor @51 + assuan_set_log_cb @52 + assuan_set_log_stream @53 + assuan_set_malloc_hooks @54 + assuan_set_okay_line @55 + assuan_set_pointer @56 + assuan_set_system_hooks @57 + assuan_sock_bind @58 + assuan_sock_check_nonce @59 + assuan_sock_close @60 + assuan_sock_connect @61 + assuan_sock_deinit @62 + assuan_sock_get_nonce @63 + assuan_sock_init @64 + assuan_sock_new @65 + assuan_socket_connect @66 + assuan_socket_connect_ext @67 + assuan_transact @68 + assuan_write_line @69 + assuan_write_status @70 + __assuan_close @71 + __assuan_pipe @72 + __assuan_socketpair @73 + __assuan_spawn @74 + __assuan_usleep @75 - __assuan_pipe - __assuan_close - __assuan_spawn - __assuan_socketpair - assuan_set_system_hooks - assuan_ctx_set_system_hooks - ; END Modified: trunk/src/libassuan.vers =================================================================== --- trunk/src/libassuan.vers 2009-10-19 17:36:24 UTC (rev 310) +++ trunk/src/libassuan.vers 2009-10-20 15:50:59 UTC (rev 311) @@ -27,13 +27,17 @@ assuan_close_input_fd; assuan_close_output_fd; assuan_command_parse_fd; + assuan_ctx_set_system_hooks; assuan_end_confidential; assuan_get_active_fds; assuan_get_assuan_log_prefix; assuan_get_command_name; assuan_get_data_fp; assuan_get_flag; + assuan_get_gpg_err_source; assuan_get_input_fd; + assuan_get_log_cb; + assuan_get_malloc_hooks; assuan_get_output_fd; assuan_get_peercred; assuan_get_pid; @@ -43,6 +47,9 @@ assuan_init_socket_server_ext; assuan_inquire; assuan_inquire_ext; + assuan_new; + assuan_new; + assuan_new_ext; assuan_pending_line; assuan_pipe_connect; assuan_pipe_connect_ext; @@ -59,46 +66,41 @@ assuan_register_output_notify; assuan_register_post_cmd_notify; assuan_register_reset_notify; + assuan_release; + assuan_release; assuan_send_data; assuan_sendfd; assuan_set_assuan_log_prefix; assuan_set_error; assuan_set_flag; + assuan_set_gpg_err_source; assuan_set_hello_line; assuan_set_io_monitor; + assuan_set_log_cb; assuan_set_log_stream; assuan_set_malloc_hooks; assuan_set_okay_line; assuan_set_pointer; + assuan_set_system_hooks; assuan_sock_bind; assuan_sock_check_nonce; assuan_sock_close; assuan_sock_connect; + assuan_sock_deinit; assuan_sock_get_nonce; + assuan_sock_init; assuan_sock_new; assuan_socket_connect; assuan_socket_connect_ext; assuan_transact; assuan_write_line; assuan_write_status; - assuan_new; - assuan_release; - assuan_set_gpg_err_source; - assuan_get_gpg_err_source; - assuan_get_malloc_hooks; - assuan_set_log_cb; - assuan_get_log_cb; - assuan_new_ext; - assuan_new; - assuan_release; - assuan_sock_init; - assuan_sock_deinit; + + __assuan_close; __assuan_pipe; - __assuan_close; + __assuan_socketpair; __assuan_spawn; - __assuan_socketpair; - assuan_set_system_hooks; - assuan_ctx_set_system_hooks; + __assuan_usleep; local: *; Modified: trunk/src/system.c =================================================================== --- trunk/src/system.c 2009-10-19 17:36:24 UTC (rev 310) +++ trunk/src/system.c 2009-10-20 15:50:59 UTC (rev 311) @@ -120,7 +120,7 @@ /* Sleep for the given number of microseconds. Default implementation. */ -static void +void __assuan_usleep (assuan_context_t ctx, unsigned int usec) { if (! usec) From cvs at cvs.gnupg.org Tue Oct 20 17:54:02 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 17:54:02 +0200 Subject: [svn] gpgme - r1399 - trunk/src Message-ID: Author: marcus Date: 2009-10-20 17:54:01 +0200 (Tue, 20 Oct 2009) New Revision: 1399 Modified: trunk/src/ChangeLog trunk/src/gpgme-config.in Log: 2009-10-20 Marcus Brinkmann * gpgme-config.in (netlibs): Remove. (assuan_cflags, assuan_libs): Add. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-20 15:39:15 UTC (rev 1398) +++ trunk/src/ChangeLog 2009-10-20 15:54:01 UTC (rev 1399) @@ -1,5 +1,8 @@ 2009-10-20 Marcus Brinkmann + * gpgme-config.in (netlibs): Remove. + (assuan_cflags, assuan_libs): Add. + * Makefile.am (assuan_cppflags, assuan_libobjs): Removed. (gpgsm_components): Move engine-assuan.c to ... (assuan_components): ... this new variable. Modified: trunk/src/gpgme-config.in =================================================================== --- trunk/src/gpgme-config.in 2009-10-20 15:39:15 UTC (rev 1398) +++ trunk/src/gpgme-config.in 2009-10-20 15:54:01 UTC (rev 1399) @@ -20,7 +20,8 @@ LANG=C # Network libraries. -netlibs="@NETLIBS@" +assuan_cflags="@LIBASSUAN_CFLAGS@" +assuan_libs="@LIBASSUAN_LIBS@" # Configure libgpg-error. gpg_error_cflags="@GPG_ERROR_CFLAGS@" @@ -112,7 +113,7 @@ output="$output $cflags_pth" ;; esac - output="$output $gpg_error_cflags" + output="$output $assuan_cflags $gpg_error_cflags" if test "x$with_glib" = "xyes"; then output="$output $glib_cflags" fi @@ -136,7 +137,7 @@ fi ;; esac - output="$output $gpg_error_libs $netlibs" + output="$output $assuan_libs $gpg_error_libs" if test "x$with_glib" = "xyes"; then output="$output $glib_cflags" fi From cvs at cvs.gnupg.org Tue Oct 20 17:54:34 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 17:54:34 +0200 Subject: [svn] gpgme - r1400 - trunk Message-ID: Author: marcus Date: 2009-10-20 17:54:34 +0200 (Tue, 20 Oct 2009) New Revision: 1400 Modified: trunk/NEWS Log: Add item on libassuan. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-20 15:54:01 UTC (rev 1399) +++ trunk/NEWS 2009-10-20 15:54:34 UTC (rev 1400) @@ -1,7 +1,10 @@ Noteworthy changes in version 1.2.1 (unreleased) ------------------------------------------------ - * (none yet) + * GPGME does not come with an internal libassuan version anymore. + The external libassuan 1.1.0 release or later is required. For + application programmers on systems that can resolve inter-library + dependencies at runtime, this is a transparent change. * Interface changes relative to the 1.1.7 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From cvs at cvs.gnupg.org Tue Oct 20 17:55:01 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 17:55:01 +0200 Subject: [svn] gpgme - r1401 - trunk Message-ID: Author: marcus Date: 2009-10-20 17:55:01 +0200 (Tue, 20 Oct 2009) New Revision: 1401 Modified: trunk/NEWS Log: Fix version number. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-20 15:54:34 UTC (rev 1400) +++ trunk/NEWS 2009-10-20 15:55:01 UTC (rev 1401) @@ -6,7 +6,7 @@ application programmers on systems that can resolve inter-library dependencies at runtime, this is a transparent change. - * Interface changes relative to the 1.1.7 release: + * Interface changes relative to the 1.2.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPGME_STATUS_INV_SGNR NEW. GPGME_STATUS_NO_SGNR NEW. From cvs at cvs.gnupg.org Tue Oct 20 18:04:06 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 18:04:06 +0200 Subject: [svn] gpgme - r1402 - trunk Message-ID: Author: marcus Date: 2009-10-20 18:04:06 +0200 (Tue, 20 Oct 2009) New Revision: 1402 Modified: trunk/ChangeLog trunk/configure.ac Log: 2009-10-20 Marcus Brinkmann * configure.ac (AC_CONFIG_FILES): Remove assuan/Makefile. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-20 15:55:01 UTC (rev 1401) +++ trunk/ChangeLog 2009-10-20 16:04:06 UTC (rev 1402) @@ -1,5 +1,9 @@ 2009-10-20 Marcus Brinkmann + * configure.ac (AC_CONFIG_FILES): Remove assuan/Makefile. + +2009-10-20 Marcus Brinkmann + * configure.ac: Replace internal libassuan by external libassuan. * m4/libassuan.m4: New file. * Makefile.am (assuan): Remove variable. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-20 15:55:01 UTC (rev 1401) +++ trunk/configure.ac 2009-10-20 16:04:06 UTC (rev 1402) @@ -753,7 +753,7 @@ # # Create config files -AC_CONFIG_FILES(Makefile assuan/Makefile src/Makefile +AC_CONFIG_FILES(Makefile src/Makefile tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile From cvs at cvs.gnupg.org Tue Oct 20 18:05:21 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 20 Oct 2009 18:05:21 +0200 Subject: [svn] gpgme - r1403 - trunk/src Message-ID: Author: marcus Date: 2009-10-20 18:05:21 +0200 (Tue, 20 Oct 2009) New Revision: 1403 Added: trunk/src/assuan-support.c Log: Really add file. From cvs at cvs.gnupg.org Wed Oct 21 16:35:24 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Wed, 21 Oct 2009 16:35:24 +0200 Subject: misc-scripts (sha1sum.c) Message-ID: Date: Wednesday, October 21, 2009 @ 16:35:24 Author: werner Path: /cvs/wk/misc-scripts Modified: sha1sum.c Add -c option + From cvs at cvs.gnupg.org Wed Oct 21 16:50:04 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Wed, 21 Oct 2009 16:50:04 +0200 Subject: misc-scripts (sha1sum.c) Message-ID: Date: Wednesday, October 21, 2009 @ 16:50:04 Author: werner Path: /cvs/wk/misc-scripts Modified: sha1sum.c Handle binary flag From cvs at cvs.gnupg.org Thu Oct 22 12:52:23 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Thu, 22 Oct 2009 12:52:23 +0200 Subject: misc-scripts (sha1sum.c) Message-ID: Date: Thursday, October 22, 2009 @ 12:52:23 Author: werner Path: /cvs/wk/misc-scripts Modified: sha1sum.c Add MD5 and SHA256 mode. Remove binary flag. From cvs at cvs.gnupg.org Thu Oct 22 18:44:08 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 22 Oct 2009 18:44:08 +0200 Subject: [svn] gpgme - r1404 - in trunk: . src Message-ID: Author: marcus Date: 2009-10-22 18:44:07 +0200 (Thu, 22 Oct 2009) New Revision: 1404 Added: trunk/src/engine-g13.c trunk/src/g13.c Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/conversion.c trunk/src/engine-assuan.c trunk/src/engine-backend.h trunk/src/engine.c trunk/src/gpgme.c trunk/src/gpgme.def trunk/src/gpgme.h.in trunk/src/libgpgme.vers trunk/src/posix-util.c trunk/src/util.h trunk/src/w32-util.c Log: 2009-10-22 Marcus Brinkmann * configure.ac: Add support for G13. src/ 2009-10-22 Marcus Brinkmann * Makefile.am: Remove @NETLIBS@ from LIBADDs. (g13_components): New variable. (main_sources): Add $(g13_components). * g13.c, engine-g13.c: New files. * engine.c (engine_ops): Check for assuan for assuan engine, add g13 engine. * util.h (_gpgme_get_g13_path, _gpgme_encode_percent_string): New prototypes. * conversion.c (_gpgme_encode_percent_string): New function. * gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_G13. (struct _gpgme_op_g13_result, gpgme_g13_result_t): New types. (gpgme_op_g13_mount): New function. * gpgme.def, libgpgme.vers: Add gpgme_op_g13_mount. * gpgme.c (gpgme_set_protocol): Allow GPGME_PROTOCOL_G13. (gpgme_get_protocol_name): Add GPGME_PROTOCOL_G13. * posix-util.c (_gpgme_get_g13_path): New function. * w32-util.c (_gpgme_get_g13_path): New function. * engine-backend.h (_gpgme_engine_ops_g13): New declaration. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/ChangeLog 2009-10-22 16:44:07 UTC (rev 1404) @@ -1,3 +1,7 @@ +2009-10-22 Marcus Brinkmann + + * configure.ac: Add support for G13. + 2009-10-20 Marcus Brinkmann * configure.ac (AC_CONFIG_FILES): Remove assuan/Makefile. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/ChangeLog 2009-10-22 16:44:07 UTC (rev 1404) @@ -1,3 +1,24 @@ +2009-10-22 Marcus Brinkmann + + * Makefile.am: Remove @NETLIBS@ from LIBADDs. + (g13_components): New variable. + (main_sources): Add $(g13_components). + * g13.c, engine-g13.c: New files. + * engine.c (engine_ops): Check for assuan for assuan engine, add + g13 engine. + * util.h (_gpgme_get_g13_path, _gpgme_encode_percent_string): New + prototypes. + * conversion.c (_gpgme_encode_percent_string): New function. + * gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_G13. + (struct _gpgme_op_g13_result, gpgme_g13_result_t): New types. + (gpgme_op_g13_mount): New function. + * gpgme.def, libgpgme.vers: Add gpgme_op_g13_mount. + * gpgme.c (gpgme_set_protocol): Allow GPGME_PROTOCOL_G13. + (gpgme_get_protocol_name): Add GPGME_PROTOCOL_G13. + * posix-util.c (_gpgme_get_g13_path): New function. + * w32-util.c (_gpgme_get_g13_path): New function. + * engine-backend.h (_gpgme_engine_ops_g13): New declaration. + 2009-10-20 Marcus Brinkmann * gpgme-config.in (netlibs): Remove. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/NEWS 2009-10-22 16:44:07 UTC (rev 1404) @@ -6,11 +6,16 @@ application programmers on systems that can resolve inter-library dependencies at runtime, this is a transparent change. + * New engine GPGME_PROTOCOL_G13 to support the new g13 tool. + * Interface changes relative to the 1.2.0 release: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GPGME_STATUS_INV_SGNR NEW. - GPGME_STATUS_NO_SGNR NEW. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GPGME_STATUS_INV_SGNR NEW +GPGME_STATUS_NO_SGNR NEW +GPGME_PROTOCOL_G13 NEW +gpgme_op_g13_mount NEW +gpgme_g13_result_t NEW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Noteworthy changes in version 1.2.0 (2009-06-18) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/configure.ac 2009-10-22 16:44:07 UTC (rev 1404) @@ -120,6 +120,7 @@ GPG_DEFAULT=no GPGSM_DEFAULT=no GPGCONF_DEFAULT=no +G13_DEFAULT=no component_system=None have_dosish_system=no have_w32_system=no @@ -133,6 +134,7 @@ GPG_DEFAULT='c:\\gnupg\\gpg.exe' GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe' GPGCONF_DEFAULT='c:\\gnupg\\gpgconf.exe' + G13_DEFAULT='c:\\gnupg\\g13.exe' #component_system='COM+' AM_PATH_GLIB_2_0 @@ -166,6 +168,7 @@ # GPG_DEFAULT='/usr/bin/gpg' # GPGSM_DEFAULT='/usr/bin/gpgsm' # GPGCONF_DEFAULT='/usr/bin/gpgconf' +# G13_DEFAULT='/usr/bin/g13' ;; esac @@ -286,9 +289,11 @@ NEED_GPG_VERSION_DEFAULT=1.3.0 NEED_GPGSM_VERSION_DEFAULT=1.9.6 NEED_GPGCONF_VERSION_DEFAULT=2.0.4 +NEED_G13_VERSION_DEFAULT=2.1.0 NEED_GPG_VERSION="$NEED_GPG_VERSION_DEFAULT" NEED_GPGSM_VERSION="$NEED_GPGSM_VERSION_DEFAULT" NEED_GPGCONF_VERSION="$NEED_GPGCONF_VERSION_DEFAULT" +NEED_G13_VERSION="$NEED_G13_VERSION_DEFAULT" AC_ARG_WITH(gpg-version, AC_HELP_STRING([--with-gpg-version=VER], [require GnuPG version VER]), NEED_GPG_VERSION=$withval) @@ -316,6 +321,15 @@ if test "$NEED_GPGCONF_VERSION" = "no"; then NEED_GPGCONF_VERSION=0.0.0 fi +AC_ARG_WITH(g13-version, + AC_HELP_STRING([--with-g13-version=VER], [require G13 version VER]), + NEED_G13_VERSION=$withval) +if test "$NEED_G13_VERSION" = "yes"; then + NEED_G13_VERSION="$NEED_G13_VERSION_DEFAULT" +fi +if test "$NEED_G13_VERSION" = "no"; then + NEED_G13_VERSION=0.0.0 +fi AC_DEFINE_UNQUOTED(NEED_GPG_VERSION, "$NEED_GPG_VERSION", [Min. needed GnuPG version.]) @@ -323,6 +337,8 @@ [Min. needed GPGSM version.]) AC_DEFINE_UNQUOTED(NEED_GPGCONF_VERSION, "$NEED_GPGCONF_VERSION", [Min. needed GPGCONF version.]) +AC_DEFINE_UNQUOTED(NEED_G13_VERSION, "$NEED_G13_VERSION", + [Min. needed G13 version.]) NO_OVERRIDE=no @@ -518,6 +534,9 @@ if test "$GPGSM" != "no"; then require_libassuan=yes fi +if test "$G13" != "no"; then + require_libassuan=yes +fi NO_OVERRIDE=no @@ -623,6 +642,109 @@ fi +NO_OVERRIDE=no +AC_ARG_WITH(g13, + AC_HELP_STRING([--with-g13=PATH], + [use g13 binary at PATH]), + G13=$withval, NO_OVERRIDE=yes) +if test "$NO_OVERRIDE" = "yes" || test "$G13" = "yes"; then + G13= + NO_OVERRIDE=yes + if test "$cross_compiling" != "yes"; then + AC_PATH_PROG(G13, g13) + fi + if test -z "$G13"; then + G13="$G13_DEFAULT" + fi +fi +if test "$G13" = no; then + if test "$NO_OVERRIDE" = "yes"; then + if test "$cross_compiling" != "yes"; then + AC_MSG_WARN([ +*** +*** Could not find g13, install g13 or use --with-g13=PATH to enable it +***]) + else + AC_MSG_ERROR([ +*** +*** Can not determine path to g13 when cross-compiling, use --with-g13=PATH +***]) + fi + fi +else + AC_DEFINE_UNQUOTED(G13_PATH, "$G13", [Path to the G13 binary.]) + AC_DEFINE(ENABLE_G13,1,[Whether G13 support is enabled]) +fi +AM_CONDITIONAL(HAVE_G13, test "$G13" != "no") + +dnl Check for G13 version requirement. +G13_VERSION=unknown +ok=maybe +if test -z "$G13" -o "x$G13" = "xno"; then + ok=no +else + if test "$cross_compiling" = "yes"; then + AC_MSG_WARN([G13 version can not be checked when cross compiling]) + ok=no + else + if test ! -x "$G13"; then + AC_MSG_WARN([G13 not executable, version check disabled]) + ok=no + fi + fi +fi +if test "$ok" = "maybe"; then + AC_MSG_CHECKING(for G13 >= $NEED_G13_VERSION) + req_major=`echo $NEED_G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + req_minor=`echo $NEED_G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + req_micro=`echo $NEED_G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + G13_VERSION=`$G13 --version | sed -n '1 s/.*\ \([[0-9]].*\)/\1/p'` + major=`echo $G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + minor=`echo $G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + micro=`echo $G13_VERSION | \ + sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + + if test "$major" -gt "$req_major"; then + ok=yes + else + if test "$major" -eq "$req_major"; then + if test "$minor" -gt "$req_minor"; then + ok=yes + else + if test "$minor" -eq "$req_minor"; then + if test "$micro" -ge "$req_micro"; then + ok=yes + fi + fi + fi + fi + fi + if test "$ok" = "yes"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_WARN([G13 must be at least version $NEED_G13_VERSION]) + fi +fi +run_g13_test="$ok" +AC_ARG_ENABLE(g13-test, + AC_HELP_STRING([--disable-g13-test], [disable G13 run test]), + run_g13_test=$enableval) +AM_CONDITIONAL(RUN_G13_TESTS, test "$run_g13_test" = "yes") + +# Only build if supported. +AM_CONDITIONAL(BUILD_G13, test "$G13" != "no") +if test "$G13" != "no"; then + AC_DEFINE(HAVE_G13, 1, + [Defined if we are building with g13 support.]) +fi + + # Check for funopen AC_CHECK_FUNCS(funopen) if test $ac_cv_func_funopen != yes; then @@ -777,6 +899,9 @@ GpgConf path: $GPGCONF GpgConf version: $GPGCONF_VERSION, min. $NEED_GPGCONF_VERSION + G13 path: $G13 + G13 version: $G13_VERSION, min. $NEED_G13_VERSION + Assuan version: $LIBASSUAN_VERSION GPGME Pthread: $have_pthread Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/Makefile.am 2009-10-22 16:44:07 UTC (rev 1404) @@ -86,6 +86,12 @@ gpgconf_components = endif +if HAVE_G13 +g13_components = engine-g13.c +else +g13_components = +endif + # These are the source files common to all library versions. We used # to build a non-installed library for that, but that does not work # correctly on all platforms (in particular, one can not specify the @@ -105,6 +111,7 @@ opassuan.c \ engine.h engine-backend.h engine.c engine-gpg.c status-table.h \ $(gpgsm_components) $(assuan_components) $(gpgconf_components) \ + $(g13_components) g13.c \ gpgconf.c \ sema.h priv-io.h $(system_components) dirinfo.c \ debug.c debug.h gpgme.c version.c error.c @@ -185,21 +192,20 @@ $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ libgpgme_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) -libgpgme_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ - @GPG_ERROR_LIBS@ @NETLIBS@ +libgpgme_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ @GPG_ERROR_LIBS@ libgpgme_pthread_la_LDFLAGS = $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ libgpgme_pthread_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers libgpgme_pthread_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ - -lpthread @GPG_ERROR_LIBS@ @NETLIBS@ + -lpthread @GPG_ERROR_LIBS@ libgpgme_pth_la_LDFLAGS = @PTH_LDFLAGS@ \ $(libgpgme_version_script_cmd) -version-info \ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ libgpgme_pth_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers libgpgme_pth_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ - @PTH_LIBS@ @GPG_ERROR_LIBS@ @NETLIBS@ + @PTH_LIBS@ @GPG_ERROR_LIBS@ if BUILD_W32_GLIB libgpgme_glib_la_LDFLAGS = $(gpgme_res_ldflag) $(no_undefined) \ @@ -208,7 +214,7 @@ libgpgme_glib_la_DEPENDENCIES = @LTLIBOBJS@ \ $(srcdir)/libgpgme.vers $(gpgme_deps) libgpgme_glib_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ - @GPG_ERROR_LIBS@ @GLIB_LIBS@ @NETLIBS@ + @GPG_ERROR_LIBS@ @GLIB_LIBS@ endif if BUILD_W32_QT @@ -217,7 +223,7 @@ @LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ libgpgme_qt_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) libgpgme_qt_la_LIBADD = @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ - @GPG_ERROR_LIBS@ @QT4_CORE_LIBS@ @NETLIBS@ + @GPG_ERROR_LIBS@ @QT4_CORE_LIBS@ endif status-table.h : gpgme.h Modified: trunk/src/conversion.c =================================================================== --- trunk/src/conversion.c 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/conversion.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -245,6 +245,75 @@ } +/* Encode the string SRC with percent escaping and store the result in + the buffer *DESTP which is LEN bytes long. If LEN is zero, then a + large enough buffer is allocated with malloc and *DESTP is set to + the result. Currently, LEN is only used to specify if allocation + is desired or not, the caller is expected to make sure that *DESTP + is large enough if LEN is not zero. If BINARY is 1, then '\0' + characters are allowed in the output. */ +gpgme_error_t +_gpgme_encode_percent_string (const char *src, char **destp, size_t len) +{ + size_t destlen; + char *dest; + const char *str; + + destlen = 0; + str = src; + /* We percent-escape the + character because the user might need a + "percent plus" escaped string (special gpg format). But we + percent-escape the space character, which works with and without + the special plus format. */ + while (*str) + { + if (*str == '+' || *str == '\"' || *str == '%' + || *(const unsigned char *)str <= 0x20) + destlen += 3; + else + destlen++; + } + /* Terminating nul byte. */ + destlen++; + + /* Set up the destination buffer. */ + if (len) + { + if (len < destlen); + return gpg_error (GPG_ERR_INTERNAL); + + dest = *destp; + } + else + { + /* The converted string will never be larger than the original + string. */ + dest = malloc (destlen); + if (!dest) + return gpg_error_from_errno (errno); + + *destp = dest; + } + + /* Convert the string. */ + while (*src) + { + if (*src == '+' || *src == '\"' || *src == '%' + || *(const unsigned char *)src <= 0x20) + { + snprintf (dest, 4, "%%%02X", *(unsigned char *)src); + dest += 3; + } + else + *(dest++) = *src; + src++; + } + *(dest++) = 0; + + return 0; +} + + /* Parse the string TIMESTAMP into a time_t. The string may either be seconds since Epoch or in the ISO 8601 format like "20390815T143012". Returns 0 for an empty string or seconds since Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/engine-assuan.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -554,6 +554,8 @@ TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: ERR line: %s", fd, err ? gpg_strerror (err) : "ok"); + /* Command execution errors are not fatal, as we use + a session based protocol. */ if (llass->result_cb) err = llass->result_cb (llass->result_cb_value, err); else Modified: trunk/src/engine-backend.h =================================================================== --- trunk/src/engine-backend.h 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/engine-backend.h 2009-10-22 16:44:07 UTC (rev 1404) @@ -22,11 +22,6 @@ #include "engine.h" -/* FIXME: Correct check? */ -#ifdef GPGSM_PATH -#define ENABLE_GPGSM 1 -#endif - struct engine_ops { /* Static functions. */ @@ -132,5 +127,8 @@ #ifdef ENABLE_ASSUAN extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */ #endif +#ifdef ENABLE_G13 +extern struct engine_ops _gpgme_engine_ops_g13; /* Crypto VFS. */ +#endif #endif /* ENGINE_BACKEND_H */ Added: trunk/src/engine-g13.c =================================================================== --- trunk/src/engine-g13.c (rev 0) +++ trunk/src/engine-g13.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -0,0 +1,796 @@ +/* engine-g13.c - G13 engine. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 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 Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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. */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include /* FIXME */ +#include + +#include "gpgme.h" +#include "util.h" +#include "ops.h" +#include "wait.h" +#include "priv-io.h" +#include "sema.h" + +#include "assuan.h" +#include "debug.h" + +#include "engine-backend.h" + + +typedef struct +{ + int fd; /* FD we talk about. */ + int server_fd;/* Server FD for this connection. */ + int dir; /* Inbound/Outbound, maybe given implicit? */ + void *data; /* Handler-specific data. */ + void *tag; /* ID from the user for gpgme_remove_io_callback. */ + char server_fd_str[15]; /* Same as SERVER_FD but as a string. We + need this because _gpgme_io_fd2str can't + be used on a closed descriptor. */ +} iocb_data_t; + + +struct engine_g13 +{ + assuan_context_t assuan_ctx; + + int lc_ctype_set; + int lc_messages_set; + + iocb_data_t status_cb; + + struct gpgme_io_cbs io_cbs; + + /* Internal callbacks. */ + engine_assuan_result_cb_t result_cb; + void *result_cb_value; + + /* User provided callbacks. */ + struct { + gpgme_assuan_data_cb_t data_cb; + void *data_cb_value; + + gpgme_assuan_inquire_cb_t inq_cb; + void *inq_cb_value; + + gpgme_assuan_status_cb_t status_cb; + void *status_cb_value; + } user; +}; + +typedef struct engine_g13 *engine_g13_t; + + +static void g13_io_event (void *engine, + gpgme_event_io_t type, void *type_data); + + + +static char * +g13_get_version (const char *file_name) +{ + return _gpgme_get_program_version (file_name ? file_name + : _gpgme_get_g13_path ()); +} + + +static const char * +g13_get_req_version (void) +{ + return NEED_G13_VERSION; +} + + +static void +close_notify_handler (int fd, void *opaque) +{ + engine_g13_t g13 = opaque; + + assert (fd != -1); + if (g13->status_cb.fd == fd) + { + if (g13->status_cb.tag) + (*g13->io_cbs.remove) (g13->status_cb.tag); + g13->status_cb.fd = -1; + g13->status_cb.tag = NULL; + } +} + + +/* This is the default inquiry callback. We use it to handle the + Pinentry notifications. */ +static gpgme_error_t +default_inq_cb (engine_g13_t g13, const char *keyword, const char *args) +{ + gpg_error_t err; + + if (!strcmp (keyword, "PINENTRY_LAUNCHED")) + { + _gpgme_allow_set_foreground_window ((pid_t)strtoul (args, NULL, 10)); + } + + if (g13->user.inq_cb) + { + gpgme_data_t data = NULL; + + err = g13->user.inq_cb (g13->user.inq_cb_value, + keyword, args, &data); + if (!err && data) + { + /* FIXME: Returning data is not yet implemented. However we + need to allow the caller to cleanup his data object. + Thus we run the callback in finish mode immediately. */ + err = g13->user.inq_cb (g13->user.inq_cb_value, + NULL, NULL, &data); + } + } + else + err = 0; + + return err; +} + + +static gpgme_error_t +g13_cancel (void *engine) +{ + engine_g13_t g13 = engine; + + if (!g13) + return gpg_error (GPG_ERR_INV_VALUE); + + if (g13->status_cb.fd != -1) + _gpgme_io_close (g13->status_cb.fd); + + if (g13->assuan_ctx) + { + assuan_release (g13->assuan_ctx); + g13->assuan_ctx = NULL; + } + + return 0; +} + + +static void +g13_release (void *engine) +{ + engine_g13_t g13 = engine; + + if (!g13) + return; + + g13_cancel (engine); + + free (g13); +} + + +static gpgme_error_t +g13_new (void **engine, const char *file_name, const char *home_dir) +{ + gpgme_error_t err = 0; + engine_g13_t g13; + int argc; + char *argv[5]; + char *dft_display = NULL; + char dft_ttyname[64]; + char *dft_ttytype = NULL; + char *optstr; + + g13 = calloc (1, sizeof *g13); + if (!g13) + return gpg_error_from_errno (errno); + + g13->status_cb.fd = -1; + g13->status_cb.dir = 1; + g13->status_cb.tag = 0; + g13->status_cb.data = g13; + + err = assuan_new (&g13->assuan_ctx); + if (err) + goto leave; + + argc = 0; + argv[argc++] = "g13"; + if (home_dir) + { + argv[argc++] = "--homedir"; + argv[argc++] = home_dir; + } + argv[argc++] = "--server"; + argv[argc++] = NULL; + + err = assuan_new_ext (&g13->assuan_ctx, GPG_ERR_SOURCE_GPGME, + &_gpgme_assuan_malloc_hooks, _gpgme_assuan_log_cb, + NULL); + if (err) + goto leave; + assuan_ctx_set_system_hooks (g13->assuan_ctx, &_gpgme_assuan_system_hooks); + +#if USE_DESCRIPTOR_PASSING + err = assuan_pipe_connect_ext + (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (), + argv, NULL, NULL, NULL, 1); +#else + err = assuan_pipe_connect + (g13->assuan_ctx, file_name ? file_name : _gpgme_get_g13_path (), + argv, NULL); +#endif + if (err) + goto leave; + + err = _gpgme_getenv ("DISPLAY", &dft_display); + if (err) + goto leave; + if (dft_display) + { + if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + { + free (dft_display); + err = gpg_error_from_errno (errno); + goto leave; + } + free (dft_display); + + err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, + NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + } + + if (isatty (1)) + { + int rc; + + rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); + if (rc) + { + err = gpg_error_from_errno (rc); + goto leave; + } + else + { + if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + { + err = gpg_error_from_errno (errno); + goto leave; + } + err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL, + NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + + err = _gpgme_getenv ("TERM", &dft_ttytype); + if (err) + goto leave; + if (dft_ttytype) + { + if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + { + free (dft_ttytype); + err = gpg_error_from_errno (errno); + goto leave; + } + free (dft_ttytype); + + err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, + NULL, NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + } + } + } + +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to use AllowSetForegroundWindow. Tell + g13 to tell us when it needs it. */ + if (!err) + { + err = assuan_transact (g13->assuan_ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* This is a new feature of g13. */ + } +#endif /*HAVE_W32_SYSTEM*/ + + leave: + + if (err) + g13_release (g13); + else + *engine = g13; + + return err; +} + + +static gpgme_error_t +g13_set_locale (void *engine, int category, const char *value) +{ + engine_g13_t g13 = engine; + gpgme_error_t err; + char *optstr; + char *catstr; + + /* FIXME: If value is NULL, we need to reset the option to default. + But we can't do this. So we error out here. G13 needs support + for this. */ + if (category == LC_CTYPE) + { + catstr = "lc-ctype"; + if (!value && g13->lc_ctype_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + g13->lc_ctype_set = 1; + } +#ifdef LC_MESSAGES + else if (category == LC_MESSAGES) + { + catstr = "lc-messages"; + if (!value && g13->lc_messages_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + g13->lc_messages_set = 1; + } +#endif /* LC_MESSAGES */ + else + return gpg_error (GPG_ERR_INV_VALUE); + + /* FIXME: Reset value to default. */ + if (!value) + return 0; + + if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + err = gpg_error_from_errno (errno); + else + { + err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, + NULL, NULL, NULL, NULL); + free (optstr); + } + + return err; +} + + +/* Forward declaration. */ +static gpgme_status_code_t parse_status (const char *name); + +static gpgme_error_t +g13_assuan_simple_command (assuan_context_t ctx, char *cmd, + engine_status_handler_t status_fnc, + void *status_fnc_value) +{ + gpg_error_t err; + char *line; + size_t linelen; + + err = assuan_write_line (ctx, cmd); + if (err) + return err; + + do + { + err = assuan_read_line (ctx, &line, &linelen); + if (err) + return err; + + if (*line == '#' || !linelen) + continue; + + if (linelen >= 2 + && line[0] == 'O' && line[1] == 'K' + && (line[2] == '\0' || line[2] == ' ')) + return 0; + else if (linelen >= 4 + && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' + && line[3] == ' ') + err = atoi (&line[4]); + else if (linelen >= 2 + && line[0] == 'S' && line[1] == ' ') + { + char *rest; + gpgme_status_code_t r; + + rest = strchr (line + 2, ' '); + if (!rest) + rest = line + linelen; /* set to an empty string */ + else + *(rest++) = 0; + + r = parse_status (line + 2); + + if (r >= 0 && status_fnc) + err = status_fnc (status_fnc_value, r, rest); + else + err = gpg_error (GPG_ERR_GENERAL); + } + else + err = gpg_error (GPG_ERR_GENERAL); + } + while (!err); + + return err; +} + + +static gpgme_error_t +status_handler (void *opaque, int fd) +{ + gpgme_error_t err = 0; + engine_g13_t g13 = opaque; + char *line; + size_t linelen; + + do + { + err = assuan_read_line (g13->assuan_ctx, &line, &linelen); + if (err) + { + /* Try our best to terminate the connection friendly. */ + /* assuan_write_line (g13->assuan_ctx, "BYE"); */ + TRACE2 (DEBUG_CTX, "gpgme:status_handler", g13, + "fd 0x%x: error reading assuan line: %s", + fd, gpg_strerror (err)); + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' + && (line[3] == '\0' || line[3] == ' ')) + { + if (line[3] == ' ') + err = atoi (&line[4]); + if (! err) + err = gpg_error (GPG_ERR_GENERAL); + TRACE2 (DEBUG_CTX, "gpgme:status_handler", g13, + "fd 0x%x: ERR line: %s", + fd, err ? gpg_strerror (err) : "ok"); + + /* In g13, command execution errors are not fatal, as we use + a session based protocol. */ + if (g13->result_cb) + err = g13->result_cb (g13->result_cb_value, err); + else + err = 0; + if (!err) + { + _gpgme_io_close (g13->status_cb.fd); + return 0; + } + } + else if (linelen >= 2 + && line[0] == 'O' && line[1] == 'K' + && (line[2] == '\0' || line[2] == ' ')) + { + TRACE1 (DEBUG_CTX, "gpgme:status_handler", g13, + "fd 0x%x: OK line", fd); + if (g13->result_cb) + err = g13->result_cb (g13->result_cb_value, 0); + else + err = 0; + if (!err) + { + _gpgme_io_close (g13->status_cb.fd); + return 0; + } + } + else if (linelen > 2 + && line[0] == 'D' && line[1] == ' ') + { + /* 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. */ + char *src = line + 2; + char *end = line + linelen; + char *dst = src; + + linelen = 0; + while (src < end) + { + if (*src == '%' && src + 2 < end) + { + /* Handle escaped characters. */ + ++src; + *dst++ = _gpgme_hextobyte (src); + src += 2; + } + else + *dst++ = *src++; + + linelen++; + } + + src = line + 2; + if (linelen && g13->user.data_cb) + err = g13->user.data_cb (g13->user.data_cb_value, + src, linelen); + else + err = 0; + + TRACE2 (DEBUG_CTX, "gpgme:g13_status_handler", g13, + "fd 0x%x: D inlinedata; status from cb: %s", + fd, (g13->user.data_cb ? + (err? gpg_strerror (err):"ok"):"no callback")); + + } + else if (linelen > 2 + && line[0] == 'S' && line[1] == ' ') + { + char *src; + char *args; + + src = line + 2; + while (*src == ' ') + src++; + + args = strchr (line + 2, ' '); + if (!args) + args = line + linelen; /* set to an empty string */ + else + *(args++) = 0; + + while (*args == ' ') + args++; + + if (g13->user.status_cb) + err = g13->user.status_cb (g13->user.status_cb_value, + src, args); + else + err = 0; + + TRACE3 (DEBUG_CTX, "gpgme:g13_status_handler", g13, + "fd 0x%x: S line (%s) - status from cb: %s", + fd, line+2, (g13->user.status_cb ? + (err? gpg_strerror (err):"ok"):"no callback")); + } + else if (linelen >= 7 + && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' + && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' + && line[6] == 'E' + && (line[7] == '\0' || line[7] == ' ')) + { + char *src; + char *args; + + for (src=line+7; *src == ' '; src++) + ; + + args = strchr (src, ' '); + if (!args) + args = line + linelen; /* Let it point to an empty string. */ + else + *(args++) = 0; + + while (*args == ' ') + args++; + + err = default_inq_cb (g13, src, args); + if (!err) + { + /* Flush and send END. */ + err = assuan_send_data (g13->assuan_ctx, NULL, 0); + } + else if (gpg_err_code (err) == GPG_ERR_ASS_CANCELED) + { + /* Flush and send CANcel. */ + err = assuan_send_data (g13->assuan_ctx, NULL, 1); + } + assuan_write_line (g13->assuan_ctx, "END"); + } + } + while (!err && assuan_pending_line (g13->assuan_ctx)); + + return err; +} + + +static gpgme_error_t +add_io_cb (engine_g13_t g13, iocb_data_t *iocbd, gpgme_io_cb_t handler) +{ + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_ENGINE, "engine-g13:add_io_cb", g13, + "fd %d, dir %d", iocbd->fd, iocbd->dir); + err = (*g13->io_cbs.add) (g13->io_cbs.add_priv, + iocbd->fd, iocbd->dir, + handler, iocbd->data, &iocbd->tag); + if (err) + return TRACE_ERR (err); + if (!iocbd->dir) + /* FIXME Kludge around poll() problem. */ + err = _gpgme_io_set_nonblocking (iocbd->fd); + return TRACE_ERR (err); +} + + +static gpgme_error_t +start (engine_g13_t g13, const char *command) +{ + gpgme_error_t err; + int fdlist[5]; + int nfds; + + /* We need to know the fd used by assuan for reads. We do this by + using the assumption that the first returned fd from + assuan_get_active_fds() is always this one. */ + nfds = assuan_get_active_fds (g13->assuan_ctx, 0 /* read fds */, + fdlist, DIM (fdlist)); + if (nfds < 1) + return gpg_error (GPG_ERR_GENERAL); /* FIXME */ + + /* We "duplicate" the file descriptor, so we can close it here (we + can't close fdlist[0], as that is closed by libassuan, and + closing it here might cause libassuan to close some unrelated FD + later). Alternatively, we could special case status_fd and + register/unregister it manually as needed, but this increases + code duplication and is more complicated as we can not use the + close notifications etc. A third alternative would be to let + Assuan know that we closed the FD, but that complicates the + Assuan interface. */ + + g13->status_cb.fd = _gpgme_io_dup (fdlist[0]); + if (g13->status_cb.fd < 0) + return gpg_error_from_syserror (); + + if (_gpgme_io_set_close_notify (g13->status_cb.fd, + close_notify_handler, g13)) + { + _gpgme_io_close (g13->status_cb.fd); + g13->status_cb.fd = -1; + return gpg_error (GPG_ERR_GENERAL); + } + + err = add_io_cb (g13, &g13->status_cb, status_handler); + if (!err) + err = assuan_write_line (g13->assuan_ctx, command); + + if (!err) + g13_io_event (g13, GPGME_EVENT_START, NULL); + + return err; +} + + +#if USE_DESCRIPTOR_PASSING +static gpgme_error_t +g13_reset (void *engine) +{ + engine_g13_t g13 = engine; + + /* We must send a reset because we need to reset the list of + signers. Note that RESET does not reset OPTION commands. */ + return g13_assuan_simple_command (g13->assuan_ctx, "RESET", NULL, NULL); +} +#endif + + +static gpgme_error_t +g13_transact (void *engine, + const char *command, + engine_assuan_result_cb_t result_cb, + void *result_cb_value, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + engine_g13_t g13 = engine; + gpgme_error_t err; + + if (!g13 || !command || !*command) + return gpg_error (GPG_ERR_INV_VALUE); + + g13->result_cb = result_cb; + g13->result_cb_value = result_cb_value; + g13->user.data_cb = data_cb; + g13->user.data_cb_value = data_cb_value; + g13->user.inq_cb = inq_cb; + g13->user.inq_cb_value = inq_cb_value; + g13->user.status_cb = status_cb; + g13->user.status_cb_value = status_cb_value; + + err = start (g13, command); + return err; +} + + + +static void +g13_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs) +{ + engine_g13_t g13 = engine; + g13->io_cbs = *io_cbs; +} + + +static void +g13_io_event (void *engine, gpgme_event_io_t type, void *type_data) +{ + engine_g13_t g13 = engine; + + TRACE3 (DEBUG_ENGINE, "gpgme:g13_io_event", g13, + "event %p, type %d, type_data %p", + g13->io_cbs.event, type, type_data); + if (g13->io_cbs.event) + (*g13->io_cbs.event) (g13->io_cbs.event_priv, type, type_data); +} + + +struct engine_ops _gpgme_engine_ops_g13 = + { + /* Static functions. */ + _gpgme_get_g13_path, + NULL, + g13_get_version, + g13_get_req_version, + g13_new, + + /* Member functions. */ + g13_release, +#if USE_DESCRIPTOR_PASSING + g13_reset, +#else + NULL, /* reset */ +#endif + NULL, /* set_status_handler */ + NULL, /* set_command_handler */ + NULL, /* set_colon_line_handler */ + g13_set_locale, + NULL, /* decrypt */ + NULL, /* delete */ + NULL, /* edit */ + NULL, /* encrypt */ + NULL, /* encrypt_sign */ + NULL, /* export */ + NULL, /* export_ext */ + NULL, /* genkey */ + NULL, /* import */ + NULL, /* keylist */ + NULL, /* keylist_ext */ + NULL, /* sign */ + NULL, /* trustlist */ + NULL, /* verify */ + NULL, /* getauditlog */ + g13_transact, + NULL, /* conf_load */ + NULL, /* conf_save */ + g13_set_io_cbs, + g13_io_event, + g13_cancel + }; Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/engine.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -55,11 +55,16 @@ #else NULL, #endif -#ifdef ENABLE_GPGSM /* This indicates that we have assuan support. */ - &_gpgme_engine_ops_assuan /* Low-Level Assuan. */ +#ifdef ENABLE_ASSUAN + &_gpgme_engine_ops_assuan, /* Low-Level Assuan. */ #else NULL #endif +#ifdef ENABLE_G13 + &_gpgme_engine_ops_g13 /* Crypto VFS. */ +#else + NULL +#endif }; @@ -194,7 +199,8 @@ gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS, GPGME_PROTOCOL_GPGCONF, - GPGME_PROTOCOL_ASSUAN }; + GPGME_PROTOCOL_ASSUAN, + GPGME_PROTOCOL_G13 }; unsigned int proto; for (proto = 0; proto < DIM (proto_list); proto++) Added: trunk/src/g13.c =================================================================== --- trunk/src/g13.c (rev 0) +++ trunk/src/g13.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -0,0 +1,229 @@ +/* g13.c - g13 support in GPGME + Copyright (C) 2009 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 Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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. */ + +#if HAVE_CONFIG_H +#include +#endif + +#include + +#include "gpgme.h" +#include "context.h" +#include "ops.h" +#include "util.h" + +typedef struct +{ + struct _gpgme_op_g13_result result; +} *op_data_t; + + + +/* This callback is used to return the status of the assuan command + back rather than transmission errors. */ +static gpgme_error_t +result_cb (void *priv, gpgme_error_t result) +{ + gpgme_ctx_t ctx = (gpgme_ctx_t)priv; + gpgme_error_t err; + void *hook; + op_data_t opd; + + err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); + opd = hook; + if (err) + return err; + if (!opd) + return gpg_error (GPG_ERR_INTERNAL); + + opd->result.err = result; + return 0; +} + + +gpgme_g13_result_t +gpgme_op_g13_result (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); + opd = hook; + /* Check in case this function is used without having run a command + before. */ + if (err || !opd) + return NULL; + + return &opd->result; +} + + +static gpgme_error_t +opg13_start (gpgme_ctx_t ctx, int synchronous, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + if (!command || !*command) + return gpg_error (GPG_ERR_INV_VALUE); + + /* The flag value 256 is used to suppress an engine reset. This is + required to keep the connection running. */ + err = _gpgme_op_reset (ctx, ((synchronous & 255) | 256)); + if (err) + return err; + + err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, sizeof (*opd), NULL); + opd = hook; + if (err) + return err; + opd->result.err = gpg_error (GPG_ERR_UNFINISHED); + + return _gpgme_engine_op_assuan_transact (ctx->engine, command, + result_cb, ctx, + data_cb, data_cb_value, + inq_cb, inq_cb_value, + status_cb, status_cb_value); +} + + + +/* XXXX. This is the asynchronous variant. */ +static gpgme_error_t +gpgme_op_g13_transact_start (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + return opg13_start (ctx, 0, command, data_cb, data_cb_value, + inq_cb, inq_cb_value, status_cb, status_cb_value); +} + + +/* XXXX. This is the synchronous variant. */ +static gpgme_error_t +gpgme_op_g13_transact (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + gpgme_error_t err; + + err = opg13_start (ctx, 1, command, data_cb, data_cb_value, + inq_cb, inq_cb_value, status_cb, status_cb_value); + if (!err) + err = _gpgme_wait_one (ctx); + return err; +} + + +/* The actual exported interface follows. */ + +static gpg_error_t +get_err (gpgme_ctx_t ctx) +{ + gpgme_g13_result_t res; + + res = gpgme_op_g13_result (ctx); + if (! res) + return gpg_error (GPG_ERR_GENERAL); + + return res->err; +} + + +/* The container is automatically unmounted when the context is reset + or destroyed. This is a synchronous convenience interface, which + automatically returns an operation error if there is no + transmission error. */ +gpgme_error_t +gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file, + const char *mount_dir, int flags) +{ + gpg_error_t err; + char *cmd; + char *container_file_esc = NULL; + + err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0); + if (err) + return err; + + if (asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0) + { + err = gpg_error_from_syserror (); + free (container_file_esc); + return err; + } + free (container_file_esc); + + err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL, + NULL, NULL); + free (cmd); + err = err || get_err (ctx); + if (err) + return err; + + if (mount_dir) + { + char *mount_dir_esc = NULL; + + err = _gpgme_encode_percent_string (mount_dir, &mount_dir_esc, 0); + if (err) + return err; + + if (asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0) + { + err = gpg_error_from_syserror (); + free (mount_dir_esc); + return err; + } + free (mount_dir_esc); + } + else + { + if (asprintf (&cmd, "MOUNT") < 0) + return gpg_error_from_syserror (); + } + + err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL, + NULL, NULL); + free (cmd); + + /* Note: in symmetry with the asynchronous variant, we don't return + the error in the result structure here, if any. */ + return err; +} Modified: trunk/src/gpgme.c =================================================================== --- trunk/src/gpgme.c 2009-10-20 16:05:21 UTC (rev 1403) +++ trunk/src/gpgme.c 2009-10-22 16:44:07 UTC (rev 1404) @@ -248,7 +248,8 @@ if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS - && protocol != GPGME_PROTOCOL_ASSUAN) + && protocol != GPGME_PROTOCOL_ASSUAN + && protocol != GPGME_PROTOCOL_G13) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (ctx->protocol != protocol) @@ -292,6 +293,9 @@ case GPGME_PROTOCOL_ASSUAN: return "Assuan"; From cvs at cvs.gnupg.org Mon Oct 26 17:45:05 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 26 Oct 2009 17:45:05 +0100 Subject: [svn] gpg-error - r224 - in trunk: . src Message-ID: Author: marcus Date: 2009-10-26 17:45:05 +0100 (Mon, 26 Oct 2009) New Revision: 224 Modified: trunk/ChangeLog trunk/src/gpg-error.h.in Log: 2009-10-26 Marcus Brinkmann * src/gpg-error.h.in (GPG_ERR_SOURCE_DIM): Reduce to 128. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-16 12:32:05 UTC (rev 223) +++ trunk/ChangeLog 2009-10-26 16:45:05 UTC (rev 224) @@ -1,3 +1,7 @@ +2009-10-26 Marcus Brinkmann + + * src/gpg-error.h.in (GPG_ERR_SOURCE_DIM): Reduce to 128. + 2009-09-21 Werner Koch * src/err-sources.h.in (GPG_ERR_SOURCE_G13): New. Modified: trunk/src/gpg-error.h.in =================================================================== --- trunk/src/gpg-error.h.in 2009-10-16 12:32:05 UTC (rev 223) +++ trunk/src/gpg-error.h.in 2009-10-26 16:45:05 UTC (rev 224) @@ -74,7 +74,7 @@ @include err-sources.h.in /* This is one more than the largest allowed entry. */ - GPG_ERR_SOURCE_DIM = 256 + GPG_ERR_SOURCE_DIM = 128 } gpg_err_source_t; @@ -109,10 +109,14 @@ /* Bits 17 to 24 are reserved. */ -/* We use the upper 8 bits of gpg_error_t for error sources. */ +/* We use the upper 7 bits of gpg_error_t for error sources. */ #define GPG_ERR_SOURCE_MASK (GPG_ERR_SOURCE_DIM - 1) #define GPG_ERR_SOURCE_SHIFT 24 +/* The highest bit is reserved. It shouldn't be used to prevent + potential negative numbers when transmitting error values as + text. */ + /* GCC feature test. */ #undef _GPG_ERR_HAVE_CONSTRUCTOR From cvs at cvs.gnupg.org Mon Oct 26 18:38:40 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 26 Oct 2009 18:38:40 +0100 Subject: [svn] gpgme - r1405 - trunk/src Message-ID: Author: marcus Date: 2009-10-26 18:38:39 +0100 (Mon, 26 Oct 2009) New Revision: 1405 Modified: trunk/src/ChangeLog trunk/src/conversion.c trunk/src/data-fd.c trunk/src/data-mem.c trunk/src/data-stream.c trunk/src/data-user.c trunk/src/debug.h trunk/src/decrypt-verify.c trunk/src/decrypt.c trunk/src/delete.c trunk/src/sign.c trunk/src/verify.c Log: 2009-10-26 Marcus Brinkmann * debug.h (DEBUG_GLOBAL): New debug level. * conversion.c (gnupg_errors, _gpgme_map_gnupg_error): Removed. * data-user.c (gpgme_data_new_from_cbs): Add debug output. * data-fd.c (gpgme_data_new_from_fd): Likewise. * data-stream.c (gpgme_data_new_from_stream): Likewise. * decrypt.c (gpgme_op_decrypt_result, gpgme_op_decrypt_start) (gpgme_op_decrypt): Likewise. * delete.c (gpgme_op_delete_start, gpgme_op_delete): Likewise. * decrypt-verify.c (gpgme_op_decrypt_verify_start) (gpgme_op_decrypt_verify): Likewise. * sign.c (gpgme_op_sign_result): Fix debug message. * data-mem.c (gpgme_data_new): Improve debug output. * verify.c (parse_trust): Use atoi instead of _gpgme_map_gnupg_error. * decrypt.c (_gpgme_decrypt_status_handler): Likewise. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/ChangeLog 2009-10-26 17:38:39 UTC (rev 1405) @@ -1,3 +1,21 @@ +2009-10-26 Marcus Brinkmann + + * debug.h (DEBUG_GLOBAL): New debug level. + * conversion.c (gnupg_errors, _gpgme_map_gnupg_error): Removed. + * data-user.c (gpgme_data_new_from_cbs): Add debug output. + * data-fd.c (gpgme_data_new_from_fd): Likewise. + * data-stream.c (gpgme_data_new_from_stream): Likewise. + * decrypt.c (gpgme_op_decrypt_result, gpgme_op_decrypt_start) + (gpgme_op_decrypt): Likewise. + * delete.c (gpgme_op_delete_start, gpgme_op_delete): Likewise. + * decrypt-verify.c (gpgme_op_decrypt_verify_start) + (gpgme_op_decrypt_verify): Likewise. + * sign.c (gpgme_op_sign_result): Fix debug message. + * data-mem.c (gpgme_data_new): Improve debug output. + * verify.c (parse_trust): Use atoi instead of + _gpgme_map_gnupg_error. + * decrypt.c (_gpgme_decrypt_status_handler): Likewise. + 2009-10-22 Marcus Brinkmann * Makefile.am: Remove @NETLIBS@ from LIBADDs. Modified: trunk/src/conversion.c =================================================================== --- trunk/src/conversion.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/conversion.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -371,119 +371,3 @@ else return (time_t)strtoul (timestamp, endp, 10); } - - - - -static struct -{ - char *name; - gpgme_error_t err; -} gnupg_errors[] = - { - { "EOF", GPG_ERR_EOF }, - { "No_Error", GPG_ERR_NO_ERROR }, - { "General_Error", GPG_ERR_GENERAL }, - { "Out_Of_Core", GPG_ERR_ENOMEM }, - { "Invalid_Value", GPG_ERR_INV_VALUE }, - { "IO_Error", GPG_ERR_GENERAL }, - { "Resource_Limit", GPG_ERR_RESOURCE_LIMIT }, - { "Internal_Error", GPG_ERR_INTERNAL }, - { "Bad_Certificate", GPG_ERR_BAD_CERT }, - { "Bad_Certificate_Chain", GPG_ERR_BAD_CERT_CHAIN}, - { "Missing_Certificate", GPG_ERR_MISSING_CERT }, - { "No_Data", GPG_ERR_NO_DATA }, - { "Bad_Signature", GPG_ERR_BAD_SIGNATURE }, - { "Not_Implemented", GPG_ERR_NOT_IMPLEMENTED }, - { "Conflict", GPG_ERR_CONFLICT }, - { "Bug", GPG_ERR_BUG }, - { "Read_Error", GPG_ERR_GENERAL }, - { "Write_Error", GPG_ERR_GENERAL }, - { "Invalid_Line", GPG_ERR_GENERAL }, - { "Incomplete_Line", GPG_ERR_INCOMPLETE_LINE }, - { "Invalid_Response", GPG_ERR_INV_RESPONSE }, - { "Agent_Error", GPG_ERR_AGENT }, - { "No_Public_Key", GPG_ERR_NO_PUBKEY }, - { "No_Secret_Key", GPG_ERR_NO_SECKEY }, - { "File_Open_Error", GPG_ERR_GENERAL }, - { "File_Create_Error", GPG_ERR_GENERAL }, - { "File_Error", GPG_ERR_GENERAL }, - { "Not_Supported", GPG_ERR_NOT_SUPPORTED }, - { "Invalid_Data", GPG_ERR_INV_DATA }, - { "Assuan_Server_Fault", GPG_ERR_ASSUAN_SERVER_FAULT }, - { "Assuan_Error", GPG_ERR_ASSUAN }, - { "Invalid_Session_Key", GPG_ERR_INV_SESSION_KEY }, - { "Invalid_Sexp", GPG_ERR_INV_SEXP }, - { "Unsupported_Algorithm", GPG_ERR_UNSUPPORTED_ALGORITHM }, - { "No_PIN_Entry", GPG_ERR_NO_PIN_ENTRY }, - { "PIN_Entry_Error", GPG_ERR_NO_PIN_ENTRY }, - { "Bad_PIN", GPG_ERR_BAD_PIN }, - { "Bad_Passphrase", GPG_ERR_BAD_PASSPHRASE }, - { "Invalid_Name", GPG_ERR_INV_NAME }, - { "Bad_Public_Key", GPG_ERR_BAD_PUBKEY }, - { "Bad_Secret_Key", GPG_ERR_BAD_SECKEY }, - { "Bad_Data", GPG_ERR_BAD_DATA }, - { "Invalid_Parameter", GPG_ERR_INV_PARAMETER }, - { "Tribute_to_D_A", GPG_ERR_TRIBUTE_TO_D_A }, - { "No_Dirmngr", GPG_ERR_NO_DIRMNGR }, - { "Dirmngr_Error", GPG_ERR_DIRMNGR }, - { "Certificate_Revoked", GPG_ERR_CERT_REVOKED }, - { "No_CRL_Known", GPG_ERR_NO_CRL_KNOWN }, - { "CRL_Too_Old", GPG_ERR_CRL_TOO_OLD }, - { "Line_Too_Long", GPG_ERR_LINE_TOO_LONG }, - { "Not_Trusted", GPG_ERR_NOT_TRUSTED }, - { "Canceled", GPG_ERR_CANCELED }, - { "Bad_CA_Certificate", GPG_ERR_BAD_CA_CERT }, - { "Certificate_Expired", GPG_ERR_CERT_EXPIRED }, - { "Certificate_Too_Young", GPG_ERR_CERT_TOO_YOUNG }, - { "Unsupported_Certificate", GPG_ERR_UNSUPPORTED_CERT }, - { "Unknown_Sexp", GPG_ERR_UNKNOWN_SEXP }, - { "Unsupported_Protection", GPG_ERR_UNSUPPORTED_PROTECTION }, - { "Corrupted_Protection", GPG_ERR_CORRUPTED_PROTECTION }, - { "Ambiguous_Name", GPG_ERR_AMBIGUOUS_NAME }, - { "Card_Error", GPG_ERR_CARD }, - { "Card_Reset", GPG_ERR_CARD_RESET }, - { "Card_Removed", GPG_ERR_CARD_REMOVED }, - { "Invalid_Card", GPG_ERR_INV_CARD }, - { "Card_Not_Present", GPG_ERR_CARD_NOT_PRESENT }, - { "No_PKCS15_App", GPG_ERR_NO_PKCS15_APP }, - { "Not_Confirmed", GPG_ERR_NOT_CONFIRMED }, - { "Configuration_Error", GPG_ERR_CONFIGURATION }, - { "No_Policy_Match", GPG_ERR_NO_POLICY_MATCH }, - { "Invalid_Index", GPG_ERR_INV_INDEX }, - { "Invalid_Id", GPG_ERR_INV_ID }, - { "No_Scdaemon", GPG_ERR_NO_SCDAEMON }, - { "Scdaemon_Error", GPG_ERR_SCDAEMON }, - { "Unsupported_Protocol", GPG_ERR_UNSUPPORTED_PROTOCOL }, - { "Bad_PIN_Method", GPG_ERR_BAD_PIN_METHOD }, - { "Card_Not_Initialized", GPG_ERR_CARD_NOT_INITIALIZED }, - { "Unsupported_Operation", GPG_ERR_UNSUPPORTED_OPERATION }, - { "Wrong_Key_Usage", GPG_ERR_WRONG_KEY_USAGE } - }; - - -gpgme_error_t -_gpgme_map_gnupg_error (char *errstr) -{ - unsigned int i; - gpgme_error_t err = gpg_err_make (GPG_ERR_SOURCE_GPG, GPG_ERR_GENERAL); - - /* Future version of GnuPG might return the error code directly, so - we first test for a a numerical value and use that verbatim. - Note that this numerical value might be followed by an - underschore and the textual representation of the error code. */ - if (*errstr >= '0' && *errstr <= '9') - return strtoul (errstr, NULL, 10); - - /* Well, this is a token, use the mapping table to get the error. - The drawback is that we won't receive an error source and have to - use GPG as source. */ - for (i = 0; i < DIM (gnupg_errors); i++) - if (!strcmp (gnupg_errors[i].name, errstr)) - err = gpg_err_make (GPG_ERR_SOURCE_GPG, gnupg_errors[i].err); - - TRACE3 (DEBUG_CTX, "_gpgme_map_gnupg_error", 0, - "mapped %s to %s <%s>", errstr, gpgme_strerror (err), - gpgme_strsource (err)); - return err; -} Modified: trunk/src/data-fd.c =================================================================== --- trunk/src/data-fd.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/data-fd.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -25,6 +25,7 @@ #include #include +#include "debug.h" #include "data.h" @@ -67,12 +68,15 @@ gpgme_error_t -gpgme_data_new_from_fd (gpgme_data_t *dh, int fd) +gpgme_data_new_from_fd (gpgme_data_t *r_dh, int fd) { - gpgme_error_t err = _gpgme_data_new (dh, &fd_cbs); + gpgme_error_t err; + TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_fd", r_dh, "fd=0x%x", fd); + + err = _gpgme_data_new (r_dh, &fd_cbs); if (err) - return err; + return TRACE_ERR (err); - (*dh)->data.fd = fd; - return 0; + (*r_dh)->data.fd = fd; + return TRACE_SUC1 ("dh=%p", *r_dh); } Modified: trunk/src/data-mem.c =================================================================== --- trunk/src/data-mem.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/data-mem.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -175,7 +175,7 @@ if (err) return TRACE_ERR (err); - return TRACE_SUC1 ("r_dh=%p", *r_dh); + return TRACE_SUC1 ("dh=%p", *r_dh); } Modified: trunk/src/data-stream.c =================================================================== --- trunk/src/data-stream.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/data-stream.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -25,6 +25,7 @@ #include #include +#include "debug.h" #include "data.h" @@ -90,12 +91,16 @@ gpgme_error_t -gpgme_data_new_from_stream (gpgme_data_t *dh, FILE *stream) +gpgme_data_new_from_stream (gpgme_data_t *r_dh, FILE *stream) { - gpgme_error_t err = _gpgme_data_new (dh, &stream_cbs); + gpgme_error_t err; + TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_stream", r_dh, "stream=%p", + stream); + + err = _gpgme_data_new (r_dh, &stream_cbs); if (err) - return err; + return TRACE_ERR (err); - (*dh)->data.stream = stream; - return 0; + (*r_dh)->data.stream = stream; + return TRACE_SUC1 ("dh=%p", *r_dh); } Modified: trunk/src/data-user.c =================================================================== --- trunk/src/data-user.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/data-user.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -25,6 +25,7 @@ #include #include +#include "debug.h" #include "data.h" @@ -86,13 +87,16 @@ gpgme_error_t -gpgme_data_new_from_cbs (gpgme_data_t *dh, gpgme_data_cbs_t cbs, void *handle) +gpgme_data_new_from_cbs (gpgme_data_t *r_dh, gpgme_data_cbs_t cbs, void *handle) { - gpgme_error_t err = _gpgme_data_new (dh, &user_cbs); + gpgme_error_t err; + TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_cbs", r_dh, "handle=%p", handle); + + err = _gpgme_data_new (r_dh, &user_cbs); if (err) - return err; + return TRACE_ERR (err); - (*dh)->data.user.cbs = cbs; - (*dh)->data.user.handle = handle; - return 0; + (*r_dh)->data.user.cbs = cbs; + (*r_dh)->data.user.handle = handle; + return TRACE_SUC1 ("dh=%p", *r_dh); } Modified: trunk/src/debug.h =================================================================== --- trunk/src/debug.h 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/debug.h 2009-10-26 17:38:39 UTC (rev 1405) @@ -34,11 +34,12 @@ /* The debug levels. */ #define DEBUG_INIT 1 -#define DEBUG_CTX 2 -#define DEBUG_ENGINE 3 -#define DEBUG_DATA 4 -#define DEBUG_ASSUAN 5 -#define DEBUG_SYSIO 6 +#define DEBUG_GLOBAL 2 +#define DEBUG_CTX 3 +#define DEBUG_ENGINE 4 +#define DEBUG_DATA 5 +#define DEBUG_ASSUAN 6 +#define DEBUG_SYSIO 7 /* Remove path components from filenames (i.e. __FILE__) for cleaner Modified: trunk/src/decrypt-verify.c =================================================================== --- trunk/src/decrypt-verify.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/decrypt-verify.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -23,6 +23,7 @@ #include #endif +#include "debug.h" #include "gpgme.h" #include "ops.h" @@ -86,7 +87,9 @@ gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) { - return decrypt_verify_start (ctx, 0, cipher, plain); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_verify_start", ctx, + "cipher=%p, plain=%p", cipher, plain); + return TRACE_ERR (decrypt_verify_start (ctx, 0, cipher, plain)); } @@ -96,8 +99,12 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) { - gpgme_error_t err = decrypt_verify_start (ctx, 1, cipher, plain); + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_verify", ctx, + "cipher=%p, plain=%p", cipher, plain); + err = decrypt_verify_start (ctx, 1, cipher, plain); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/decrypt.c =================================================================== --- trunk/src/decrypt.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/decrypt.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -26,6 +26,7 @@ #include #include +#include "debug.h" #include "gpgme.h" #include "util.h" #include "context.h" @@ -74,11 +75,45 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + if (_gpgme_debug_trace ()) + { + gpgme_recipient_t rcp; + int signatures = 0; + + if (opd->result.unsupported_algorithm) + { + TRACE_LOG1 ("result: unsupported_algorithm: %s", + opd->result.unsupported_algorithm); + } + if (opd->result.wrong_key_usage) + { + TRACE_LOG ("result: wrong key usage"); + } + rcp = opd->result.recipients; + while (rcp) + { + TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, " + "status=%s", rcp->keyid, rcp->pubkey_algo, + gpg_strerror (rcp->status)); + rcp = rcp->next; + } + if (opd->result.file_name) + { + TRACE_LOG1 ("result: original file name: %s", opd->result.file_name); + } + } + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -188,8 +223,7 @@ while (*args == ' ') args++; - if (gpg_err_code (_gpgme_map_gnupg_error (args)) - == GPG_ERR_UNSUPPORTED_ALGORITHM) + if (gpg_err_code (atoi (args)) == GPG_ERR_UNSUPPORTED_ALGORITHM) { char *end; @@ -216,8 +250,7 @@ while (*args == ' ') args++; - err = _gpgme_map_gnupg_error (args); - if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE) + if (gpg_err_code (atoi (args)) == GPG_ERR_WRONG_KEY_USAGE) opd->result.wrong_key_usage = 1; } } @@ -333,7 +366,9 @@ gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) { - return decrypt_start (ctx, 0, cipher, plain); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx, + "cipher=%p, plain=%p", cipher, plain); + return TRACE_ERR (decrypt_start (ctx, 0, cipher, plain)); } @@ -342,8 +377,12 @@ gpgme_error_t gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain) { - gpgme_error_t err = decrypt_start (ctx, 1, cipher, plain); + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx, + "cipher=%p, plain=%p", cipher, plain); + err = decrypt_start (ctx, 1, cipher, plain); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/delete.c =================================================================== --- trunk/src/delete.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/delete.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -24,6 +24,7 @@ #include #include +#include "debug.h" #include "gpgme.h" #include "context.h" #include "ops.h" @@ -93,7 +94,11 @@ gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret) { - return delete_start (ctx, 0, key, allow_secret); + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx, + "key=%p (%s), allow_secret=%i", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", allow_secret); + return TRACE_ERR (delete_start (ctx, 0, key, allow_secret)); } @@ -102,7 +107,13 @@ gpgme_error_t gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret) { - gpgme_error_t err = delete_start (ctx, 1, key, allow_secret); + gpgme_error_t err; + + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx, + "key=%p (%s), allow_secret=%i", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", allow_secret); + err = delete_start (ctx, 1, key, allow_secret); if (!err) err = _gpgme_wait_one (ctx); return err; Modified: trunk/src/sign.c =================================================================== --- trunk/src/sign.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/sign.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -399,7 +399,7 @@ { gpgme_error_t err; - TRACE_BEG3 (DEBUG_CTX, "gpgme_op_sign_start", ctx, + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_sign", ctx, "plain=%p, sig=%p, mode=%i", plain, sig, mode); err = sign_start (ctx, 1, plain, sig, mode); if (!err) Modified: trunk/src/verify.c =================================================================== --- trunk/src/verify.c 2009-10-22 16:44:07 UTC (rev 1404) +++ trunk/src/verify.c 2009-10-26 17:38:39 UTC (rev 1405) @@ -545,7 +545,7 @@ sig->chain_model = 0; if (*args) { - sig->validity_reason = _gpgme_map_gnupg_error (args); + sig->validity_reason = atoi (args); while (*args && *args != ' ') args++; if (*args) @@ -585,7 +585,7 @@ else return gpg_error (GPG_ERR_INV_ENGINE); - err = _gpgme_map_gnupg_error (which); + err = atoi (which); if (!strcmp (where, "proc_pkt.plaintext") && gpg_err_code (err) == GPG_ERR_BAD_DATA) From cvs at cvs.gnupg.org Mon Oct 26 19:52:32 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 26 Oct 2009 19:52:32 +0100 Subject: [svn] gpgme - r1406 - in trunk: . src tests tests/opassuan Message-ID: Author: marcus Date: 2009-10-26 19:52:32 +0100 (Mon, 26 Oct 2009) New Revision: 1406 Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/context.h trunk/src/data.c trunk/src/engine-assuan.c trunk/src/engine-backend.h trunk/src/engine-g13.c trunk/src/engine-gpg.c trunk/src/engine-gpgsm.c trunk/src/engine.c trunk/src/engine.h trunk/src/g13.c trunk/src/gpgme.c trunk/src/gpgme.def trunk/src/gpgme.h.in trunk/src/keylist.c trunk/src/libgpgme.vers trunk/src/opassuan.c trunk/src/ops.h trunk/src/trustlist.c trunk/src/wait-global.c trunk/src/wait-private.c trunk/src/wait-user.c trunk/src/wait.c trunk/src/wait.h trunk/tests/ChangeLog trunk/tests/opassuan/t-command.c Log: 2009-10-26 Marcus Brinkmann * configure.ac (NEED_GPG_VERSION_DEFAULT): Bump to 1.4.0 as 1.3.0 was development versions only. tests/ 2009-10-26 Marcus Brinkmann * opassuan/t-command.c: Update to new interface. src/ 2009-10-26 Marcus Brinkmann * gpgme.h.in (struct gpgme_io_event_done_data) (gpgme_io_event_done_data_t): New types. (struct _gpgme_op_assuan_result): Deprecate the err member. (gpgme_op_assuan_result): Deprecate (for now). (gpgme_op_assuan_transact_ext): New prototype. (gpgme_op_assuan_transact): Deprecate. (struct _gpgme_op_g13_result): Replace with ... (struct _gpgme_op_vfs_mount_result): ... this. (gpgme_op_g13_mount): Replace with ... (gpgme_op_vfs_mount): ... this. * gpgme.def (gpgme_op_assuan_transact_ext, gpgme_wait_ext) (gpgme_op_vfs_mount_result, gpgme_op_vfs_mount): New. (gpgme_op_g13_mount): Remove. * libgpgme.vers: Likewise. * engine-backend.h (struct engine_ops): Remove RESULT_CB and RESULT_CB_VALUE args in opassuan_transact member. Add CANCEL_OP member. * ops.h (_gpgme_cancel_with_err, _gpgme_wait_on_condition): Add OP_ERR argument. (_gpgme_wait_one_ext): New prototype. * context.h (ctx_op_data_id_t): Add OPDATA_VFS_MOUNT. * engine-g13.c (g13_cancel_op): New function. (parse_status): Remove declaration. (g13_assuan_simple_command): Do nothing with status lines for now. (status_handler): Update opaque value access. (_gpgme_engine_ops_g13): Add new cancel_op member. * gpgme.c (_gpgme_cancel_with_err): Add new parameter OP_ERR. Handle operational errors. (gpgme_cancel, gpgme_io_read, gpgme_io_write): Add debug output. * data.c (_gpgme_data_inbound_handler) (_gpgme_data_outbound_handler): Adjust opaque value access. * engine-gpg.c (command_handler, status_handler) (colon_line_handler): Likewise. * engine-gpgsm.c (status_handler): Likewise. * engine-gpg.c (_gpgme_engine_ops_gpg): Add cancel_op member. * engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Likewise. * g13.c: Rewritten (and will be rewritten again). * engine.h (_gpgme_engine_op_assuan_transact): Remove result_cb and result_cb_value parameters from prototype. (_gpgme_engine_cancel_op): New prototype. * engine.c (engine_ops) [! ENABLE_ASSUAN]: Add missing comma. (_gpgme_engine_op_assuan_transact): Remove result_cb and result_cb_value parameter. (_gpgme_engine_cancel_op): New function. * wait.h (_gpgme_run_io_cb): Add new argument OP_ERR. (struct io_cb_data): New struct to pass opaque data and get a op_err return value. Needed because we can't modify I/O callback handler signature because it is exposed to the user. * wait.c (_gpgme_run_io_cb): Add OP_ERR parameter. Handle operational errors. * wait-user.c (_gpgme_user_io_cb_handler): Handle operational errors. * wait-private.c (_gpgme_wait_on_condition): New argument to retrieve the operational result. Handle operational errors in session based protocols. (_gpgme_wait_one_ext): New function. (_gpgme_wait_one): Pass argument in invocation of _gpgme_wait_on_condition. * wait-global.c (struct ctx_list_item): Add member OP_ERR. (ctx_done): New argument OP_ERR. (ctx_wait): New argument OP_ERR. (gpgme_wait_ext): New function based on gpgme_wait but handling operational errors. (gpgme_wait): Implement in term of gpgme_wait_ext. * keylist.c (gpgme_op_keylist_next): Pass argument in invocation of _gpgme_wait_on_condition. * trustlist.c (gpgme_op_trustlist_next): Pass argument in invocation of _gpgme_wait_on_condition. * engine-assuan.c (struct engine_llass): Replace members RESULT_CB and RESULT_CB_VALUE by LAST_OP_ERR. (_gpgme_engine_assuan_last_op_err): Add this hack function. (llass_cancel_op): New function. (_gpgme_engine_llass_ops): Add cancel_op member. (llass_status_handler): Update opaque value access. (llass_transact): Remove RESULT_CB and RESULT_CB_VALUE arguments. * opassuan.c: Move compat hacks to the end of file. (opassuan_start): Do not set OPD->result.err. Do not pass RESULT_Cb and CTX to _gpgme_engine_op_assuan_transact. (gpgme_op_assuan_transact_ext): New function. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/ChangeLog 2009-10-26 18:52:32 UTC (rev 1406) @@ -1,3 +1,8 @@ +2009-10-26 Marcus Brinkmann + + * configure.ac (NEED_GPG_VERSION_DEFAULT): Bump to 1.4.0 as 1.3.0 + was development versions only. + 2009-10-22 Marcus Brinkmann * configure.ac: Add support for G13. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/ChangeLog 2009-10-26 18:52:32 UTC (rev 1406) @@ -1,5 +1,85 @@ 2009-10-26 Marcus Brinkmann + * gpgme.h.in (struct gpgme_io_event_done_data) + (gpgme_io_event_done_data_t): New types. + (struct _gpgme_op_assuan_result): Deprecate the err member. + (gpgme_op_assuan_result): Deprecate (for now). + (gpgme_op_assuan_transact_ext): New prototype. + (gpgme_op_assuan_transact): Deprecate. + (struct _gpgme_op_g13_result): Replace with ... + (struct _gpgme_op_vfs_mount_result): ... this. + (gpgme_op_g13_mount): Replace with ... + (gpgme_op_vfs_mount): ... this. + * gpgme.def (gpgme_op_assuan_transact_ext, gpgme_wait_ext) + (gpgme_op_vfs_mount_result, gpgme_op_vfs_mount): New. + (gpgme_op_g13_mount): Remove. + * libgpgme.vers: Likewise. + * engine-backend.h (struct engine_ops): Remove RESULT_CB and + RESULT_CB_VALUE args in opassuan_transact member. Add CANCEL_OP + member. + * ops.h (_gpgme_cancel_with_err, _gpgme_wait_on_condition): Add + OP_ERR argument. + (_gpgme_wait_one_ext): New prototype. + * context.h (ctx_op_data_id_t): Add OPDATA_VFS_MOUNT. + * engine-g13.c (g13_cancel_op): New function. + (parse_status): Remove declaration. + (g13_assuan_simple_command): Do nothing with status lines for now. + (status_handler): Update opaque value access. + (_gpgme_engine_ops_g13): Add new cancel_op member. + * gpgme.c (_gpgme_cancel_with_err): Add new parameter OP_ERR. + Handle operational errors. + (gpgme_cancel, gpgme_io_read, gpgme_io_write): Add debug output. + * data.c (_gpgme_data_inbound_handler) + (_gpgme_data_outbound_handler): Adjust opaque value access. + * engine-gpg.c (command_handler, status_handler) + (colon_line_handler): Likewise. + * engine-gpgsm.c (status_handler): Likewise. + * engine-gpg.c (_gpgme_engine_ops_gpg): Add cancel_op member. + * engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Likewise. + * g13.c: Rewritten (and will be rewritten again). + * engine.h (_gpgme_engine_op_assuan_transact): Remove result_cb + and result_cb_value parameters from prototype. + (_gpgme_engine_cancel_op): New prototype. + * engine.c (engine_ops) [! ENABLE_ASSUAN]: Add missing comma. + (_gpgme_engine_op_assuan_transact): Remove result_cb and + result_cb_value parameter. + (_gpgme_engine_cancel_op): New function. + * wait.h (_gpgme_run_io_cb): Add new argument OP_ERR. + (struct io_cb_data): New struct to pass opaque data and get a + op_err return value. Needed because we can't modify I/O callback + handler signature because it is exposed to the user. + * wait.c (_gpgme_run_io_cb): Add OP_ERR parameter. Handle + operational errors. + * wait-user.c (_gpgme_user_io_cb_handler): Handle operational + errors. + * wait-private.c (_gpgme_wait_on_condition): New argument to + retrieve the operational result. Handle operational errors in + session based protocols. + (_gpgme_wait_one_ext): New function. + (_gpgme_wait_one): Pass argument in invocation of + _gpgme_wait_on_condition. + * wait-global.c (struct ctx_list_item): Add member OP_ERR. + (ctx_done): New argument OP_ERR. + (ctx_wait): New argument OP_ERR. + (gpgme_wait_ext): New function based on gpgme_wait but handling + operational errors. + (gpgme_wait): Implement in term of gpgme_wait_ext. + * keylist.c (gpgme_op_keylist_next): Pass argument in invocation + of _gpgme_wait_on_condition. + * trustlist.c (gpgme_op_trustlist_next): Pass argument in + invocation of _gpgme_wait_on_condition. + * engine-assuan.c (struct engine_llass): Replace members RESULT_CB + and RESULT_CB_VALUE by LAST_OP_ERR. + (_gpgme_engine_assuan_last_op_err): Add this hack function. + (llass_cancel_op): New function. + (_gpgme_engine_llass_ops): Add cancel_op member. + (llass_status_handler): Update opaque value access. + (llass_transact): Remove RESULT_CB and RESULT_CB_VALUE arguments. + * opassuan.c: Move compat hacks to the end of file. + (opassuan_start): Do not set OPD->result.err. + Do not pass RESULT_Cb and CTX to _gpgme_engine_op_assuan_transact. + (gpgme_op_assuan_transact_ext): New function. + * debug.h (DEBUG_GLOBAL): New debug level. * conversion.c (gnupg_errors, _gpgme_map_gnupg_error): Removed. * data-user.c (gpgme_data_new_from_cbs): Add debug output. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/tests/ChangeLog 2009-10-26 18:52:32 UTC (rev 1406) @@ -1,3 +1,7 @@ +2009-10-26 Marcus Brinkmann + + * opassuan/t-command.c: Update to new interface. + 2009-10-15 Werner Koch * run-verify.c: New. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/configure.ac 2009-10-26 18:52:32 UTC (rev 1406) @@ -286,7 +286,7 @@ fi # Checks for system services -NEED_GPG_VERSION_DEFAULT=1.3.0 +NEED_GPG_VERSION_DEFAULT=1.4.0 NEED_GPGSM_VERSION_DEFAULT=1.9.6 NEED_GPGCONF_VERSION_DEFAULT=2.0.4 NEED_G13_VERSION_DEFAULT=2.1.0 Modified: trunk/src/context.h =================================================================== --- trunk/src/context.h 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/context.h 2009-10-26 18:52:32 UTC (rev 1406) @@ -38,7 +38,7 @@ { OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE, OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT, - OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN + OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN, OPDATA_VFS_MOUNT } ctx_op_data_id_t; Modified: trunk/src/data.c =================================================================== --- trunk/src/data.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/data.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -247,7 +247,8 @@ gpgme_error_t _gpgme_data_inbound_handler (void *opaque, int fd) { - gpgme_data_t dh = (gpgme_data_t) opaque; + struct io_cb_data *data = (struct io_cb_data *) opaque; + gpgme_data_t dh = (gpgme_data_t) data->handler_value; char buffer[BUFFER_SIZE]; char *bufp = buffer; ssize_t buflen; @@ -279,7 +280,8 @@ gpgme_error_t _gpgme_data_outbound_handler (void *opaque, int fd) { - gpgme_data_t dh = (gpgme_data_t) opaque; + struct io_cb_data *data = (struct io_cb_data *) opaque; + gpgme_data_t dh = (gpgme_data_t) data->handler_value; ssize_t nwritten; TRACE_BEG1 (DEBUG_CTX, "_gpgme_data_outbound_handler", dh, "fd=0x%x", fd); Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine-assuan.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -70,9 +70,8 @@ struct gpgme_io_cbs io_cbs; - /* Internal callbacks. */ - engine_assuan_result_cb_t result_cb; - void *result_cb_value; + /* Hack for old opassuan.c interface, see there the result struct. */ + gpg_error_t last_op_err; /* User provided callbacks. */ struct { @@ -95,7 +94,13 @@ typedef struct engine_llass *engine_llass_t; +gpg_error_t _gpgme_engine_assuan_last_op_err (void *engine) +{ + engine_llass_t llass = engine; + return llass->last_op_err; +} + /* Prototypes. */ static void llass_io_event (void *engine, gpgme_event_io_t type, void *type_data); @@ -169,6 +174,21 @@ } +static gpgme_error_t +llass_cancel_op (void *engine) +{ + engine_llass_t llass = engine; + + if (!llass) + return gpg_error (GPG_ERR_INV_VALUE); + + if (llass->status_cb.fd != -1) + _gpgme_io_close (llass->status_cb.fd); + + return 0; +} + + static void llass_release (void *engine) { @@ -408,8 +428,9 @@ static gpgme_error_t llass_status_handler (void *opaque, int fd) { + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_llass_t llass = (engine_llass_t) data->handler_value; gpgme_error_t err = 0; - engine_llass_t llass = opaque; char *line; size_t linelen; @@ -459,8 +480,6 @@ if (linelen && llass->user.data_cb) err = llass->user.data_cb (llass->user.data_cb_value, src, linelen); - else - err = 0; TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: D inlinedata; status from cb: %s", @@ -474,8 +493,6 @@ /* END received. Tell the data callback. */ if (llass->user.data_cb) err = llass->user.data_cb (llass->user.data_cb_value, NULL, 0); - else - err = 0; TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: END line; status from cb: %s", @@ -502,8 +519,6 @@ if (llass->user.status_cb) err = llass->user.status_cb (llass->user.status_cb_value, src, args); - else - err = 0; TRACE3 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: S line (%s) - status from cb: %s", @@ -554,17 +569,15 @@ TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: ERR line: %s", fd, err ? gpg_strerror (err) : "ok"); + /* Command execution errors are not fatal, as we use a session based protocol. */ - if (llass->result_cb) - err = llass->result_cb (llass->result_cb_value, err); - else - err = 0; - if (!err) - { - _gpgme_io_close (llass->status_cb.fd); - return 0; - } + data->op_err = err; + llass->last_op_err = err; + + /* The caller will do the rest (namely, call cancel_op, + which closes status_fd). */ + return 0; } else if (linelen >= 2 && line[0] == 'O' && line[1] == 'K' @@ -572,15 +585,11 @@ { TRACE1 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: OK line", fd); - if (llass->result_cb) - err = llass->result_cb (llass->result_cb_value, 0); - else - err = 0; - if (!err) - { - _gpgme_io_close (llass->status_cb.fd); - return 0; - } + + llass->last_op_err = 0; + + _gpgme_io_close (llass->status_cb.fd); + return 0; } else { @@ -667,8 +676,6 @@ static gpgme_error_t llass_transact (void *engine, const char *command, - engine_assuan_result_cb_t result_cb, - void *result_cb_value, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, gpgme_assuan_inquire_cb_t inq_cb, @@ -682,8 +689,6 @@ if (!llass || !command || !*command) return gpg_error (GPG_ERR_INV_VALUE); - llass->result_cb = result_cb; - llass->result_cb_value = result_cb_value; llass->user.data_cb = data_cb; llass->user.data_cb_value = data_cb_value; llass->user.inq_cb = inq_cb; @@ -754,5 +759,6 @@ NULL, /* conf_save */ llass_set_io_cbs, llass_io_event, - llass_cancel + llass_cancel, + llass_cancel_op }; Modified: trunk/src/engine-backend.h =================================================================== --- trunk/src/engine-backend.h 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine-backend.h 2009-10-26 18:52:32 UTC (rev 1406) @@ -98,8 +98,6 @@ unsigned int flags); gpgme_error_t (*opassuan_transact) (void *engine, const char *command, - engine_assuan_result_cb_t result_cb, - void *result_cb_value, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, gpgme_assuan_inquire_cb_t inq_cb, @@ -113,7 +111,11 @@ void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs); void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data); + /* Cancel the whole engine session. */ gpgme_error_t (*cancel) (void *engine); + + /* Cancel only the current operation, not the whole session. */ + gpgme_error_t (*cancel_op) (void *engine); }; Modified: trunk/src/engine-g13.c =================================================================== --- trunk/src/engine-g13.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine-g13.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -180,6 +180,21 @@ } +static gpgme_error_t +g13_cancel_op (void *engine) +{ + engine_g13_t g13 = engine; + + if (!g13) + return gpg_error (GPG_ERR_INV_VALUE); + + if (g13->status_cb.fd != -1) + _gpgme_io_close (g13->status_cb.fd); + + return 0; +} + + static void g13_release (void *engine) { @@ -385,9 +400,6 @@ } -/* Forward declaration. */ -static gpgme_status_code_t parse_status (const char *name); - static gpgme_error_t g13_assuan_simple_command (assuan_context_t ctx, char *cmd, engine_status_handler_t status_fnc, @@ -422,7 +434,6 @@ && line[0] == 'S' && line[1] == ' ') { char *rest; - gpgme_status_code_t r; rest = strchr (line + 2, ' '); if (!rest) @@ -430,12 +441,7 @@ else *(rest++) = 0; - r = parse_status (line + 2); - - if (r >= 0 && status_fnc) - err = status_fnc (status_fnc_value, r, rest); - else - err = gpg_error (GPG_ERR_GENERAL); + /* Nothing to do with status lines. */ } else err = gpg_error (GPG_ERR_GENERAL); @@ -449,8 +455,9 @@ static gpgme_error_t status_handler (void *opaque, int fd) { + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_g13_t g13 = (engine_g13_t) data->handler_value; gpgme_error_t err = 0; - engine_g13_t g13 = opaque; char *line; size_t linelen; @@ -792,5 +799,6 @@ NULL, /* conf_save */ g13_set_io_cbs, g13_io_event, - g13_cancel + g13_cancel, + g13_cancel_op, }; Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine-gpg.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -646,10 +646,10 @@ static gpgme_error_t command_handler (void *opaque, int fd) { + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_gpg_t gpg = (engine_gpg_t) data->handler_value; gpgme_error_t err; - engine_gpg_t gpg = (engine_gpg_t) opaque; int processed = 0; - assert (gpg->cmd.used); assert (gpg->cmd.code); assert (gpg->cmd.fnc); @@ -1139,7 +1139,8 @@ static gpgme_error_t status_handler (void *opaque, int fd) { - engine_gpg_t gpg = opaque; + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_gpg_t gpg = (engine_gpg_t) data->handler_value; int err; assert (fd == gpg->status.fd[0]); @@ -1246,7 +1247,8 @@ static gpgme_error_t colon_line_handler (void *opaque, int fd) { - engine_gpg_t gpg = opaque; + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_gpg_t gpg = (engine_gpg_t) data->handler_value; gpgme_error_t rc = 0; assert (fd == gpg->colon.fd[0]); @@ -2365,5 +2367,6 @@ NULL, /* conf_save */ gpg_set_io_cbs, gpg_io_event, - gpg_cancel + gpg_cancel, + NULL /* cancel_op */ }; Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine-gpgsm.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -761,8 +761,9 @@ static gpgme_error_t status_handler (void *opaque, int fd) { + struct io_cb_data *data = (struct io_cb_data *) opaque; + engine_gpgsm_t gpgsm = (engine_gpgsm_t) data->handler_value; gpgme_error_t err = 0; - engine_gpgsm_t gpgsm = opaque; char *line; size_t linelen; @@ -799,7 +800,7 @@ err = gpgsm->status.fnc (gpgsm->status.fnc_value, GPGME_STATUS_EOF, ""); - if (!err && gpgsm->colon.fnc && gpgsm->colon.any ) + if (!err && gpgsm->colon.fnc && gpgsm->colon.any) { /* We must tell a colon function about the EOF. We do this only when we have seen any data lines. Note @@ -1939,5 +1940,6 @@ NULL, /* conf_save */ gpgsm_set_io_cbs, gpgsm_io_event, - gpgsm_cancel + gpgsm_cancel, + NULL /* cancel_op */ }; Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -58,7 +58,7 @@ #ifdef ENABLE_ASSUAN &_gpgme_engine_ops_assuan, /* Low-Level Assuan. */ #else - NULL + NULL, #endif #ifdef ENABLE_G13 &_gpgme_engine_ops_g13 /* Crypto VFS. */ @@ -777,8 +777,6 @@ gpgme_error_t _gpgme_engine_op_assuan_transact (engine_t engine, const char *command, - engine_assuan_result_cb_t result_cb, - void *result_cb_value, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, gpgme_assuan_inquire_cb_t inq_cb, @@ -794,7 +792,6 @@ return (*engine->ops->opassuan_transact) (engine->engine, command, - result_cb, result_cb_value, data_cb, data_cb_value, inq_cb, inq_cb_value, status_cb, status_cb_value); @@ -848,6 +845,7 @@ } +/* Cancel the session and the pending operation if any. */ gpgme_error_t _gpgme_engine_cancel (engine_t engine) { @@ -859,3 +857,17 @@ return (*engine->ops->cancel) (engine->engine); } + + +/* Cancel the pending operation, but not the complete session. */ +gpgme_error_t +_gpgme_engine_cancel_op (engine_t engine) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->cancel_op) + return 0; + + return (*engine->ops->cancel_op) (engine->engine); +} Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/engine.h 2009-10-26 18:52:32 UTC (rev 1406) @@ -133,8 +133,6 @@ gpgme_error_t _gpgme_engine_op_assuan_transact (engine_t engine, const char *command, - engine_assuan_result_cb_t result_cb, - void *result_cb_value, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, gpgme_assuan_inquire_cb_t inq_cb, @@ -154,4 +152,6 @@ gpgme_error_t _gpgme_engine_cancel (engine_t engine); +gpgme_error_t _gpgme_engine_cancel_op (engine_t engine); + #endif /* ENGINE_H */ Modified: trunk/src/g13.c =================================================================== --- trunk/src/g13.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/g13.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -31,42 +31,20 @@ typedef struct { - struct _gpgme_op_g13_result result; + struct _gpgme_op_vfs_mount_result result; } *op_data_t; -/* This callback is used to return the status of the assuan command - back rather than transmission errors. */ -static gpgme_error_t -result_cb (void *priv, gpgme_error_t result) +gpgme_vfs_mount_result_t +gpgme_op_vfs_mount_result (gpgme_ctx_t ctx) { - gpgme_ctx_t ctx = (gpgme_ctx_t)priv; gpgme_error_t err; void *hook; op_data_t opd; - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); + err = _gpgme_op_data_lookup (ctx, OPDATA_VFS_MOUNT, &hook, -1, NULL); opd = hook; - if (err) - return err; - if (!opd) - return gpg_error (GPG_ERR_INTERNAL); - - opd->result.err = result; - return 0; -} - - -gpgme_g13_result_t -gpgme_op_g13_result (gpgme_ctx_t ctx) -{ - gpgme_error_t err; - void *hook; - op_data_t opd; - - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); - opd = hook; /* Check in case this function is used without having run a command before. */ if (err || !opd) @@ -77,14 +55,14 @@ static gpgme_error_t -opg13_start (gpgme_ctx_t ctx, int synchronous, - const char *command, - gpgme_assuan_data_cb_t data_cb, - void *data_cb_value, - gpgme_assuan_inquire_cb_t inq_cb, - void *inq_cb_value, - gpgme_assuan_status_cb_t status_cb, - void *status_cb_value) +vfs_start (gpgme_ctx_t ctx, int synchronous, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) { gpgme_error_t err; void *hook; @@ -99,14 +77,13 @@ if (err) return err; - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, sizeof (*opd), NULL); + err = _gpgme_op_data_lookup (ctx, OPDATA_VFS_MOUNT, &hook, sizeof (*opd), + NULL); opd = hook; if (err) return err; - opd->result.err = gpg_error (GPG_ERR_UNFINISHED); return _gpgme_engine_op_assuan_transact (ctx->engine, command, - result_cb, ctx, data_cb, data_cb_value, inq_cb, inq_cb_value, status_cb, status_cb_value); @@ -116,7 +93,7 @@ /* XXXX. This is the asynchronous variant. */ static gpgme_error_t -gpgme_op_g13_transact_start (gpgme_ctx_t ctx, +gpgme_op_vfs_transact_start (gpgme_ctx_t ctx, const char *command, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, @@ -125,59 +102,52 @@ gpgme_assuan_status_cb_t status_cb, void *status_cb_value) { - return opg13_start (ctx, 0, command, data_cb, data_cb_value, - inq_cb, inq_cb_value, status_cb, status_cb_value); + return vfs_start (ctx, 0, command, data_cb, data_cb_value, + inq_cb, inq_cb_value, status_cb, status_cb_value); } /* XXXX. This is the synchronous variant. */ static gpgme_error_t -gpgme_op_g13_transact (gpgme_ctx_t ctx, +gpgme_op_vfs_transact (gpgme_ctx_t ctx, const char *command, gpgme_assuan_data_cb_t data_cb, void *data_cb_value, gpgme_assuan_inquire_cb_t inq_cb, void *inq_cb_value, gpgme_assuan_status_cb_t status_cb, - void *status_cb_value) + void *status_cb_value, + gpgme_error_t *op_err) { gpgme_error_t err; - err = opg13_start (ctx, 1, command, data_cb, data_cb_value, - inq_cb, inq_cb_value, status_cb, status_cb_value); + err = vfs_start (ctx, 1, command, data_cb, data_cb_value, + inq_cb, inq_cb_value, status_cb, status_cb_value); if (!err) - err = _gpgme_wait_one (ctx); + err = _gpgme_wait_one_ext (ctx, op_err); return err; } /* The actual exported interface follows. */ -static gpg_error_t -get_err (gpgme_ctx_t ctx) -{ - gpgme_g13_result_t res; - - res = gpgme_op_g13_result (ctx); - if (! res) - return gpg_error (GPG_ERR_GENERAL); - - return res->err; -} - - /* The container is automatically unmounted when the context is reset or destroyed. This is a synchronous convenience interface, which automatically returns an operation error if there is no transmission error. */ gpgme_error_t -gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file, - const char *mount_dir, int flags) +gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, + const char *mount_dir, int flags, gpgme_error_t *op_err) { gpg_error_t err; char *cmd; char *container_file_esc = NULL; - + + /* We want to encourage people to check error values, so not getting + them is discouraged here. Also makes our code easier. */ + if (! op_err) + return gpg_error (GPG_ERR_INV_VALUE); + err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0); if (err) return err; @@ -190,11 +160,10 @@ } free (container_file_esc); - err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL, - NULL, NULL); + err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, + NULL, NULL, op_err); free (cmd); - err = err || get_err (ctx); - if (err) + if (err || *op_err) return err; if (mount_dir) @@ -219,11 +188,9 @@ return gpg_error_from_syserror (); } - err = gpgme_op_g13_transact (ctx, cmd, NULL, NULL, NULL, NULL, - NULL, NULL); + err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL, + NULL, NULL, op_err); free (cmd); - /* Note: in symmetry with the asynchronous variant, we don't return - the error in the result structure here, if any. */ return err; } Modified: trunk/src/gpgme.c =================================================================== --- trunk/src/gpgme.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/gpgme.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -46,7 +46,7 @@ gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; /* Protects all reference counters in result structures. All other - accesses to a key are read only. */ + accesses to a result structure are read only. */ DEFINE_STATIC_LOCK (result_ref_lock); @@ -118,18 +118,33 @@ gpgme_error_t -_gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err) +_gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err, + gpg_error_t op_err) { gpgme_error_t err; - TRACE_BEG1 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i", - ctx_err); + struct gpgme_io_event_done_data data; - err = _gpgme_engine_cancel (ctx->engine); - if (err) - return TRACE_ERR (err); + TRACE_BEG2 (DEBUG_CTX, "_gpgme_cancel_with_err", ctx, "ctx_err=%i, op_err=%i", + ctx_err, op_err); - _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &ctx_err); + if (ctx_err) + { + err = _gpgme_engine_cancel (ctx->engine); + if (err) + return TRACE_ERR (err); + } + else + { + err = _gpgme_engine_cancel_op (ctx->engine); + if (err) + return TRACE_ERR (err); + } + data.err = ctx_err; + data.op_err = op_err; + + _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data); + return TRACE_ERR (0); } @@ -138,7 +153,13 @@ gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx) { - return _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED)); + gpg_error_t err; + + TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx); + + err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0); + + return TRACE_ERR (err); } @@ -486,10 +507,12 @@ gpgme_io_read (int fd, void *buffer, size_t count) { int ret; + TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_read", fd, + "buffer=%p, count=%u", buffer, count); ret = _gpgme_io_read (fd, buffer, count); - return ret; + return TRACE_SYSRES (ret); } @@ -500,10 +523,12 @@ gpgme_io_write (int fd, const void *buffer, size_t count) { int ret; + TRACE_BEG2 (DEBUG_GLOBAL, "gpgme_io_write", fd, + "buffer=%p, count=%u", buffer, count); ret = _gpgme_io_write (fd, buffer, count); - return ret; + return TRACE_SYSRES (ret); } Modified: trunk/src/gpgme.def =================================================================== --- trunk/src/gpgme.def 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/gpgme.def 2009-10-26 18:52:32 UTC (rev 1406) @@ -185,7 +185,11 @@ gpgme_op_export_keys @142 gpgme_op_export_keys_start @143 - gpgme_op_g13_mount @144 + gpgme_op_assuan_transact_ext @144 + gpgme_wait_ext @145 + gpgme_op_vfs_mount_result @146 + gpgme_op_vfs_mount @147 + ; END Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/gpgme.h.in 2009-10-26 18:52:32 UTC (rev 1406) @@ -960,6 +960,17 @@ } gpgme_event_io_t; +struct gpgme_io_event_done_data +{ + /* A fatal IPC error or an operational error in state-less + protocols. */ + gpgme_error_t err; + + /* An operational errors in session-based protocols. */ + gpgme_error_t op_err; +}; +typedef struct gpgme_io_event_done_data *gpgme_io_event_done_data_t; + /* The type of a function that is called when a context finished an operation. */ typedef void (*gpgme_event_io_cb_t) (void *data, gpgme_event_io_t type, @@ -990,6 +1001,9 @@ the pending operation to finish. */ gpgme_ctx_t gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang); +gpgme_ctx_t gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status, + gpgme_error_t *op_err, int hang); + /* Functions to handle data objects. */ @@ -1733,21 +1747,6 @@ typedef gpgme_error_t (*gpgme_assuan_status_cb_t) (void *opaque, const char *status, const char *args); -struct _gpgme_op_assuan_result -{ - /* The result of the actual assuan command. An OK is indicated by a - value of 0 and an ERR by the respective error error value. This - is required because assuan operations use a session-based - interface. The error code of the GPGME function calls just - reflects transmission errors. */ - gpgme_error_t err; -}; -typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t; - - -/* Return the result of the last Assuan command. */ -gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx); - /* Send the Assuan COMMAND and return results via the callbacks. Asynchronous variant. */ gpgme_error_t gpgme_op_assuan_transact_start (gpgme_ctx_t ctx, @@ -1761,35 +1760,56 @@ /* Send the Assuan COMMAND and return results via the callbacks. Synchronous variant. */ -gpgme_error_t gpgme_op_assuan_transact (gpgme_ctx_t ctx, - const char *command, - gpgme_assuan_data_cb_t data_cb, - void *data_cb_value, - gpgme_assuan_inquire_cb_t inq_cb, - void *inq_cb_value, - gpgme_assuan_status_cb_t stat_cb, - void *stat_cb_value); +gpgme_error_t gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t stat_cb, + void *stat_cb_value, + gpgme_error_t *op_err); +/* Compat. */ +struct _gpgme_op_assuan_result +{ + /* Deprecated. Use the second value in a DONE event or the + synchronous variant gpgme_op_assuan_transact_ext. */ + gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME; +}; +typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t; + +/* Return the result of the last Assuan command. */ +gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx) + _GPGME_DEPRECATED; + +gpgme_error_t +gpgme_op_assuan_transact (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) _GPGME_DEPRECATED; + /* Crypto container support. */ -struct _gpgme_op_g13_result +struct _gpgme_op_vfs_mount_result { - /* The result of the actual assuan command. An OK is indicated by a - value of 0 and an ERR by the respective error error value. This - is required because assuan operations use a session-based - interface. The error code of the GPGME function calls just - reflects transmission errors. */ - gpgme_error_t err; + char *mount_dir; }; -typedef struct _gpgme_op_g13_result *gpgme_g13_result_t; +typedef struct _gpgme_op_vfs_mount_result *gpgme_vfs_mount_result_t; +gpgme_vfs_mount_result_t gpgme_op_vfs_mount_result (gpgme_ctx_t ctx); + /* The container is automatically unmounted when the context is reset - or destroyed. This is a synchronous convenience interface, which - automatically returns an operation error if there is no - transmission error. */ -gpgme_error_t gpgme_op_g13_mount (gpgme_ctx_t ctx, const char *container_file, - const char *mount_dir, int flags); + or destroyed. Transmission errors are returned directly, + operational errors are returned in OP_ERR. */ +gpgme_error_t gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, + const char *mount_dir, int flags, + gpgme_error_t *op_err); /* Interface to gpgconf(1). */ Modified: trunk/src/keylist.c =================================================================== --- trunk/src/keylist.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/keylist.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -928,7 +928,7 @@ if (!opd->key_queue) { - err = _gpgme_wait_on_condition (ctx, &opd->key_cond); + err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL); if (err) return err; Modified: trunk/src/libgpgme.vers =================================================================== --- trunk/src/libgpgme.vers 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/libgpgme.vers 2009-10-26 18:52:32 UTC (rev 1406) @@ -65,7 +65,12 @@ gpgme_op_export_keys; gpgme_op_export_keys_start; - gpgme_op_g13_mount; + gpgme_op_assuan_transact_ext; + + gpgme_wait_ext; + + gpgme_op_vfs_mount_result; + gpgme_op_vfs_mount; }; Modified: trunk/src/opassuan.c =================================================================== --- trunk/src/opassuan.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/opassuan.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -26,59 +26,7 @@ #include "ops.h" #include "util.h" - -typedef struct -{ - struct _gpgme_op_assuan_result result; - -} *op_data_t; - - - - -/* This callback is used to return the status of the assuan command - back. Note that this is different from the error code returned - from gpgme_op_assuan_transact because the later only reflects error - with the connection. */ static gpgme_error_t -result_cb (void *priv, gpgme_error_t result) -{ - gpgme_ctx_t ctx = (gpgme_ctx_t)priv; - gpgme_error_t err; - void *hook; - op_data_t opd; - - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); - opd = hook; - if (err) - return err; - if (!opd) - return gpg_error (GPG_ERR_INTERNAL); - - opd->result.err = result; - return 0; -} - - -gpgme_assuan_result_t -gpgme_op_assuan_result (gpgme_ctx_t ctx) -{ - gpgme_error_t err; - void *hook; - op_data_t opd; - - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); - opd = hook; - /* Check in case this function is used without having run a command - before. */ - if (err || !opd) - return NULL; - - return &opd->result; -} - - -static gpgme_error_t opassuan_start (gpgme_ctx_t ctx, int synchronous, const char *command, gpgme_assuan_data_cb_t data_cb, @@ -89,8 +37,6 @@ void *status_cb_value) { gpgme_error_t err; - void *hook; - op_data_t opd; if (!command || !*command) return gpg_error (GPG_ERR_INV_VALUE); @@ -101,14 +47,7 @@ if (err) return err; - err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, sizeof (*opd), NULL); - opd = hook; - if (err) - return err; - opd->result.err = gpg_error (GPG_ERR_UNFINISHED); - return _gpgme_engine_op_assuan_transact (ctx->engine, command, - result_cb, ctx, data_cb, data_cb_value, inq_cb, inq_cb_value, status_cb, status_cb_value); @@ -119,13 +58,13 @@ /* XXXX. This is the asynchronous variant. */ gpgme_error_t gpgme_op_assuan_transact_start (gpgme_ctx_t ctx, - const char *command, - gpgme_assuan_data_cb_t data_cb, - void *data_cb_value, - gpgme_assuan_inquire_cb_t inq_cb, - void *inq_cb_value, - gpgme_assuan_status_cb_t status_cb, - void *status_cb_value) + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) { return opassuan_start (ctx, 0, command, data_cb, data_cb_value, @@ -136,14 +75,15 @@ /* XXXX. This is the synchronous variant. */ gpgme_error_t -gpgme_op_assuan_transact (gpgme_ctx_t ctx, - const char *command, - gpgme_assuan_data_cb_t data_cb, - void *data_cb_value, - gpgme_assuan_inquire_cb_t inq_cb, - void *inq_cb_value, - gpgme_assuan_status_cb_t status_cb, - void *status_cb_value) +gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value, + gpgme_error_t *op_err) { gpgme_error_t err; @@ -152,7 +92,70 @@ inq_cb, inq_cb_value, status_cb, status_cb_value); if (!err) - err = _gpgme_wait_one (ctx); + err = _gpgme_wait_one_ext (ctx, op_err); return err; } + + + +/* Compatibility code for old interface. */ + +/* Evil hack breaking abstractions for the purpose of localizing our + other hack. This is copied from engine.c. */ +struct engine +{ + struct engine_ops *ops; + void *engine; +}; + +typedef struct +{ + struct _gpgme_op_assuan_result result; +} *op_data_t; + +gpg_error_t _gpgme_engine_assuan_last_op_err (void *engine); + +gpgme_assuan_result_t +gpgme_op_assuan_result (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); + opd = hook; + /* Check in case this function is used without having run a command + before. */ + if (err || !opd) + return NULL; + + /* All of this is a hack for the old style interface. The new style + interface returns op errors directly. */ + opd->result.err = _gpgme_engine_assuan_last_op_err (ctx->engine->engine); + + return &opd->result; +} + + +gpgme_error_t +gpgme_op_assuan_transact (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + gpgme_error_t op_err; + gpgme_error_t err; + + /* Users of the old-style session based interfaces need to look at + the result structure. */ + gpgme_op_assuan_transact_ext (ctx, command, data_cb, data_cb_value, + inq_cb, inq_cb_value, + status_cb, status_cb_value, &op_err); + + return err; +} Modified: trunk/src/ops.h =================================================================== --- trunk/src/ops.h 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/ops.h 2009-10-26 18:52:32 UTC (rev 1406) @@ -27,14 +27,17 @@ /* From gpgme.c. */ -gpgme_error_t _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err); +gpgme_error_t _gpgme_cancel_with_err (gpgme_ctx_t ctx, gpg_error_t ctx_err, + gpg_error_t op_err); void _gpgme_release_result (gpgme_ctx_t ctx); /* From wait.c. */ gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx); -gpgme_error_t _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond); +gpgme_error_t _gpgme_wait_one_ext (gpgme_ctx_t ctx, gpgme_error_t *op_err); +gpgme_error_t _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond, + gpgme_error_t *op_err); /* From data.c. */ Modified: trunk/src/trustlist.c =================================================================== --- trunk/src/trustlist.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/trustlist.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -220,7 +220,7 @@ if (!opd->trust_queue) { - err = _gpgme_wait_on_condition (ctx, &opd->trust_cond); + err = _gpgme_wait_on_condition (ctx, &opd->trust_cond, NULL); if (err) return err; if (!opd->trust_cond) Modified: trunk/src/wait-global.c =================================================================== --- trunk/src/wait-global.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/wait-global.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -74,6 +74,7 @@ gpgme_ctx_t ctx; /* The status is set when the ctx is moved to the done list. */ gpgme_error_t status; + gpgme_error_t op_err; }; /* The active list contains all contexts that are in the global event @@ -112,7 +113,7 @@ /* Enter the context CTX into the done list with status STATUS. */ static void -ctx_done (gpgme_ctx_t ctx, gpgme_error_t status) +ctx_done (gpgme_ctx_t ctx, gpgme_error_t status, gpgme_error_t op_err) { struct ctx_list_item *li; @@ -131,6 +132,7 @@ ctx_active_list = li->next; li->status = status; + li->op_err = op_err; /* Add LI to done list. */ li->next = ctx_done_list; @@ -147,7 +149,7 @@ If a matching context could be found, return it. Return NULL if no context could be found. */ static gpgme_ctx_t -ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status) +ctx_wait (gpgme_ctx_t ctx, gpgme_error_t *status, gpgme_error_t *op_err) { struct ctx_list_item *li; @@ -164,6 +166,8 @@ ctx = li->ctx; if (status) *status = li->status; + if (op_err) + *op_err = li->op_err; /* Remove LI from done list. */ if (li->next) @@ -203,15 +207,16 @@ if (err) /* An error occured. Close all fds in this context, and send the error in a done event. */ - _gpgme_cancel_with_err (ctx, err); + _gpgme_cancel_with_err (ctx, err, 0); } break; case GPGME_EVENT_DONE: { - gpgme_error_t *errp = (gpgme_error_t *) type_data; - assert (errp); - ctx_done (ctx, *errp); + gpgme_io_event_done_data_t done_data = + (gpgme_io_event_done_data_t) type_data; + + ctx_done (ctx, done_data->err, done_data->op_err); } break; @@ -246,7 +251,8 @@ error occurs, NULL is returned and *STATUS is set to the error value. */ gpgme_ctx_t -gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang) +gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status, + gpgme_error_t *op_err, int hang) { do { @@ -266,6 +272,8 @@ UNLOCK (ctx_list_lock); if (status) *status = gpg_error_from_errno (saved_errno); + if (op_err) + *op_err = 0; return NULL; } fdt.size = i; @@ -285,6 +293,8 @@ free (fdt.fds); if (status) *status = gpg_error_from_errno (saved_errno); + if (op_err) + *op_err = 0; return NULL; } @@ -294,6 +304,7 @@ { gpgme_ctx_t ictx; gpgme_error_t err = 0; + gpgme_error_t local_op_err = 0; struct wait_item_s *item; assert (nr); @@ -310,12 +321,12 @@ UNLOCK (ctx->lock); if (!err) - err = _gpgme_run_io_cb (&fdt.fds[i], 0); - if (err) + err = _gpgme_run_io_cb (&fdt.fds[i], 0, &local_op_err); + if (err || local_op_err) { /* An error occured. Close all fds in this context, and signal it. */ - _gpgme_cancel_with_err (ictx, err); + _gpgme_cancel_with_err (ictx, err, local_op_err); /* Break out of the loop, and retry the select() from scratch, because now all fds should be @@ -338,8 +349,10 @@ break; if (i == actx->fdt.size) { - gpgme_error_t err = 0; - + struct gpgme_io_event_done_data data; + data.err = 0; + data.op_err = 0; + /* FIXME: This does not perform too well. We have to release the lock because the I/O event handler acquires it to remove the context from the active @@ -349,7 +362,7 @@ contexts to be released and call the DONE events afterwards. */ UNLOCK (ctx_list_lock); - _gpgme_engine_io_event (actx->engine, GPGME_EVENT_DONE, &err); + _gpgme_engine_io_event (actx->engine, GPGME_EVENT_DONE, &data); LOCK (ctx_list_lock); goto retry; } @@ -357,7 +370,7 @@ UNLOCK (ctx_list_lock); { - gpgme_ctx_t dctx = ctx_wait (ctx, status); + gpgme_ctx_t dctx = ctx_wait (ctx, status, op_err); if (dctx) { @@ -369,6 +382,8 @@ ctx = NULL; if (status) *status = 0; + if (op_err) + *op_err = 0; } } } @@ -376,3 +391,10 @@ return ctx; } + + +gpgme_ctx_t +gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang) +{ + return gpgme_wait_ext (ctx, status, NULL, hang); +} Modified: trunk/src/wait-private.c =================================================================== --- trunk/src/wait-private.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/wait-private.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -72,7 +72,8 @@ finished and return its error value. Otherwise, wait until COND is satisfied or the operation finished. */ gpgme_error_t -_gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond) +_gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond, + gpgme_error_t *op_err_p) { gpgme_error_t err = 0; int hang = 1; @@ -87,8 +88,10 @@ /* An error occured. Close all fds in this context, and signal it. */ err = gpg_error_from_errno (errno); - _gpgme_cancel_with_err (ctx, err); + _gpgme_cancel_with_err (ctx, err, 0); + if (op_err_p) + *op_err_p = 0; return err; } @@ -96,6 +99,8 @@ { if (ctx->fdt.fds[i].fd != -1 && ctx->fdt.fds[i].signaled) { + gpgme_error_t op_err = 0; + ctx->fdt.fds[i].signaled = 0; assert (nr); nr--; @@ -106,15 +111,33 @@ UNLOCK (ctx->lock); if (!err) - err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0); + err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0, &op_err); if (err) { /* An error occured. Close all fds in this context, and signal it. */ - _gpgme_cancel_with_err (ctx, err); + _gpgme_cancel_with_err (ctx, err, 0); + if (op_err_p) + *op_err_p = 0; return err; } + else if (op_err) + { + /* An operational error occured. Cancel the current + operation but not the session, and signal it. */ + _gpgme_cancel_with_err (ctx, 0, op_err); + + /* NOTE: This relies on the operational error being + generated after the operation really has + completed, for example after no further status + line output is generated. Otherwise the + following I/O will spill over into the next + operation. */ + if (op_err_p) + *op_err_p = op_err; + return 0; + } } } @@ -123,7 +146,10 @@ break; if (i == ctx->fdt.size) { - _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err); + struct gpgme_io_event_done_data data; + data.err = 0; + data.op_err = 0; + _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &data); hang = 0; } if (cond && *cond) @@ -131,14 +157,26 @@ } while (hang); + if (op_err_p) + *op_err_p = 0; return 0; } /* Wait until the blocking operation in context CTX has finished and - return the error value. */ + return the error value. This variant can not be used for + session-based protocols. */ gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx) { - return _gpgme_wait_on_condition (ctx, NULL); + return _gpgme_wait_on_condition (ctx, NULL, NULL); } + +/* Wait until the blocking operation in context CTX has finished and + return the error value. This is the right variant to use for + sesion-based protocols. */ +gpgme_error_t +_gpgme_wait_one_ext (gpgme_ctx_t ctx, gpgme_error_t *op_err) +{ + return _gpgme_wait_on_condition (ctx, NULL, op_err); +} Modified: trunk/src/wait-user.c =================================================================== --- trunk/src/wait-user.c 2009-10-26 17:38:39 UTC (rev 1405) +++ trunk/src/wait-user.c 2009-10-26 18:52:32 UTC (rev 1406) @@ -41,6 +41,7 @@ From cvs at cvs.gnupg.org Tue Oct 27 20:23:57 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 27 Oct 2009 20:23:57 +0100 Subject: [svn] gpgme - r1407 - trunk/src Message-ID: Author: marcus Date: 2009-10-27 20:23:56 +0100 (Tue, 27 Oct 2009) New Revision: 1407 Modified: trunk/src/ChangeLog trunk/src/debug.h trunk/src/decrypt.c trunk/src/edit.c trunk/src/encrypt-sign.c trunk/src/encrypt.c trunk/src/export.c trunk/src/genkey.c trunk/src/getauditlog.c trunk/src/import.c trunk/src/keylist.c trunk/src/opassuan.c trunk/src/signers.c trunk/src/trustlist.c trunk/src/verify.c trunk/src/wait-private.c Log: 2009-10-27 Marcus Brinkmann * edit.c (gpgme_op_edit_start, gpgme_op_edit) (gpgme_op_card_edit_start, gpgme_op_card_edit): Add debug output. * encrypt-sign.c (gpgme_op_encrypt_sign_start) (gpgme_op_encrypt_sign): Likewise. * encrypt.c (gpgme_op_encrypt_start, gpgme_op_encrypt) (gpgme_op_encrypt_result): Likewise. * export.c (gpgme_op_export_start, gpgme_op_export) (gpgme_op_export_ext_start, gpgme_op_export_ext) (gpgme_op_export_keys_start, gpgme_op_export_keys): Likewise. * genkey.c (gpgme_op_genkey_start, gpgme_op_genkey) (gpgme_op_genkey_result): Likewise. * getauditlog.c (gpgme_op_getauditlog_start) (gpgme_op_getauditlog): Likewise. * import.c (gpgme_op_import_result, gpgme_op_import_start) (gpgme_op_import): Likewise. * keylist.c (gpgme_op_keylist_result, keylist_colon_handler) (gpgme_op_keylist_start, gpgme_op_keylist_ext_start) (gpgme_op_keylist_next, gpgme_op_keylist_end, gpgme_get_key): Likewise. * opassuan.c (gpgme_op_assuan_transact_start) (gpgme_op_assuan_transact_ext, gpgme_op_assuan_result) (gpgme_op_assuan_transact): Likewise. * signers.c (gpgme_signers_add, gpgme_signers_clear): Likewise. * trustlist.c (gpgme_op_trustlist_start) (gpgme_op_trustlist_next, gpgme_op_trustlist_end): Likewise. * verify.c (gpgme_op_verify_start, gpgme_op_verify) (gpgme_op_verify_result): Likewise. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/ChangeLog 2009-10-27 19:23:56 UTC (rev 1407) @@ -1,3 +1,32 @@ +2009-10-27 Marcus Brinkmann + + * edit.c (gpgme_op_edit_start, gpgme_op_edit) + (gpgme_op_card_edit_start, gpgme_op_card_edit): Add debug output. + * encrypt-sign.c (gpgme_op_encrypt_sign_start) + (gpgme_op_encrypt_sign): Likewise. + * encrypt.c (gpgme_op_encrypt_start, gpgme_op_encrypt) + (gpgme_op_encrypt_result): Likewise. + * export.c (gpgme_op_export_start, gpgme_op_export) + (gpgme_op_export_ext_start, gpgme_op_export_ext) + (gpgme_op_export_keys_start, gpgme_op_export_keys): Likewise. + * genkey.c (gpgme_op_genkey_start, gpgme_op_genkey) + (gpgme_op_genkey_result): Likewise. + * getauditlog.c (gpgme_op_getauditlog_start) + (gpgme_op_getauditlog): Likewise. + * import.c (gpgme_op_import_result, gpgme_op_import_start) + (gpgme_op_import): Likewise. + * keylist.c (gpgme_op_keylist_result, keylist_colon_handler) + (gpgme_op_keylist_start, gpgme_op_keylist_ext_start) + (gpgme_op_keylist_next, gpgme_op_keylist_end, gpgme_get_key): Likewise. + * opassuan.c (gpgme_op_assuan_transact_start) + (gpgme_op_assuan_transact_ext, gpgme_op_assuan_result) + (gpgme_op_assuan_transact): Likewise. + * signers.c (gpgme_signers_add, gpgme_signers_clear): Likewise. + * trustlist.c (gpgme_op_trustlist_start) + (gpgme_op_trustlist_next, gpgme_op_trustlist_end): Likewise. + * verify.c (gpgme_op_verify_start, gpgme_op_verify) + (gpgme_op_verify_result): Likewise. + 2009-10-26 Marcus Brinkmann * gpgme.h.in (struct gpgme_io_event_done_data) Modified: trunk/src/debug.h =================================================================== --- trunk/src/debug.h 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/debug.h 2009-10-27 19:23:56 UTC (rev 1407) @@ -117,6 +117,25 @@ _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ _gpgme_trace_func, _gpgme_trace_tagname, \ _gpgme_trace_tag, arg1, arg2, arg3, arg4), 0 +#define TRACE_BEG5(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5) \ + _TRACE (lvl, name, tag); \ + _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ + _gpgme_trace_func, _gpgme_trace_tagname, \ + _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5), 0 +#define TRACE_BEG7(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) \ + _TRACE (lvl, name, tag); \ + _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ + _gpgme_trace_func, _gpgme_trace_tagname, \ + _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7), 0 +#define TRACE_BEG8(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7, arg8) \ + _TRACE (lvl, name, tag); \ + _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ + _gpgme_trace_func, _gpgme_trace_tagname, \ + _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7, arg8), 0 #define TRACE(lvl, name, tag) \ _gpgme_debug (lvl, "%s (%s=%p): call\n", \ @@ -199,6 +218,10 @@ _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ _gpgme_trace_func, _gpgme_trace_tagname, \ _gpgme_trace_tag, arg1, arg2, arg3, arg4), 0 +#define TRACE_LOG5(fmt, arg1, arg2, arg3, arg4, arg5) \ + _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ + _gpgme_trace_func, _gpgme_trace_tagname, \ + _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5), 0 #define TRACE_LOG6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \ _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ _gpgme_trace_func, _gpgme_trace_tagname, \ Modified: trunk/src/decrypt.c =================================================================== --- trunk/src/decrypt.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/decrypt.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -379,7 +379,7 @@ { gpgme_error_t err; - TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_start", ctx, + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt", ctx, "cipher=%p, plain=%p", cipher, plain); err = decrypt_start (ctx, 1, cipher, plain); if (!err) Modified: trunk/src/edit.c =================================================================== --- trunk/src/edit.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/edit.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -24,6 +24,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -138,7 +139,11 @@ gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out) { - return edit_start (ctx, 0, 0, key, fnc, fnc_value, out); + TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit_start", ctx, + "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", fnc, fnc_value, out); + return TRACE_ERR (edit_start (ctx, 0, 0, key, fnc, fnc_value, out)); } @@ -148,10 +153,18 @@ gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out) { - gpgme_error_t err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out); + gpgme_error_t err; + + TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit", ctx, + "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", fnc, fnc_value, out); + + err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out); + if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } @@ -160,7 +173,11 @@ gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out) { - return edit_start (ctx, 0, 1, key, fnc, fnc_value, out); + TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit_start", ctx, + "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", fnc, fnc_value, out); + return TRACE_ERR (edit_start (ctx, 0, 1, key, fnc, fnc_value, out)); } @@ -170,8 +187,14 @@ gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out) { - gpgme_error_t err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out); + gpgme_error_t err; + + TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit", ctx, + "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, + (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid", fnc, fnc_value, out); + err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/encrypt-sign.c =================================================================== --- trunk/src/encrypt-sign.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/encrypt-sign.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -24,6 +24,7 @@ #endif #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -91,7 +92,23 @@ gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher) { - return encrypt_sign_start (ctx, 0, recp, flags, plain, cipher); + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx, + "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher); + + if (_gpgme_debug_trace () && recp) + { + int i = 0; + + while (recp[i]) + { + TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], + (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + recp[i]->subkeys->fpr : "invalid"); + i++; + } + } + + return TRACE_ERR (encrypt_sign_start (ctx, 0, recp, flags, plain, cipher)); } @@ -103,8 +120,26 @@ gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher) { - gpgme_error_t err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher); + gpgme_error_t err; + + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign", ctx, + "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher); + + if (_gpgme_debug_trace () && recp) + { + int i = 0; + + while (recp[i]) + { + TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], + (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + recp[i]->subkeys->fpr : "invalid"); + i++; + } + } + + err = encrypt_sign_start (ctx, 1, recp, flags, plain, cipher); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/encrypt.c =================================================================== --- trunk/src/encrypt.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/encrypt.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -27,6 +27,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -66,12 +67,33 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_encrypt_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + if (_gpgme_debug_trace ()) + { + gpgme_invalid_key_t invkeys = opd->result.invalid_recipients; + int i = 0; + + while (invkeys) + { + TRACE_LOG3 ("invalid_recipients[%i] = %s (%s)", + i, invkeys->fpr ? invkeys->fpr : "(null)", + gpg_strerror (invkeys->reason)); + invkeys = invkeys->next; + i++; + } + } + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -205,7 +227,23 @@ gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher) { - return encrypt_start (ctx, 0, recp, flags, plain, cipher); + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_start", ctx, + "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher); + + if (_gpgme_debug_trace () && recp) + { + int i = 0; + + while (recp[i]) + { + TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], + (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + recp[i]->subkeys->fpr : "invalid"); + i++; + } + } + + return TRACE_ERR (encrypt_start (ctx, 0, recp, flags, plain, cipher)); } @@ -216,8 +254,26 @@ gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t cipher) { - gpgme_error_t err = encrypt_start (ctx, 1, recp, flags, plain, cipher); + gpgme_error_t err; + + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt", ctx, + "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher); + + if (_gpgme_debug_trace () && recp) + { + int i = 0; + + while (recp[i]) + { + TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i], + (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + recp[i]->subkeys->fpr : "invalid"); + i++; + } + } + + err = encrypt_start (ctx, 1, recp, flags, plain, cipher); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/export.c =================================================================== --- trunk/src/export.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/export.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -26,6 +26,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -74,7 +75,9 @@ gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern, gpgme_export_mode_t mode, gpgme_data_t keydata) { - return export_start (ctx, 0, pattern, mode, keydata); + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_export_start", ctx, + "pattern=%s, mode=0x%x, keydata=%p", pattern, mode, keydata); + return TRACE_ERR (export_start (ctx, 0, pattern, mode, keydata)); } @@ -83,7 +86,12 @@ gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, gpgme_export_mode_t mode, gpgme_data_t keydata) { - gpgme_error_t err = export_start (ctx, 1, pattern, mode, keydata); + gpgme_error_t err; + + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_export", ctx, + "pattern=%s, mode=0x%x, keydata=%p", pattern, mode, keydata); + + err = export_start (ctx, 1, pattern, mode, keydata); if (!err) err = _gpgme_wait_one (ctx); return err; @@ -126,7 +134,21 @@ gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[], gpgme_export_mode_t mode, gpgme_data_t keydata) { - return export_ext_start (ctx, 0, pattern, mode, keydata); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_ext_start", ctx, + "mode=0x%x, keydata=%p", mode, keydata); + + if (_gpgme_debug_trace () && pattern) + { + int i = 0; + + while (pattern[i]) + { + TRACE_LOG2 ("pattern[%i] = %s", i, pattern[i]); + i++; + } + } + + return TRACE_ERR (export_ext_start (ctx, 0, pattern, mode, keydata)); } @@ -135,10 +157,26 @@ gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[], gpgme_export_mode_t mode, gpgme_data_t keydata) { - gpgme_error_t err = export_ext_start (ctx, 1, pattern, mode, keydata); + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_ext_start", ctx, + "mode=0x%x, keydata=%p", mode, keydata); + + if (_gpgme_debug_trace () && pattern) + { + int i = 0; + + while (pattern[i]) + { + TRACE_LOG2 ("pattern[%i] = %s", i, pattern[i]); + i++; + } + } + + err = export_ext_start (ctx, 1, pattern, mode, keydata); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } @@ -206,7 +244,23 @@ gpgme_export_mode_t mode, gpgme_data_t keydata) { - return export_keys_start (ctx, 0, keys, mode, keydata); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_keys_start", ctx, + "mode=0x%x, keydata=%p", mode, keydata); + + if (_gpgme_debug_trace () && keys) + { + int i = 0; + + while (keys[i]) + { + TRACE_LOG3 ("keys[%i] = %p (%s)", i,keys[i], + (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + keys[i]->subkeys->fpr : "invalid"); + i++; + } + } + + return TRACE_ERR (export_keys_start (ctx, 0, keys, mode, keydata)); } gpgme_error_t @@ -215,7 +269,25 @@ gpgme_export_mode_t mode, gpgme_data_t keydata) { - gpgme_error_t err = export_keys_start (ctx, 1, keys, mode, keydata); + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_keys", ctx, + "mode=0x%x, keydata=%p", mode, keydata); + + if (_gpgme_debug_trace () && keys) + { + int i = 0; + + while (keys[i]) + { + TRACE_LOG3 ("keys[%i] = %p (%s)", i,keys[i], + (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + keys[i]->subkeys->fpr : "invalid"); + i++; + } + } + + err = export_keys_start (ctx, 1, keys, mode, keydata); if (!err) err = _gpgme_wait_one (ctx); return err; Modified: trunk/src/genkey.c =================================================================== --- trunk/src/genkey.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/genkey.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -27,6 +27,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -59,11 +60,21 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_genkey_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + TRACE_LOG3 ("fpr = %s, %s, %s", opd->result.fpr, + opd->result.primary ? "primary" : "no primary", + opd->result.sub ? "sub" : "no sub"); + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -186,7 +197,10 @@ gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey, gpgme_data_t seckey) { - return genkey_start (ctx, 0, parms, pubkey, seckey); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_genkey_start", ctx, + "pubkey=%p, seckey=%p", pubkey, seckey); + TRACE_LOGBUF (parms, strlen (parms)); + return TRACE_ERR (genkey_start (ctx, 0, parms, pubkey, seckey)); } @@ -199,6 +213,10 @@ { gpgme_error_t err; + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_genkey", ctx, + "pubkey=%p, seckey=%p", pubkey, seckey); + TRACE_LOGBUF (parms, strlen (parms)); + err = genkey_start (ctx, 1, parms, pubkey, seckey); if (!err) err = _gpgme_wait_one (ctx); Modified: trunk/src/getauditlog.c =================================================================== --- trunk/src/getauditlog.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/getauditlog.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -22,6 +22,7 @@ #endif #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -62,7 +63,9 @@ gpgme_op_getauditlog_start (gpgme_ctx_t ctx, gpgme_data_t output, unsigned int flags) { - return getauditlog_start (ctx, 0, output, flags); + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_getauditlog_start", ctx, + "output=%p, flags=0x%x", output, flags); + return TRACE_ERR (getauditlog_start (ctx, 0, output, flags)); } @@ -73,9 +76,14 @@ gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output, unsigned int flags) { - gpgme_error_t err = getauditlog_start (ctx, 1, output, flags); + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_getauditlog", ctx, + "output=%p, flags=0x%x", output, flags); + + err = getauditlog_start (ctx, 1, output, flags); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/import.c =================================================================== --- trunk/src/import.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/import.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -27,6 +27,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" @@ -65,11 +66,48 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_import_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + + if (_gpgme_debug_trace ()) + { + gpgme_import_status_t impstat; + int i; + + TRACE_LOG5 ("%i considered, %i no UID, %i imported, %i imported RSA, " + "%i unchanged", opd->result.considered, + opd->result.no_user_id, opd->result.imported, + opd->result.imported_rsa, opd->result.unchanged); + TRACE_LOG4 ("%i new UIDs, %i new sub keys, %i new signatures, " + "%i new revocations", opd->result.new_user_ids, + opd->result.new_sub_keys, opd->result.new_signatures, + opd->result.new_revocations); + TRACE_LOG3 ("%i secret keys, %i imported, %i unchanged", + opd->result.secret_read, opd->result.secret_imported, + opd->result.secret_unchanged); + TRACE_LOG2 ("%i skipped new keys, %i not imported", + opd->result.skipped_new_keys, opd->result.not_imported); + + impstat = opd->result.imports; + i = 0; + while (impstat) + { + TRACE_LOG4 ("import[%i] for %s = 0x%x (%s)", + i, impstat->fpr, impstat->status, impstat->result); + impstat = impstat->next; + i++; + } + } + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -245,7 +283,10 @@ gpgme_error_t gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata) { - return _gpgme_op_import_start (ctx, 0, keydata); + TRACE_BEG1 (DEBUG_CTX, "gpgme_op_import_start", ctx, + "keydata=%p", keydata); + + return TRACE_ERR (_gpgme_op_import_start (ctx, 0, keydata)); } @@ -253,10 +294,15 @@ gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata) { - gpgme_error_t err = _gpgme_op_import_start (ctx, 1, keydata); + gpgme_error_t err; + + TRACE_BEG1 (DEBUG_CTX, "gpgme_op_import", ctx, + "keydata=%p", keydata); + + err = _gpgme_op_import_start (ctx, 1, keydata); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } @@ -312,7 +358,21 @@ gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t *keys) { - return _gpgme_op_import_keys_start (ctx, 0, keys); + TRACE_BEG (DEBUG_CTX, "gpgme_op_import_keys_start", ctx); + if (_gpgme_debug_trace () && keys) + { + int i = 0; + + while (keys[i]) + { + TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], + (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + keys[i]->subkeys->fpr : "invalid"); + i++; + } + } + + return TRACE_ERR (_gpgme_op_import_keys_start (ctx, 0, keys)); } @@ -330,10 +390,26 @@ gpgme_error_t gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t *keys) { - gpgme_error_t err = _gpgme_op_import_keys_start (ctx, 1, keys); + gpgme_error_t err; + + TRACE_BEG (DEBUG_CTX, "gpgme_op_import_keys", ctx); + if (_gpgme_debug_trace () && keys) + { + int i = 0; + + while (keys[i]) + { + TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], + (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + keys[i]->subkeys->fpr : "invalid"); + i++; + } + } + + err = _gpgme_op_import_keys_start (ctx, 1, keys); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/keylist.c =================================================================== --- trunk/src/keylist.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/keylist.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -94,11 +94,19 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + TRACE_LOG1 ("truncated = %i", opd->result.truncated); + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -850,25 +858,29 @@ void *hook; op_data_t opd; + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx, + "pattern=%s, secret_only=%i", pattern, secret_only); + err = _gpgme_op_reset (ctx, 2); if (err) - return err; + return TRACE_ERR (err); err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, sizeof (*opd), release_op_data); opd = hook; if (err) - return err; + return TRACE_ERR (err); _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); err = _gpgme_engine_set_colon_line_handler (ctx->engine, keylist_colon_handler, ctx); if (err) - return err; + return TRACE_ERR (err); - return _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, - ctx->keylist_mode); + err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, + ctx->keylist_mode); + return TRACE_ERR (err); } @@ -883,24 +895,28 @@ void *hook; op_data_t opd; + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx, + "secret_only=%i, reserved=0x%x", secret_only, reserved); + err = _gpgme_op_reset (ctx, 2); if (err) - return err; + return TRACE_ERR (err); err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, sizeof (*opd), release_op_data); opd = hook; if (err) - return err; + return TRACE_ERR (err); _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); err = _gpgme_engine_set_colon_line_handler (ctx->engine, keylist_colon_handler, ctx); if (err) - return err; + return TRACE_ERR (err); - return _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, - reserved, ctx->keylist_mode); + err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, + reserved, ctx->keylist_mode); + return TRACE_ERR (err); } @@ -913,27 +929,29 @@ void *hook; op_data_t opd; + TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx); + if (!ctx || !r_key) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); *r_key = NULL; if (!ctx) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL); opd = hook; if (err) - return err; + return TRACE_ERR (err); if (opd == NULL) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (!opd->key_queue) { err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL); if (err) - return err; + return TRACE_ERR (err); if (!opd->key_cond) - return gpg_error (GPG_ERR_EOF); + return TRACE_ERR (gpg_error (GPG_ERR_EOF)); opd->key_cond = 0; assert (opd->key_queue); @@ -945,7 +963,10 @@ *r_key = queue_item->key; free (queue_item); - return 0; + + return TRACE_SUC2 ("key=%p (%s)", *r_key, + ((*r_key)->subkeys && !(*r_key)->subkeys->fpr) ? + (*r_key)->subkeys->fpr : "invalid"); } @@ -953,6 +974,8 @@ gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t ctx) { + TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx); + if (!ctx) return gpg_error (GPG_ERR_INV_VALUE); @@ -970,17 +993,20 @@ gpgme_error_t err; gpgme_key_t key; + TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx, + "fpr=%s, secret=%i", fpr, secret); + if (!ctx || !r_key || !fpr) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (strlen (fpr) < 8) /* We have at least a key ID. */ - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); /* FIXME: We use our own context because we have to avoid the user's I/O callback handlers. */ err = gpgme_new (&listctx); if (err) - return err; + return TRACE_ERR (err); { gpgme_protocol_t proto; gpgme_engine_info_t info; @@ -1031,5 +1057,11 @@ } } gpgme_release (listctx); - return err; + if (! err) + { + TRACE_LOG2 ("key=%p (%s)", *r_key, + ((*r_key)->subkeys && !(*r_key)->subkeys->fpr) ? + (*r_key)->subkeys->fpr : "invalid"); + } + return TRACE_ERR (err); } Modified: trunk/src/opassuan.c =================================================================== --- trunk/src/opassuan.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/opassuan.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -21,10 +21,13 @@ #include #endif +/* Suppress warning for accessing deprecated member "err". */ +#define _GPGME_IN_GPGME 1 #include "gpgme.h" #include "context.h" #include "ops.h" #include "util.h" +#include "debug.h" static gpgme_error_t opassuan_start (gpgme_ctx_t ctx, int synchronous, @@ -66,10 +69,15 @@ gpgme_assuan_status_cb_t status_cb, void *status_cb_value) { - return opassuan_start (ctx, 0, command, - data_cb, data_cb_value, - inq_cb, inq_cb_value, - status_cb, status_cb_value); + TRACE_BEG7 (DEBUG_CTX, "gpgme_op_assuan_transact_start", ctx, + "command=%s, data_cb=%p/%p, inq_cb=%p/%p, status_cb=%p/%p", + command, data_cb, data_cb_value, inq_cb, inq_cb_value, + status_cb, status_cb_value); + + return TRACE_ERR (opassuan_start (ctx, 0, command, + data_cb, data_cb_value, + inq_cb, inq_cb_value, + status_cb, status_cb_value)); } @@ -83,17 +91,37 @@ void *inq_cb_value, gpgme_assuan_status_cb_t status_cb, void *status_cb_value, - gpgme_error_t *op_err) + gpgme_error_t *op_err_p) { gpgme_error_t err; + gpgme_error_t op_err; + TRACE_BEG8 (DEBUG_CTX, "gpgme_op_assuan_transact", ctx, + "command=%s, data_cb=%p/%p, inq_cb=%p/%p, status_cb=%p/%p, " + "op_err=%p", + command, data_cb, data_cb_value, inq_cb, inq_cb_value, + status_cb, status_cb_value, op_err_p); + err = opassuan_start (ctx, 1, command, data_cb, data_cb_value, inq_cb, inq_cb_value, status_cb, status_cb_value); if (!err) - err = _gpgme_wait_one_ext (ctx, op_err); - return err; + err = _gpgme_wait_one_ext (ctx, &op_err); + + if (op_err) + { + TRACE_LOG2 ("op_err = %s <%s>", gpgme_strerror (op_err), + gpgme_strsource (op_err)); + if (! op_err_p) + { + TRACE_LOG ("warning: operational error ignored by user"); + } + } + if (op_err_p) + *op_err_p = op_err; + + return TRACE_ERR (err); } @@ -123,17 +151,32 @@ void *hook; op_data_t opd; + TRACE_BEG (DEBUG_CTX, "gpgme_op_assuan_result", ctx); + err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); opd = hook; /* Check in case this function is used without having run a command before. */ if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } /* All of this is a hack for the old style interface. The new style interface returns op errors directly. */ opd->result.err = _gpgme_engine_assuan_last_op_err (ctx->engine->engine); + if (opd->result.err) + { + TRACE_LOG1 ("err = %s", gpg_strerror (0)); + } + else + { + TRACE_LOG2 ("err = %s <%s>", gpg_strerror (opd->result.err), + gpg_strsource (opd->result.err)); + } + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -148,14 +191,15 @@ gpgme_assuan_status_cb_t status_cb, void *status_cb_value) { - gpgme_error_t op_err; gpgme_error_t err; + TRACE (DEBUG_CTX, "gpgme_op_assuan_transact", ctx); + /* Users of the old-style session based interfaces need to look at the result structure. */ gpgme_op_assuan_transact_ext (ctx, command, data_cb, data_cb_value, inq_cb, inq_cb_value, - status_cb, status_cb_value, &op_err); + status_cb, status_cb_value, NULL); return err; } Modified: trunk/src/signers.c =================================================================== --- trunk/src/signers.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/signers.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -28,8 +28,10 @@ #include #include +#include "gpgme.h" #include "util.h" #include "context.h" +#include "debug.h" /* Delete all signers from CTX. */ @@ -38,6 +40,8 @@ { unsigned int i; + TRACE (DEBUG_CTX, "gpgme_signers_clear", ctx); + if (!ctx || !ctx->signers) return; @@ -54,8 +58,12 @@ gpgme_error_t gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key) { + TRACE_BEG2 (DEBUG_CTX, "gpgme_signers_add", ctx, + "key=%p (%s)", key, (key->subkeys && !key->subkeys->fpr) ? + key->subkeys->fpr : "invalid"); + if (!ctx || !key) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (ctx->signers_len == ctx->signers_size) { @@ -65,7 +73,7 @@ newarr = realloc (ctx->signers, n * sizeof (*newarr)); if (!newarr) - return gpg_error_from_errno (errno); + return TRACE_ERR (gpg_error_from_errno (errno)); for (j = ctx->signers_size; j < n; j++) newarr[j] = NULL; ctx->signers = newarr; @@ -74,7 +82,7 @@ gpgme_key_ref (key); ctx->signers[ctx->signers_len++] = key; - return 0; + return TRACE_SUC (); } Modified: trunk/src/trustlist.c =================================================================== --- trunk/src/trustlist.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/trustlist.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -28,6 +28,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "util.h" #include "context.h" #include "ops.h" @@ -173,27 +174,31 @@ void *hook; op_data_t opd; + TRACE_BEG2 (DEBUG_CTX, "gpgme_op_trustlist_start", ctx, + "pattern=%s, max_level=%i", pattern, max_level); + if (!pattern || !*pattern) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = _gpgme_op_reset (ctx, 2); if (err) - return err; + return TRACE_ERR (err); err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, sizeof (*opd), NULL); opd = hook; if (err) - return err; + return TRACE_ERR (err); _gpgme_engine_set_status_handler (ctx->engine, trustlist_status_handler, ctx); err = _gpgme_engine_set_colon_line_handler (ctx->engine, trustlist_colon_handler, ctx); if (err) - return err; + return TRACE_ERR (err); - return _gpgme_engine_op_trustlist (ctx->engine, pattern); + err = _gpgme_engine_op_trustlist (ctx->engine, pattern); + return TRACE_ERR (err); } @@ -205,26 +210,28 @@ op_data_t opd; struct trust_queue_item_s *q; + TRACE_BEG (DEBUG_CTX, "gpgme_op_trustlist_next", ctx); + if (!r_item) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); *r_item = NULL; if (!ctx) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL); opd = hook; if (err) - return err; + return TRACE_ERR (err); if (opd == NULL) - return gpg_error (GPG_ERR_INV_VALUE); + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (!opd->trust_queue) { err = _gpgme_wait_on_condition (ctx, &opd->trust_cond, NULL); if (err) - return err; + return TRACE_ERR (err); if (!opd->trust_cond) - return gpg_error (GPG_ERR_EOF); + return TRACE_ERR (gpg_error (GPG_ERR_EOF)); opd->trust_cond = 0; assert (opd->trust_queue); } @@ -233,6 +240,25 @@ *r_item = q->item; free (q); + if ((*r_item)->type == 1) + { + TRACE_SUC5 ("trust_item=%p: %s: owner trust %s with level %i " + "and validity 0x%x", *r_item, (*r_item)->keyid, + (*r_item)->owner_trust, (*r_item)->level, + (*r_item)->validity); + } + else if ((*r_item)->type == 2) + { + TRACE_SUC5 ("trust_item=%p: %s: UID %s with level %i " + "and validity 0x%x", *r_item, (*r_item)->keyid, + (*r_item)->name, (*r_item)->level, (*r_item)->validity); + } + else + { + TRACE_SUC5 ("trust_item=%p: %s: unknown type %i with level %i " + "and validity 0x%x", *r_item, (*r_item)->keyid, + (*r_item)->type, (*r_item)->level, (*r_item)->validity); + } return 0; } @@ -241,6 +267,8 @@ gpgme_error_t gpgme_op_trustlist_end (gpgme_ctx_t ctx) { + TRACE (DEBUG_CTX, "gpgme_op_trustlist_end", ctx); + if (!ctx) return gpg_error (GPG_ERR_INV_VALUE); Modified: trunk/src/verify.c =================================================================== --- trunk/src/verify.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/verify.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -28,6 +28,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "util.h" #include "context.h" #include "ops.h" @@ -83,11 +84,48 @@ op_data_t opd; gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_op_verify_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL); opd = hook; if (err || !opd) - return NULL; + { + TRACE_SUC0 ("result=(null)"); + return NULL; + } + if (_gpgme_debug_trace ()) + { + gpgme_signature_t sig = opd->result.signatures; + int i = 0; + + while (sig) + { + TRACE_LOG4 ("sig[%i] = fpr %s, summary 0x%x, status %s", + i, sig->fpr, sig->summary, gpg_strerror (sig->status)); + TRACE_LOG6 ("sig[%i] = timestamps 0x%x/0x%x flags:%s%s%s", + i, sig->timestamp, sig->exp_timestamp, + sig->wrong_key_usage ? "wrong key usage" : "", + sig->pka_trust == 1 ? "pka bad" + : (sig->pka_trust == 2 ? "pka_okay" : "pka RFU"), + sig->chain_model ? "chain model" : ""); + TRACE_LOG5 ("sig[%i] = validity 0x%x (%s), algos %s/%s", + i, sig->validity, gpg_strerror (sig->validity_reason), + gpgme_pubkey_algo_name (sig->pubkey_algo), + gpgme_hash_algo_name (sig->hash_algo)); + if (sig->pka_address) + { + TRACE_LOG2 ("sig[%i] = PKA address %s", i, sig->pka_address); + } + if (sig->notations) + { + TRACE_LOG1 ("sig[%i] = has notations (not shown)", i); + } + sig = sig->next; + i++; + } + } + + TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; } @@ -794,7 +832,10 @@ gpgme_op_verify_start (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t signed_text, gpgme_data_t plaintext) { - return verify_start (ctx, 0, sig, signed_text, plaintext); + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_verify_start", ctx, + "sig=%p, signed_text=%p, plaintext=%p", + sig, signed_text, plaintext); + return TRACE_ERR (verify_start (ctx, 0, sig, signed_text, plaintext)); } @@ -806,10 +847,14 @@ { gpgme_error_t err; + TRACE_BEG3 (DEBUG_CTX, "gpgme_op_verify", ctx, + "sig=%p, signed_text=%p, plaintext=%p", + sig, signed_text, plaintext); + err = verify_start (ctx, 1, sig, signed_text, plaintext); if (!err) err = _gpgme_wait_one (ctx); - return err; + return TRACE_ERR (err); } Modified: trunk/src/wait-private.c =================================================================== --- trunk/src/wait-private.c 2009-10-26 18:52:32 UTC (rev 1406) +++ trunk/src/wait-private.c 2009-10-27 19:23:56 UTC (rev 1407) @@ -78,6 +78,9 @@ gpgme_error_t err = 0; int hang = 1; + if (op_err_p) + *op_err_p = 0; + do { int nr = _gpgme_io_select (ctx->fdt.fds, ctx->fdt.size, 0); @@ -90,8 +93,6 @@ err = gpg_error_from_errno (errno); _gpgme_cancel_with_err (ctx, err, 0); - if (op_err_p) - *op_err_p = 0; return err; } @@ -118,8 +119,6 @@ and signal it. */ _gpgme_cancel_with_err (ctx, err, 0); - if (op_err_p) - *op_err_p = 0; return err; } else if (op_err) @@ -157,8 +156,6 @@ } while (hang); - if (op_err_p) - *op_err_p = 0; return 0; } From cvs at cvs.gnupg.org Wed Oct 28 13:02:15 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Oct 2009 13:02:15 +0100 Subject: [svn] GnuPG - r5187 - in trunk: . common doc g13 scd Message-ID: Author: wk Date: 2009-10-28 13:02:15 +0100 (Wed, 28 Oct 2009) New Revision: 5187 Modified: trunk/THANKS trunk/common/ChangeLog trunk/common/status.h trunk/doc/DETAILS trunk/g13/be-encfs.c trunk/g13/g13.c trunk/g13/g13.h trunk/g13/mount.c trunk/g13/mountinfo.c trunk/g13/mountinfo.h trunk/g13/server.c trunk/scd/ChangeLog trunk/scd/command.c trunk/scd/scdaemon.c Log: [scd] Memory leak fix. [g13] Send MOUNTPOINT status line Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/common/ChangeLog 2009-10-28 12:02:15 UTC (rev 5187) @@ -1,3 +1,7 @@ +2009-10-28 Werner Koch + + * status.h (STATUS_MOUNTPOINT): New. + 2009-10-16 Marcus Brinkmann * Makefile.am (libcommon_a_CFLAGS): Use LIBASSUAN_CFLAGS instead @@ -2,3 +6,3 @@ of LIBASSUAN_PTH_CFLAGS. - + 2009-10-13 Werner Koch Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/scd/ChangeLog 2009-10-28 12:02:15 UTC (rev 5187) @@ -1,3 +1,9 @@ +2009-10-25 Werner Koch + + * scdaemon.c (scd_deinit_default_ctrl): Release IN_DATA. + * command.c (cmd_setdata): Release IN_DATA. Reported by Klaus + Flittner. + 2009-10-16 Marcus Brinkmann * AM_CFLAGS, scdaemon_LDADD: Use libassuan instead of libassuan-pth. Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/THANKS 2009-10-28 12:02:15 UTC (rev 5187) @@ -145,6 +145,7 @@ Ken Takusagawa ken.takusagawa.2 at gmail.com Kevin Ryde user42 at zip.com.au Kiss Gabor kissg at ssg.ki.iif.hu +Klaus Flittner klaus at flittner org Klaus Singvogel ks at caldera.de Kurt Garloff garloff at suse.de Lars Kellogg-Stedman lars at bu.edu Modified: trunk/common/status.h =================================================================== --- trunk/common/status.h 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/common/status.h 2009-10-28 12:02:15 UTC (rev 5187) @@ -124,6 +124,8 @@ STATUS_PKA_TRUST_GOOD, STATUS_TRUNCATED, + STATUS_MOUNTPOINT, + STATUS_ERROR }; Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/doc/DETAILS 2009-10-28 12:02:15 UTC (rev 5187) @@ -680,7 +680,13 @@ A backup key named FNAME has been created for the key with KEYID. + MOUNTPOINT + NAME is a percent-plus escaped filename describing the + mountpoint for the current operation (e.g. g13 --mount). This + may either be the specified mountpoint or one randomly choosen + by g13. + Format of the "--attribute-fd" output ===================================== Modified: trunk/g13/be-encfs.c =================================================================== --- trunk/g13/be-encfs.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/be-encfs.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -418,7 +418,7 @@ { err = gpg_error_from_syserror (); log_error (_("can't create directory `%s': %s\n"), - "/tmp/g13-XXXXXX", gpg_strerror (err)); + "/tmp/.#g13_XXXXXX", gpg_strerror (err)); goto leave; } Modified: trunk/g13/g13.c =================================================================== --- trunk/g13/g13.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/g13.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -420,6 +420,8 @@ /* Setup a default control structure for command line mode. */ memset (&ctrl, 0, sizeof ctrl); g13_init_default_ctrl (&ctrl); + ctrl.no_server = 1; + ctrl.status_fd = -1; /* No status output. */ /* Set the default option file */ if (default_config ) @@ -678,6 +680,7 @@ case aServer: { start_idle_task (); + ctrl.no_server = 0; err = g13_server (&ctrl); if (err) log_error ("server exited with error: %s <%s>\n", Modified: trunk/g13/g13.h =================================================================== --- trunk/g13/g13.h 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/g13.h 2009-10-28 12:02:15 UTC (rev 5187) @@ -106,6 +106,8 @@ void g13_exit (int rc); void g13_init_default_ctrl (struct server_control_s *ctrl); +/*-- server.c (commonly used, thus declared here) --*/ +gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GNUPG_GCC_A_SENTINEL(0); #endif /*G13_H*/ Modified: trunk/g13/mount.c =================================================================== --- trunk/g13/mount.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/mount.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -250,15 +250,35 @@ const unsigned char *value; int conttype; unsigned int rid; + char *mountpoint_buffer = NULL; /* A quick check to see whether the container exists. */ if (access (filename, R_OK)) return gpg_error_from_syserror (); + if (!mountpoint) + { + mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX"); + if (!mountpoint_buffer) + return gpg_error_from_syserror (); + if (!mkdtemp (mountpoint_buffer)) + { + err = gpg_error_from_syserror (); + log_error (_("can't create directory `%s': %s\n"), + "/tmp/g13-XXXXXX", gpg_strerror (err)); + xfree (mountpoint_buffer); + return err; + } + mountpoint = mountpoint_buffer; + } + /* Try to take a lock. */ lock = create_dotlock (filename); if (!lock) - return gpg_error_from_syserror (); + { + xfree (mountpoint_buffer); + return gpg_error_from_syserror (); + } if (make_dotlock (lock, 0)) { @@ -318,9 +338,21 @@ err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid); if (!err) { - err = mountinfo_add_mount (filename, mountpoint, conttype, rid); + err = mountinfo_add_mount (filename, mountpoint, conttype, rid, + !!mountpoint_buffer); /* Fixme: What shall we do if this fails? Add a provisional mountinfo entry first and remove it on error? */ + if (!err) + { + char *tmp = percent_plus_escape (mountpoint); + if (!tmp) + err = gpg_error_from_syserror (); + else + { + g13_status (ctrl, STATUS_MOUNTPOINT, tmp, NULL); + xfree (tmp); + } + } } leave: @@ -328,6 +360,7 @@ xfree (keyblob); xfree (enckeyblob); destroy_dotlock (lock); + xfree (mountpoint_buffer); return err; } Modified: trunk/g13/mountinfo.c =================================================================== --- trunk/g13/mountinfo.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/mountinfo.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -43,6 +43,10 @@ char *mountpoint; /* Name of the mounttype. */ int conttype; /* Type of the container. */ unsigned int rid; /* Identifier of the runner task. */ + struct { + unsigned int remove:1; /* True if the mountpoint shall be removed + on umount. */ + } flags; }; @@ -55,7 +59,7 @@ /* Add CONTAINER,MOUNTPOINT,CONTTYPE,RID to the mounttable. */ gpg_error_t mountinfo_add_mount (const char *container, const char *mountpoint, - int conttype, unsigned int rid) + int conttype, unsigned int rid, int remove_flag) { size_t idx; mtab_t m; @@ -96,6 +100,7 @@ } m->conttype = conttype; m->rid = rid; + m->flags.remove = !!remove_flag; m->in_use = 1; return 0; @@ -125,6 +130,16 @@ for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) if (m->in_use && m->rid == rid) { + if (m->flags.remove && m->mountpoint) + { + /* FIXME: This does not always work because the umount may + not have completed yet. We should add the mountpoints + to an idle queue and retry a remove. */ + if (rmdir (m->mountpoint)) + log_error ("error removing mount point `%s': %s\n", + m->mountpoint, + gpg_strerror (gpg_error_from_syserror ())); + } m->in_use = 0; xfree (m->container); m->container = NULL; @@ -177,7 +192,8 @@ for (idx=0, m = mounttable; idx < mounttable_size; idx++, m++) if (m->in_use) - log_info ("mtab[%d] %s on %s type %d rid %u\n", - idx, m->container, m->mountpoint, m->conttype, m->rid); + log_info ("mtab[%d] %s on %s type %d rid %u%s\n", + idx, m->container, m->mountpoint, m->conttype, m->rid, + m->flags.remove?" [remove]":""); } Modified: trunk/g13/mountinfo.h =================================================================== --- trunk/g13/mountinfo.h 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/mountinfo.h 2009-10-28 12:02:15 UTC (rev 5187) @@ -25,7 +25,8 @@ gpg_error_t mountinfo_add_mount (const char *container, const char *mountpoint, - int conttype, unsigned int rid); + int conttype, unsigned int rid, + int remove_flag); gpg_error_t mountinfo_del_mount (const char *container, const char *mountpoint, unsigned int rid); Modified: trunk/g13/server.c =================================================================== --- trunk/g13/server.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/g13/server.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -33,6 +33,10 @@ #include "mount.h" #include "create.h" + +/* The filepointer for status message used in non-server mode */ +static FILE *statusfp; + /* Local data for this server module. A pointer to this is stored in the CTRL object of each connection. */ struct server_local_s @@ -310,7 +314,8 @@ /* UMOUNT [options] [] Unmount the currently open file or the one opened at MOUNTPOINT. - MOUNTPOINT must be percent-plus escaped. + MOUNTPOINT must be percent-plus escaped. On success the mountpoint + is returned via a "MOUNTPOINT" status line. */ static gpg_error_t cmd_umount (assuan_context_t ctx, char *line) @@ -662,101 +667,83 @@ } +/* Send a status line with status ID NO. The arguments are a list of + strings terminated by a NULL argument. */ +gpg_error_t +g13_status (ctrl_t ctrl, int no, ...) +{ + gpg_error_t err = 0; + va_list arg_ptr; + const char *text; -/* gpg_error_t */ -/* gpgsm_status2 (ctrl_t ctrl, int no, ...) */ -/* { */ -/* gpg_error_t err = 0; */ -/* va_list arg_ptr; */ -/* const char *text; */ + va_start (arg_ptr, no); -/* va_start (arg_ptr, no); */ - -/* if (ctrl->no_server && ctrl->status_fd == -1) */ -/* ; /\* No status wanted. *\/ */ -/* else if (ctrl->no_server) */ -/* { */ -/* if (!statusfp) */ -/* { */ -/* if (ctrl->status_fd == 1) */ -/* statusfp = stdout; */ -/* else if (ctrl->status_fd == 2) */ -/* statusfp = stderr; */ -/* else */ -/* statusfp = fdopen (ctrl->status_fd, "w"); */ + if (ctrl->no_server && ctrl->status_fd == -1) + ; /* No status wanted. */ + else if (ctrl->no_server) + { + if (!statusfp) + { + if (ctrl->status_fd == 1) + statusfp = stdout; + else if (ctrl->status_fd == 2) + statusfp = stderr; + else + statusfp = fdopen (ctrl->status_fd, "w"); + + if (!statusfp) + { + log_fatal ("can't open fd %d for status output: %s\n", + ctrl->status_fd, strerror(errno)); + } + } -/* if (!statusfp) */ -/* { */ -/* log_fatal ("can't open fd %d for status output: %s\n", */ -/* ctrl->status_fd, strerror(errno)); */ -/* } */ -/* } */ - -/* fputs ("[GNUPG:] ", statusfp); */ -/* fputs (get_status_string (no), statusfp); */ + fputs ("[GNUPG:] ", statusfp); + fputs (get_status_string (no), statusfp); -/* while ( (text = va_arg (arg_ptr, const char*) )) */ -/* { */ -/* putc ( ' ', statusfp ); */ -/* for (; *text; text++) */ -/* { */ -/* if (*text == '\n') */ -/* fputs ( "\\n", statusfp ); */ -/* else if (*text == '\r') */ -/* fputs ( "\\r", statusfp ); */ -/* else */ -/* putc ( *(const byte *)text, statusfp ); */ -/* } */ -/* } */ -/* putc ('\n', statusfp); */ -/* fflush (statusfp); */ -/* } */ -/* else */ -/* { */ -/* assuan_context_t ctx = ctrl->server_local->assuan_ctx; */ -/* char buf[950], *p; */ -/* size_t n; */ + while ( (text = va_arg (arg_ptr, const char*) )) + { + putc ( ' ', statusfp ); + for (; *text; text++) + { + if (*text == '\n') + fputs ( "\\n", statusfp ); + else if (*text == '\r') + fputs ( "\\r", statusfp ); + else + putc ( *(const byte *)text, statusfp ); + } + } + putc ('\n', statusfp); + fflush (statusfp); + } + else + { + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + char buf[950], *p; + size_t n; -/* p = buf; */ -/* n = 0; */ -/* while ( (text = va_arg (arg_ptr, const char *)) ) */ -/* { */ -/* if (n) */ -/* { */ -/* *p++ = ' '; */ -/* n++; */ -/* } */ -/* for ( ; *text && n < DIM (buf)-2; n++) */ -/* *p++ = *text++; */ -/* } */ -/* *p = 0; */ -/* err = assuan_write_status (ctx, get_status_string (no), buf); */ -/* } */ + p = buf; + n = 0; + while ( (text = va_arg (arg_ptr, const char *)) ) + { + if (n) + { + *p++ = ' '; + n++; + } + for ( ; *text && n < DIM (buf)-2; n++) + *p++ = *text++; + } + *p = 0; + err = assuan_write_status (ctx, get_status_string (no), buf); + } -/* va_end (arg_ptr); */ -/* return err; */ -/* } */ + va_end (arg_ptr); + return err; +} -/* gpg_error_t */ -/* gpgsm_status (ctrl_t ctrl, int no, const char *text) */ -/* { */ -/* return gpgsm_status2 (ctrl, no, text, NULL); */ -/* } */ -/* gpg_error_t */ -/* gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, */ -/* gpg_err_code_t ec) */ -/* { */ -/* char buf[30]; */ - -/* sprintf (buf, "%u", (unsigned int)ec); */ -/* if (text) */ -/* return gpgsm_status2 (ctrl, no, text, buf, NULL); */ -/* else */ -/* return gpgsm_status2 (ctrl, no, buf, NULL); */ -/* } */ - - /* Helper to notify the client about Pinentry events. Returns an gpg error code. */ gpg_error_t @@ -768,5 +755,3 @@ } - - Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/scd/command.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -804,6 +804,7 @@ if (!buf) return out_of_core (); + xfree (ctrl->in_data.value); ctrl->in_data.value = buf; ctrl->in_data.valuelen = n; for (p=line, n=0; n < ctrl->in_data.valuelen; p += 2, n++) Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-10-20 14:30:47 UTC (rev 5186) +++ trunk/scd/scdaemon.c 2009-10-28 12:02:15 UTC (rev 5187) @@ -895,7 +895,11 @@ static void scd_deinit_default_ctrl (ctrl_t ctrl) { - (void)ctrl; + if (!ctrl) + return; + xfree (ctrl->in_data.value); + ctrl->in_data.value = NULL; + ctrl->in_data.valuelen = 0; } From cvs at cvs.gnupg.org Wed Oct 28 16:11:40 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Oct 2009 16:11:40 +0100 Subject: [svn] gcry - r1406 - trunk/doc Message-ID: Author: wk Date: 2009-10-28 16:11:40 +0100 (Wed, 28 Oct 2009) New Revision: 1406 Modified: trunk/doc/ChangeLog trunk/doc/gcrypt.texi Log: Add examples. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-08-21 09:34:39 UTC (rev 1405) +++ trunk/doc/ChangeLog 2009-10-28 15:11:40 UTC (rev 1406) @@ -1,3 +1,7 @@ +2009-10-28 Werner Koch + + * gcrypt.texi (Multi-Threading): Add examples. + 2009-07-02 Daiki Ueno * gcrypt.texi (Working with S-expressions): Describe format Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-08-21 09:34:39 UTC (rev 1405) +++ trunk/doc/gcrypt.texi 2009-10-28 15:11:40 UTC (rev 1406) @@ -498,8 +498,13 @@ After including this macro, @code{gcry_control()} shall be used with a command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the -thread callback structure named ``gcry_threads_pth''. +thread callback structure named ``gcry_threads_pth''. Example: + at smallexample + ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); + at end smallexample + + @item GCRY_THREAD_OPTION_PTHREAD_IMPL This macro defines the following (static) symbols: @@ -509,7 +514,13 @@ After including this macro, @code{gcry_control()} shall be used with a command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the -thread callback structure named ``gcry_threads_pthread''. +thread callback structure named ``gcry_threads_pthread''. Example: + + at smallexample + ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); + at end smallexample + + @end table Note that these macros need to be terminated with a semicolon. Keep @@ -589,11 +600,12 @@ @table @code @item GCRYCTL_ENABLE_M_GUARD; Arguments: none -This command enables the built-in memory guard. It must not be used to -activate the memory guard after the memory management has already been -used; therefore it can ONLY be used at initialization time. Note that -the memory guard is NOT used when the user of the library has set his -own memory management callbacks. +This command enables the built-in memory guard. It must not be used +to activate the memory guard after the memory management has already +been used; therefore it can ONLY be used before + at code{gcry_check_version}. Note that the memory guard is NOT used +when the user of the library has set his own memory management +callbacks. @item GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none This command inhibits the use the very secure random quality level From cvs at cvs.gnupg.org Wed Oct 28 17:39:20 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 28 Oct 2009 17:39:20 +0100 Subject: [svn] gpgme - r1408 - trunk/src Message-ID: Author: marcus Date: 2009-10-28 17:39:19 +0100 (Wed, 28 Oct 2009) New Revision: 1408 Modified: trunk/src/ChangeLog trunk/src/delete.c trunk/src/edit.c trunk/src/encrypt-sign.c trunk/src/encrypt.c trunk/src/export.c trunk/src/import.c trunk/src/keylist.c trunk/src/signers.c Log: 2009-10-28 Marcus Brinkmann * signers.c, encrypt-sign.c, encrypt.c, delete.c, keylist.c, edit.c, import.c, export.c: Fix last change in debug output. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/ChangeLog 2009-10-28 16:39:19 UTC (rev 1408) @@ -1,3 +1,8 @@ +2009-10-28 Marcus Brinkmann + + * signers.c, encrypt-sign.c, encrypt.c, delete.c, keylist.c, + edit.c, import.c, export.c: Fix last change in debug output. + 2009-10-27 Marcus Brinkmann * edit.c (gpgme_op_edit_start, gpgme_op_edit) Modified: trunk/src/delete.c =================================================================== --- trunk/src/delete.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/delete.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -96,7 +96,7 @@ { TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx, "key=%p (%s), allow_secret=%i", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", allow_secret); return TRACE_ERR (delete_start (ctx, 0, key, allow_secret)); } @@ -111,7 +111,7 @@ TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx, "key=%p (%s), allow_secret=%i", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", allow_secret); err = delete_start (ctx, 1, key, allow_secret); if (!err) Modified: trunk/src/edit.c =================================================================== --- trunk/src/edit.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/edit.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -141,7 +141,7 @@ { TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit_start", ctx, "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", fnc, fnc_value, out); return TRACE_ERR (edit_start (ctx, 0, 0, key, fnc, fnc_value, out)); } @@ -157,7 +157,7 @@ TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit", ctx, "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", fnc, fnc_value, out); err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out); @@ -175,7 +175,7 @@ { TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit_start", ctx, "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", fnc, fnc_value, out); return TRACE_ERR (edit_start (ctx, 0, 1, key, fnc, fnc_value, out)); } @@ -191,7 +191,7 @@ TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit", ctx, "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key, - (key->subkeys && !key->subkeys->fpr) ? + (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", fnc, fnc_value, out); err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out); if (!err) Modified: trunk/src/encrypt-sign.c =================================================================== --- trunk/src/encrypt-sign.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/encrypt-sign.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -101,8 +101,8 @@ while (recp[i]) { - TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], - (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i], + (recp[i]->subkeys && recp[i]->subkeys->fpr) ? recp[i]->subkeys->fpr : "invalid"); i++; } @@ -131,8 +131,8 @@ while (recp[i]) { - TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], - (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i], + (recp[i]->subkeys && recp[i]->subkeys->fpr) ? recp[i]->subkeys->fpr : "invalid"); i++; } Modified: trunk/src/encrypt.c =================================================================== --- trunk/src/encrypt.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/encrypt.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -236,8 +236,8 @@ while (recp[i]) { - TRACE_LOG3 ("recipient[%i] = %p (%s)", i,recp[i], - (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i], + (recp[i]->subkeys && recp[i]->subkeys->fpr) ? recp[i]->subkeys->fpr : "invalid"); i++; } @@ -266,7 +266,7 @@ while (recp[i]) { TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i], - (recp[i]->subkeys && !recp[i]->subkeys->fpr) ? + (recp[i]->subkeys && recp[i]->subkeys->fpr) ? recp[i]->subkeys->fpr : "invalid"); i++; } Modified: trunk/src/export.c =================================================================== --- trunk/src/export.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/export.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -253,8 +253,8 @@ while (keys[i]) { - TRACE_LOG3 ("keys[%i] = %p (%s)", i,keys[i], - (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], + (keys[i]->subkeys && keys[i]->subkeys->fpr) ? keys[i]->subkeys->fpr : "invalid"); i++; } @@ -280,8 +280,8 @@ while (keys[i]) { - TRACE_LOG3 ("keys[%i] = %p (%s)", i,keys[i], - (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], + (keys[i]->subkeys && keys[i]->subkeys->fpr) ? keys[i]->subkeys->fpr : "invalid"); i++; } Modified: trunk/src/import.c =================================================================== --- trunk/src/import.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/import.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -366,7 +366,7 @@ while (keys[i]) { TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], - (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + (keys[i]->subkeys && keys[i]->subkeys->fpr) ? keys[i]->subkeys->fpr : "invalid"); i++; } @@ -400,7 +400,7 @@ while (keys[i]) { TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i], - (keys[i]->subkeys && !keys[i]->subkeys->fpr) ? + (keys[i]->subkeys && keys[i]->subkeys->fpr) ? keys[i]->subkeys->fpr : "invalid"); i++; } Modified: trunk/src/keylist.c =================================================================== --- trunk/src/keylist.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/keylist.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -965,7 +965,7 @@ free (queue_item); return TRACE_SUC2 ("key=%p (%s)", *r_key, - ((*r_key)->subkeys && !(*r_key)->subkeys->fpr) ? + ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ? (*r_key)->subkeys->fpr : "invalid"); } @@ -1060,7 +1060,7 @@ if (! err) { TRACE_LOG2 ("key=%p (%s)", *r_key, - ((*r_key)->subkeys && !(*r_key)->subkeys->fpr) ? + ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ? (*r_key)->subkeys->fpr : "invalid"); } return TRACE_ERR (err); Modified: trunk/src/signers.c =================================================================== --- trunk/src/signers.c 2009-10-27 19:23:56 UTC (rev 1407) +++ trunk/src/signers.c 2009-10-28 16:39:19 UTC (rev 1408) @@ -59,7 +59,7 @@ gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key) { TRACE_BEG2 (DEBUG_CTX, "gpgme_signers_add", ctx, - "key=%p (%s)", key, (key->subkeys && !key->subkeys->fpr) ? + "key=%p (%s)", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid"); if (!ctx || !key) From cvs at cvs.gnupg.org Wed Oct 28 20:26:07 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Oct 2009 20:26:07 +0100 Subject: [svn] GpgOL - r311 - in trunk: . po src Message-ID: Author: wk Date: 2009-10-28 20:26:06 +0100 (Wed, 28 Oct 2009) New Revision: 311 Added: trunk/src/cmdbarcontrols.cpp trunk/src/cmdbarcontrols.h trunk/src/decrypt-mask.bmp trunk/src/decrypt-verify-mask.bmp trunk/src/decrypt-verify.bmp trunk/src/explorers.cpp trunk/src/explorers.h trunk/src/inspectors.cpp trunk/src/inspectors.h trunk/src/key-manager-mask.bmp trunk/src/key-manager.bmp trunk/src/oomhelp.cpp trunk/src/oomhelp.h trunk/src/sign-mask.bmp trunk/src/verify-mask.bmp trunk/src/verify.bmp Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/po/de.po trunk/po/sv.po trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/common.c trunk/src/common.h trunk/src/decrypt.bmp trunk/src/dialogs.h trunk/src/dialogs.rc trunk/src/ext-commands.cpp trunk/src/ext-commands.h trunk/src/item-events.h trunk/src/main.c trunk/src/message-events.cpp trunk/src/message.cpp trunk/src/mimemaker.c trunk/src/myexchext.h trunk/src/ol-ext-callback.cpp trunk/src/ol-ext-callback.h trunk/src/olflange-dlgs.cpp trunk/src/olflange.cpp trunk/src/sign.bmp trunk/src/user-events.cpp trunk/src/util.h Log: A bunch of changes to support better looking icons. CLeaned up some code and introduced a lot of code to support the OOM. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/ChangeLog 2009-10-28 19:26:06 UTC (rev 311) @@ -1,3 +1,7 @@ +2009-10-08 Werner Koch + + * configure.ac (CFLAGS): Add -fno-strict-aliasing. + 2009-09-28 Werner Koch Release 1.0.1. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/ChangeLog 2009-10-28 19:26:06 UTC (rev 311) @@ -1,3 +1,47 @@ +2009-10-28 Werner Koch + + * ext-commands.cpp: Remove m_nCmdCryptoState and all related code; + now handled in inspectors.cpp. Remove m_nCmdKeyManager and all + related code; now handled in cmdbarcontrols.cpp. + + * oomhelp.cpp, oomhelp.h, eventsink.h: New. + * myexchext.h: Move generic COM+ stuff to oomhelp.h. + * explorers.cpp, explorers.h: New. + * inspectors.cpp, inspectors.h: New. + * cmdbarcontrols.cpp cmdbarcontrols.h: New. + * olflange.cpp (install_sinks): New. + (Install): Call install_sinks. + * main.c (DllMain): Call initialize_inspectors. + + * common.c (fatal_error): New. + +2009-10-20 Werner Koch + + * myexchext.h (IID_IConnectionPoint) + (IID_IConnectionPointContainer): Define. There are missing in + current wine From ReactOS. + +2009-10-19 Werner Koch + + * message-events.cpp (show_event_object): Move to .. + * ol-ext-callback.cpp (show_event_object): .. here. + (show_preview_pane): Revert dispparms order to make it work. + + * common.c (mem2str): New. + +2009-10-07 Werner Koch + + * ext-commands.cpp (InstallCommands): Comment out the protocol + selection. + (DoCommand, Help, QueryHelpText, QueryButtonInfo): Ditto. + (update_protocol_menu): Comment out. + * main.c (write_options): Do not write the default protocol. + (read_options): Always set it to auto. + * dialogs.rc: Remove openpgp-by-default and smime-by-default check + boxes. + * olflange-dlgs.cpp (set_labels): Likewise. + (GPGOptionsDlgProc): Likewise. + 2009-09-25 Werner Koch * main.c (read_options): Enable Smime by default. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/NEWS 2009-10-28 19:26:06 UTC (rev 311) @@ -1,3 +1,15 @@ +Noteworthy changes for version 1.1.0 +=================================================== + + * Replaced some ECF code by direct OOM code. This was required to + support better icons; i.e. icons not limited to a 16 color palette. + + * New icons. + + * Removed protocol selection. The UI-server is now expected to select + the protocol (i.e. the auto selection modus is now the only one). + + Noteworthy changes for version 1.0.1 (2009-09-28) =================================================== Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/configure.ac 2009-10-28 19:26:06 UTC (rev 311) @@ -16,8 +16,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.0.1]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.1.0]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) @@ -190,8 +190,8 @@ fi if test "$GCC" = yes; then - CFLAGS="$CFLAGS -Wall -mms-bitfields" - CXXFLAGS="$CXXFLAGS -Wall -mms-bitfields" + CFLAGS="$CFLAGS -Wall -mms-bitfields -fno-strict-aliasing" + CXXFLAGS="$CXXFLAGS -Wall -mms-bitfields -fno-strict-aliasing" if test "$USE_MAINTAINER_MODE" = "yes"; then CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wno-format-y2k -Wformat-security" Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/Makefile.am 2009-10-28 19:26:06 UTC (rev 311) @@ -16,9 +16,14 @@ bin_PROGRAMS = gpgol #treeview EXTRA_DIST = versioninfo.rc.in mapi32.def $(unused_sources) Outlook.gpl \ - logo.bmp decrypt.bmp encrypt.bmp sign.bmp key_mana.bmp \ + logo.bmp encrypt.bmp \ proto-auto.bmp proto-pgpmime.bmp proto-smime.bmp \ - cryptostate.bmp + cryptostate.bmp \ + key-manager.bmp key-manager-mask.bmp \ + decrypt.bmp decrypt-mask.bmp \ + verify.bmp verify-mask.bmp \ + decrypt-verify.bmp decrypt-verify-mask.bmp \ + sign.bmp sign-mask.bmp EXEEXT = .dll @@ -63,6 +68,10 @@ property-sheets.cpp property-sheets.h \ item-events.h \ ol-ext-callback.cpp ol-ext-callback.h \ + oomhelp.cpp oomhelp.h eventsink.h \ + explorers.cpp explorers.h \ + inspectors.cpp inspectors.h \ + cmdbarcontrols.cpp cmdbarcontrols.h \ w32-gettext.c w32-gettext.h Added: trunk/src/cmdbarcontrols.cpp =================================================================== --- trunk/src/cmdbarcontrols.cpp (rev 0) +++ trunk/src/cmdbarcontrols.cpp 2009-10-28 19:26:06 UTC (rev 311) @@ -0,0 +1,132 @@ +/* cmdbarcontrols.cpp - Code to handle the CommandBarControls + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "common.h" +#include "oomhelp.h" +#include "cmdbarcontrols.h" +#include "inspectors.h" +#include "engine.h" + +#include "eventsink.h" + + +/* Subclass of CommandBarButtonEvents so that we can hook into the + Click event. */ +BEGIN_EVENT_SINK(GpgolCommandBarButtonEvents, IOOMCommandBarButtonEvents) + STDMETHOD (Click) (THIS_ LPDISPATCH, PBOOL); +EVENT_SINK_DEFAULT_DTOR(GpgolCommandBarButtonEvents) +EVENT_SINK_INVOKE(GpgolCommandBarButtonEvents) +{ + HRESULT hr; + (void)lcid; (void)riid; (void)result; (void)exepinfo; (void)argerr; + + if (dispid == 1 && (flags & DISPATCH_METHOD)) + { + if (!parms) + hr = DISP_E_PARAMNOTOPTIONAL; + else if (parms->cArgs != 2) + hr = DISP_E_BADPARAMCOUNT; + else if (parms->rgvarg[0].vt != (VT_BOOL|VT_BYREF) + || parms->rgvarg[1].vt != VT_DISPATCH) + hr = DISP_E_BADVARTYPE; + else + { + BOOL cancel_default = !!*parms->rgvarg[0].pboolVal; + hr = Click (parms->rgvarg[1].pdispVal, (PBOOL)&cancel_default); + *parms->rgvarg[0].pboolVal = (cancel_default + ? VARIANT_TRUE:VARIANT_FALSE); + } + } + else + hr = DISP_E_MEMBERNOTFOUND; + return hr; +} +END_EVENT_SINK(GpgolCommandBarButtonEvents, IID_IOOMCommandBarButtonEvents) + + + + +static int +tagcmp (const char *a, const char *b) +{ + return strncmp (a, b, strlen (b)); +} + + +/* This is the event sink for a button click. */ +STDMETHODIMP +GpgolCommandBarButtonEvents::Click (LPDISPATCH button, PBOOL cancel_default) +{ + char *tag; + + (void)cancel_default; + log_debug ("%s:%s: Called", SRCNAME, __func__); + + { + char *tmp = get_object_name (button); + log_debug ("%s:%s: button is %p (%s)", + SRCNAME, __func__, button, tmp? tmp:"(null)"); + xfree (tmp); + } + + tag = get_oom_string (button, "Tag"); + log_debug ("%s:%s: button's tag is (%s)", + SRCNAME, __func__, tag? tag:"(null)"); + if (!tag) + ; + else if (!tagcmp (tag, "GpgOL_Start_Key_Manager")) + { + /* FIXME: We don't have the current window handle. */ + if (engine_start_keymanager (NULL)) + MessageBox (NULL, _("Could not start certificate manager"), + _("GpgOL"), MB_ICONERROR|MB_OK); + } + else if (!tagcmp (tag, "GpgOL_Inspector_Crypto_Info")) + { + /* FIXME: We should invoke the decrypt/verify again. */ + update_inspector_crypto_info (button); +#if 0 /* This is the code we used to use. */ + log_debug ("%s:%s: command CryptoState called\n", SRCNAME, __func__); + hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); + if (SUCCEEDED (hr)) + { + if (message_incoming_handler (message, hwnd, true)) + message_display_handler (eecb, hwnd); + } + else + log_debug_w32 (hr, "%s:%s: command CryptoState failed", + SRCNAME, __func__); + ul_release (message, __func__, __LINE__); + ul_release (mdb, __func__, __LINE__); +#endif + + } + + xfree (tag); + return S_OK; +} + + Added: trunk/src/cmdbarcontrols.h =================================================================== --- trunk/src/cmdbarcontrols.h (rev 0) +++ trunk/src/cmdbarcontrols.h 2009-10-28 19:26:06 UTC (rev 311) @@ -0,0 +1,63 @@ +/* cmdbarcontrols.h - Defs to handle the CommandBarControls + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifndef CMDBARCONTROLS_H +#define CMDBARCONTROLS_H + +#include +#include "oomhelp.h" + +DEFINE_OLEGUID(IID_IOOMCommandBarButtonEvents, 0x000c0351, 0, 0); + +typedef struct IOOMCommandBarButtonEvents IOOMCommandBarButtonEvents; +typedef IOOMCommandBarButtonEvents *LPOOMCOMMANDBARBUTTONEVENTS; + +struct IOOMCommandBarButton; +typedef IOOMCommandBarButton *LPOOMCOMMANDBARBUTTON; + + +EXTERN_C const IID IID_IOOMCommandBarButtonEvents; +#undef INTERFACE +#define INTERFACE IOOMCommandBarButtonEvents +DECLARE_INTERFACE_(IOOMCommandBarButtonEvents, IDispatch) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDispatch methods ***/ + STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE; + STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE; + STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE; + STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD, + DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE; + + /*** IOOMCommandBarButtonEvents methods ***/ + /* dispid=1 */ + STDMETHOD(Click)(THIS_ LPDISPATCH, PBOOL) PURE; +}; + + + +LPDISPATCH install_GpgolCommandBarButtonEvents_sink (LPDISPATCH button); + + + +#endif /*CMDBARCONTROLS_H*/ Modified: trunk/src/common.c =================================================================== --- trunk/src/common.c 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/common.c 2009-10-28 19:26:06 UTC (rev 311) @@ -223,10 +223,25 @@ void +fatal_error (const char *format, ...) +{ + va_list arg_ptr; + char buf[512]; + + va_start (arg_ptr, format); + vsnprintf (buf, sizeof buf -1, format, arg_ptr); + buf[sizeof buf - 1] = 0; + va_end (arg_ptr); + MessageBox (NULL, buf, "Fatal Error", MB_OK); + abort (); +} + + +void out_of_core (void) { - MessageBox (NULL, "Out of core!", "Fatal Error", MB_OK); - abort (); + MessageBox (NULL, "Out of core!", "Fatal Error", MB_OK); + abort (); } void* @@ -391,6 +406,38 @@ } +/* This function is similar to strncpy(). However it won't copy more + than N - 1 characters and makes sure that a Nul is appended. With N + given as 0, nothing will happen. With DEST given as NULL, memory + will be allocated using xmalloc (i.e. if it runs out of core the + function terminates). Returns DEST or a pointer to the allocated + memory. */ +char * +mem2str (char *dest, const void *src, size_t n) +{ + char *d; + const char *s; + + if (n) + { + if (!dest) + dest = xmalloc (n); + d = dest; + s = src ; + for (n--; n && *s; n--) + *d++ = *s++; + *d = 0; + } + else if (!dest) + { + dest = xmalloc (1); + *dest = 0; + } + + return dest; +} + + /* Strip off trailing white spaces from STRING. Returns STRING. */ char * trim_trailing_spaces (char *string) Modified: trunk/src/common.h =================================================================== --- trunk/src/common.h 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/common.h 2009-10-28 19:26:06 UTC (rev 311) @@ -242,6 +242,10 @@ const char *filename); +/*-- inspectors.cpp --*/ +int initialize_inspectors (void); + + #ifdef __cplusplus } #endif Added: trunk/src/decrypt-mask.bmp =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-mask.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/src/decrypt-verify-mask.bmp =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-verify-mask.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/src/decrypt-verify.bmp =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-verify.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/src/decrypt.bmp =================================================================== (Binary files differ) Modified: trunk/src/dialogs.h =================================================================== --- trunk/src/dialogs.h 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/dialogs.h 2009-10-28 19:26:06 UTC (rev 311) @@ -7,18 +7,27 @@ #define DIALOGS_H -/* Ids used for bitmaps. */ -#define IDB_DECRYPT 3001 /* Not used. */ -#define IDB_ENCRYPT 3002 -#define IDB_SIGN 3003 -#define IDB_ADD_KEYS 3004 -#define IDB_KEY_MANAGER 3005 -#define IDB_BANNER 3006 /* The g10 Code logo. */ -#define IDB_BANNER_HI 3007 /* Not used. */ -#define IDB_CRYPTO_STATE 3008 -#define IDB_PROTO_AUTO 3009 -#define IDB_PROTO_PGPMIME 3010 -#define IDB_PROTO_SMIME 3011 +/* Ids used for bitmaps. + Note: FOO_MASK must have a value of FOO + 1. */ +#define IDB_ENCRYPT 3004 +#define IDB_SIGN 3006 +#define IDB_SIGN_MASK 3007 +#define IDB_ADD_KEYS 3008 +#define IDB_KEY_MANAGER 3010 +#define IDB_KEY_MANAGER_MASK 3011 +#define IDB_BANNER 3012 /* The g10 Code logo. */ +#define IDB_BANNER_HI 3014 /* Not used. */ +#define IDB_CRYPTO_STATE 3016 +#define IDB_PROTO_AUTO 3018 /* Not used. */ +#define IDB_PROTO_PGPMIME 3020 /* Not used. */ +#define IDB_PROTO_SMIME 3022 /* Not used. */ +#define IDB_PROTO_SMIME_MASK 3023 /* Not used. */ +#define IDB_DECRYPT 3024 +#define IDB_DECRYPT_MASK 3025 +#define IDB_VERIFY 3026 +#define IDB_VERIFY_MASK 3027 +#define IDB_DECRYPT_VERIFY 3028 +#define IDB_DECRYPT_VERIFY_MASK 3029 /* Ids used for the main config dialog. */ Modified: trunk/src/dialogs.rc =================================================================== --- trunk/src/dialogs.rc 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/dialogs.rc 2009-10-28 19:26:06 UTC (rev 311) @@ -28,15 +28,26 @@ /*IDB_DECRYPT BITMAP DISCARDABLE "decrypt.bmp"*/ IDB_ENCRYPT BITMAP DISCARDABLE "encrypt.bmp" -IDB_SIGN BITMAP DISCARDABLE "sign.bmp" -IDB_KEY_MANAGER BITMAP DISCARDABLE "key_mana.bmp" IDB_BANNER BITMAP DISCARDABLE "logo.bmp" IDB_CRYPTO_STATE BITMAP DISCARDABLE "cryptostate.bmp" IDB_PROTO_AUTO BITMAP DISCARDABLE "proto-auto.bmp" IDB_PROTO_PGPMIME BITMAP DISCARDABLE "proto-pgpmime.bmp" IDB_PROTO_SMIME BITMAP DISCARDABLE "proto-smime.bmp" +IDB_PROTO_SMIME_MASK BITMAP DISCARDABLE "proto-smime-mask.bmp" +IDB_KEY_MANAGER BITMAP DISCARDABLE "key-manager.bmp" +IDB_KEY_MANAGER_MASK BITMAP DISCARDABLE "key-manager-mask.bmp" +IDB_DECRYPT BITMAP DISCARDABLE "decrypt.bmp" +IDB_DECRYPT_MASK BITMAP DISCARDABLE "decrypt-mask.bmp" +IDB_VERIFY BITMAP DISCARDABLE "verify.bmp" +IDB_VERIFY_MASK BITMAP DISCARDABLE "verify-mask.bmp" +IDB_DECRYPT_VERIFY BITMAP DISCARDABLE "decrypt-verify.bmp" +IDB_DECRYPT_VERIFY_MASK BITMAP DISCARDABLE "decrypt-verify-mask.bmp" +IDB_SIGN BITMAP DISCARDABLE "sign.bmp" +IDB_SIGN_MASK BITMAP DISCARDABLE "sign-mask.bmp" + + IDD_GPG_OPTIONS DIALOG DISCARDABLE 0, 0, 266, 274 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "GpgOL" @@ -52,7 +63,7 @@ /* Send options box. */ GROUPBOX "send-options", IDC_G_SEND, - 9, 40, 250, 58 + 9, 40, 250, 38 CONTROL "encrypt-by-default", IDC_ENCRYPT_DEFAULT, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, @@ -62,17 +73,9 @@ "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 24, 61, 215, 10 - CONTROL "openpgp-by-default", IDC_OPENPGP_DEFAULT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 24, 72, 215, 10 - - CONTROL "smime-by-default", IDC_SMIME_DEFAULT, - "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 24, 83, 215, 10 - /* Receive options box. */ GROUPBOX "recv-options", IDC_G_RECV, - 9, 104, 250, 36 + 9, 82, 250, 36 /* We have no reliable way to detect the preview window, thus we don't show this option. */ @@ -82,11 +85,11 @@ CONTROL "prefer-html", IDC_PREFER_HTML, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 24, 114, 215, 10 + 24, 94, 215, 10 CONTROL "body-as-attachment", IDC_BODY_AS_ATTACHMENT, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, - 24, 125, 215, 10 + 24, 103, 215, 10 /* Stuff at the lower left corner. */ LTEXT "GpgOL by g10 Code GmbH", IDC_G10CODE_STRING, Added: trunk/src/explorers.cpp =================================================================== --- trunk/src/explorers.cpp (rev 0) +++ trunk/src/explorers.cpp 2009-10-28 19:26:06 UTC (rev 311) @@ -0,0 +1,164 @@ +/* explorers.cpp - Code to handle the OOM Explorers + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "common.h" +#include "oomhelp.h" +#include "explorers.h" +#include "dialogs.h" /* IDB_xxx */ +#include "cmdbarcontrols.h" + +#include "eventsink.h" + +BEGIN_EVENT_SINK(GpgolExplorersEvents, IOOMExplorersEvents) + STDMETHOD (NewExplorer) (THIS_ LPOOMEXPLORER); +EVENT_SINK_DEFAULT_DTOR(GpgolExplorersEvents) +EVENT_SINK_INVOKE(GpgolExplorersEvents) +{ + HRESULT hr; + (void)lcid; (void)riid; (void)result; (void)exepinfo; (void)argerr; + + if (dispid == 0xf001 && (flags & DISPATCH_METHOD)) + { + if (!parms) + hr = DISP_E_PARAMNOTOPTIONAL; + else if (parms->cArgs != 1) + hr = DISP_E_BADPARAMCOUNT; + else if (parms->rgvarg[0].vt != VT_DISPATCH) + hr = DISP_E_BADVARTYPE; + else + hr = NewExplorer ((LPOOMEXPLORER)parms->rgvarg[0].pdispVal); + } + else + hr = DISP_E_MEMBERNOTFOUND; + return hr; +} +END_EVENT_SINK(GpgolExplorersEvents, IID_IOOMExplorersEvents) + + + + +/* The method called by outlook for each new explorer. Note that + Outlook sometimes reuses Inspectro objects thus this event is not + an indication for a newly opened Explorer. */ +STDMETHODIMP +GpgolExplorersEvents::NewExplorer (LPOOMEXPLORER explorer) +{ + log_debug ("%s:%s: Called", SRCNAME, __func__); + + add_explorer_controls (explorer); + return S_OK; +} + + +/* Add buttons to the explorer. */ +void +add_explorer_controls (LPOOMEXPLORER explorer) +{ + LPDISPATCH pObj, pDisp, pTmp; + + log_debug ("%s:%s: Enter", SRCNAME, __func__); + + /* In theory we should take a lock here to avoid a race between the + test for a new control and the creation. However, we are not + called from a second thread. */ + + /* Check that our controls do not already exist. */ + pObj = get_oom_object (explorer, "CommandBars"); + if (!pObj) + { + log_debug ("%s:%s: CommandBars not found", SRCNAME, __func__); + return; + } + pDisp = get_oom_control_bytag (pObj, "GpgOL_Start_Key_Manager"); + pObj->Release (); + pObj = NULL; + if (pDisp) + { + pDisp->Release (); + log_debug ("%s:%s: Leave (Controls are already added)", + SRCNAME, __func__); + return; + } + + /* Fixme: To avoid an extra lookup we should use the CommandBars + object to start the search for the controls. I tried this but + Outlooked crashed. Quite likely my error but I was not able to + find the problem. */ + + /* Create the Start-Key-Manager menu entry. */ + pDisp = get_oom_object (explorer, + "CommandBars.FindControl(,30007).get_Controls"); + if (!pDisp) + log_debug ("%s:%s: Menu Popup Extras not found\n", SRCNAME, __func__); + else + { + pTmp = add_oom_button (pDisp); + pDisp->Release (); + pDisp = pTmp; + if (pDisp) + { + put_oom_string (pDisp, "Tag", "GpgOL_Start_Key_Manager"); + put_oom_int (pDisp, "Style", msoButtonIconAndCaption ); + put_oom_string (pDisp, "Caption", _("GnuPG Certificate &Manager")); + put_oom_string (pDisp, "TooltipText", + _("Open the certificate manager")); + put_oom_icon (pDisp, IDB_KEY_MANAGER, 16); + + install_GpgolCommandBarButtonEvents_sink (pDisp); + pDisp->Release (); + } + } + + /* Create the Start-Key-Manager toolbar icon. Not ethat we need to + use a different tag name here. If we won't do that event sink + would be called twice. */ + pDisp = get_oom_object (explorer, + "CommandBars.Item(Standard).get_Controls"); + if (!pDisp) + log_debug ("%s:%s: CommandBar \"Standard\" not found\n", + SRCNAME, __func__); + else + { + pTmp = add_oom_button (pDisp); + pDisp->Release (); + pDisp = pTmp; + if (pDisp) + { + put_oom_string (pDisp, "Tag", "GpgOL_Start_Key_Manager at t"); + put_oom_int (pDisp, "Style", msoButtonIcon ); + put_oom_string (pDisp, "TooltipText", + _("Open the certificate manager")); + put_oom_icon (pDisp, IDB_KEY_MANAGER, 16); + + install_GpgolCommandBarButtonEvents_sink (pDisp); + /* Fixme: store the event sink object somewhere. */ + pDisp->Release (); + } + } + + log_debug ("%s:%s: Leave", SRCNAME, __func__); +} + Added: trunk/src/explorers.h =================================================================== --- trunk/src/explorers.h (rev 0) +++ trunk/src/explorers.h 2009-10-28 19:26:06 UTC (rev 311) @@ -0,0 +1,91 @@ +/* explorers.h - Defs to handle the OOM Explorers + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifndef EXPLORERS_H +#define EXPLORERS_H + +#include "myexchext.h" + +DEFINE_OLEGUID(IID_IOOMExplorer, 0x00063003, 0, 0); +DEFINE_OLEGUID(IID_IOOMExplorers, 0x0006300A, 0, 0); +DEFINE_OLEGUID(IID_IOOMExplorersEvents, 0x00063078, 0, 0); + + +typedef struct IOOMExplorer IOOMExplorer; +typedef IOOMExplorer *LPOOMEXPLORER; + +typedef struct IOOMExplorersEvents IOOMExplorersEvents; +typedef IOOMExplorersEvents *LPOOMEXPLORERSEVENTS; + + +EXTERN_C const IID IID_IOOMExplorer; +#undef INTERFACE +#define INTERFACE IOOMExplorer +DECLARE_INTERFACE_(IOOMExplorer, IDispatch) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDispatch methods ***/ + STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE; + STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE; + STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE; + STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD, + DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE; + + /*** IOOM_Explorer methods ***/ + /* Activate, Close, .... */ +}; + + +EXTERN_C const IID IID_IOOMExplorersEvents; +#undef INTERFACE +#define INTERFACE IOOMExplorersEvents +DECLARE_INTERFACE_(IOOMExplorersEvents, IDispatch) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + /*** IDispatch methods ***/ + STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE; + STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE; + STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE; + STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD, + DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE; + + /*** IOOMExplorersEvents methods ***/ + /* dispid=0xf001 */ + STDMETHOD(NewExplorer)(THIS_ LPOOMEXPLORER) PURE; +}; + + +/* Install an explorers collection event sink in OBJ. Returns the + event sink object which must be released by the caller if it is not + anymore required. */ +LPDISPATCH install_GpgolExplorersEvents_sink (LPDISPATCH obj); + +void add_explorer_controls (LPOOMEXPLORER explorer); + + + +#endif /*EXPLORERS_H*/ Modified: trunk/src/ext-commands.cpp =================================================================== --- trunk/src/ext-commands.cpp 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/ext-commands.cpp 2009-10-28 19:26:06 UTC (rev 311) @@ -40,6 +40,7 @@ #include "engine.h" #include "ext-commands.h" #include "revert.h" +#include "explorers.h" #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \ SRCNAME, __func__, __LINE__); \ @@ -103,9 +104,7 @@ m_nCmdProtoSmime = 0; m_nCmdEncrypt = 0; m_nCmdSign = 0; - m_nCmdKeyManager = 0; m_nCmdRevertFolder = 0; - m_nCmdCryptoState = 0; m_nCmdDebug0 = 0; m_nCmdDebug1 = 0; m_nCmdDebug2 = 0; @@ -213,90 +212,8 @@ } -static void -check_toolbar (LPEXCHEXTCALLBACK eecb, struct toolbar_info_s *toolbar_info, - UINT cmd_id, int checked) -{ - HWND hwnd; - toolbar_info_t tb_info; - TBBUTTONINFOA tbb; - eecb->GetToolbar (EETBID_STANDARD, &hwnd); - if (debug_commands) - log_debug ("check_toolbar: eecb=%p cmd_id=%u checked=%d -> hwnd=%p\n", - eecb, cmd_id, checked, hwnd); - - for (tb_info = toolbar_info; tb_info; tb_info = tb_info->next ) - if (tb_info->cmd_id == cmd_id) - break; - if (!tb_info) - { - log_error ("check_toolbar: no such toolbar button"); - return; - } - if (!tb_info->did_qbi) - { - if(debug_commands) - log_debug ("check_toolbar: button(cmd_id=%d) not yet initialized", - cmd_id); - return; - } - - tbb.cbSize = sizeof (tbb); - tbb.dwMask = TBIF_COMMAND | TBIF_STATE | TBIF_STYLE; - if (!SendMessage (hwnd, TB_GETBUTTONINFO, cmd_id, (LPARAM)&tbb)) - log_error_w32 (-1, "TB_GETBUTTONINFO failed"); - else - { - tbb.cbSize = sizeof (tbb); - tbb.dwMask = TBIF_STATE; - if (checked) - tbb.fsState |= TBSTATE_CHECKED; - else - tbb.fsState &= ~TBSTATE_CHECKED; - if (!SendMessage (hwnd, TB_SETBUTTONINFO, cmd_id, (LPARAM)&tbb)) - log_error_w32 (-1, "TB_SETBUTTONINFO failed"); - } -} - - -static void -check_menu_toolbar (LPEXCHEXTCALLBACK eecb, - struct toolbar_info_s *toolbar_info, - UINT cmd_id, int checked) -{ - check_menu (eecb, cmd_id, checked); - check_toolbar (eecb, toolbar_info, cmd_id, checked); -} - - void -GpgolExtCommands::update_protocol_menu (LPEXCHEXTCALLBACK eecb) -{ - if (debug_commands) - log_debug ("update_protocol_menu called\n"); - switch (m_pExchExt->m_protoSelection) - { - case PROTOCOL_OPENPGP: - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoAuto, FALSE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoPgpmime, TRUE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoSmime, FALSE); - break; - case PROTOCOL_SMIME: - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoAuto, FALSE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoPgpmime, FALSE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoSmime, TRUE); - break; - default: - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoAuto, TRUE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoPgpmime, FALSE); - check_menu_toolbar (eecb, m_toolbar_info, m_nCmdProtoSmime, FALSE); - break; - } -} - - -void GpgolExtCommands::add_toolbar (LPTBENTRY tbearr, UINT n_tbearr, ...) { va_list arg_ptr; @@ -365,7 +282,6 @@ - /* Called by Exchange to install commands and toolbar buttons. Returns S_FALSE to signal Exchange to continue calling extensions. */ STDMETHODIMP @@ -396,6 +312,7 @@ log_debug ("%s:%s: context=%s flags=0x%lx\n", SRCNAME, __func__, ext_context_name (m_lContext), lFlags); + show_event_object (eecb, __func__); /* Outlook 2003 sometimes displays the plaintext and sometimes the original undecrypted text when doing a reply. This seems to @@ -509,44 +426,8 @@ /* Now install menu and toolbar items. */ if (m_lContext == EECONTEXT_READNOTEMESSAGE) { - int is_encrypted = 0; - int not_a_gpgol_message = 0; - - LPMDB mdb = NULL; - LPMESSAGE message = NULL; - - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (FAILED(hr)) - log_debug ("%s:%s: getObject failed: hr=%#lx\n", SRCNAME, __func__, hr); - else - { - switch (mapi_get_message_type (message)) - { - case MSGTYPE_GPGOL_MULTIPART_ENCRYPTED: - case MSGTYPE_GPGOL_OPAQUE_ENCRYPTED: - case MSGTYPE_GPGOL_PGP_MESSAGE: - is_encrypted = 1; - if ( mapi_test_sig_status (message) ) - is_encrypted++; - break; - case MSGTYPE_GPGOL: - case MSGTYPE_SMIME: - case MSGTYPE_UNKNOWN: - not_a_gpgol_message = 1; - break; - default: - break; - } - } - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - add_menu (eecb, pnCommandIDBase, "@", NULL, - (opt.disable_gpgol || not_a_gpgol_message)? - "" : _("GpgOL Decrypt/Verify"), &m_nCmdCryptoState, - opt.enable_debug? "GpgOL Debug-0 (display crypto info)":"", - &m_nCmdDebug0, (opt.enable_debug && !opt.disable_gpgol)? "GpgOL Debug-1 (open_inspector)":"", &m_nCmdDebug1, (opt.enable_debug && !opt.disable_gpgol)? @@ -555,58 +436,21 @@ &m_nCmdDebug3, NULL); - if (!opt.disable_gpgol && !not_a_gpgol_message) - add_toolbar (pTBEArray, nTBECnt, - is_encrypted == 2 - ? _("This is a signed and encrypted message.\n" - "Click for more information. ") - : is_encrypted - ? _("This is an encrypted message.\n" - "Click for more information. ") - : _("This is a signed message.\n" - "Click for more information. "), - IDB_CRYPTO_STATE, m_nCmdCryptoState, - NULL, 0, 0); - } else if (m_lContext == EECONTEXT_SENDNOTEMESSAGE && !opt.disable_gpgol) { add_menu (eecb, pnCommandIDBase, "@", NULL, - _(">GnuPG protocol"), NULL, - _("auto"), &m_nCmdProtoAuto, - _("PGP/MIME"),&m_nCmdProtoPgpmime, - _("S/MIME"), &m_nCmdProtoSmime, - "<", NULL, _("&encrypt message with GnuPG"), &m_nCmdEncrypt, _("&sign message with GnuPG"), &m_nCmdSign, NULL ); - /* We display the protocol icons only for Outlook 2007 becuase - there seems to be no way to add a plain menu item. */ - if (get_ol_main_version () > 11) add_toolbar (pTBEArray, nTBECnt, "Encrypt", IDB_ENCRYPT, m_nCmdEncrypt, "Sign", IDB_SIGN, m_nCmdSign, - "Autoselect", IDB_PROTO_AUTO, m_nCmdProtoAuto, - "Use PGP/MIME", IDB_PROTO_PGPMIME, m_nCmdProtoPgpmime, - "Use/MIME", IDB_PROTO_SMIME, m_nCmdProtoSmime, NULL, 0, 0); - else - add_toolbar (pTBEArray, nTBECnt, - "Encrypt", IDB_ENCRYPT, m_nCmdEncrypt, - "Sign", IDB_SIGN, m_nCmdSign, - NULL, 0, 0); - if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'A') - m_pExchExt->m_protoSelection = PROTOCOL_UNKNOWN; - else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'P') - m_pExchExt->m_protoSelection = PROTOCOL_OPENPGP; - else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'X') - m_pExchExt->m_protoSelection = PROTOCOL_SMIME; - else - m_pExchExt->m_protoSelection = opt.default_protocol; - update_protocol_menu (eecb); + m_pExchExt->m_protoSelection = opt.default_protocol; if (draft_info && draft_info[0] == 'E') m_pExchExt->m_gpgEncrypt = true; @@ -631,13 +475,9 @@ { add_menu (eecb, pnCommandIDBase, "@", NULL, - _("GnuPG Certificate &Manager"), &m_nCmdKeyManager, _("Remove GpgOL flags from this folder"), &m_nCmdRevertFolder, NULL); - add_toolbar (pTBEArray, nTBECnt, - _("Open the certificate manager"), IDB_KEY_MANAGER, m_nCmdKeyManager, - NULL, 0, 0); } xfree (draft_info); @@ -664,6 +504,8 @@ SRCNAME, __func__, nCommandID, nCommandID, ext_context_name (m_lContext), hwnd); + show_event_object (eecb, __func__); + if (nCommandID == SC_CLOSE && m_lContext == EECONTEXT_READNOTEMESSAGE) { /* This is the system close command. Replace it with our own to @@ -733,57 +575,6 @@ log_debug ("%s:%s: command Forward called\n", SRCNAME, __func__); return S_FALSE; /* Pass it on. */ } - else if (nCommandID == m_nCmdCryptoState - && m_lContext == EECONTEXT_READNOTEMESSAGE) - { - log_debug ("%s:%s: command CryptoState called\n", SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - if (message_incoming_handler (message, hwnd, true)) - message_display_handler (eecb, hwnd); - } - else - log_debug_w32 (hr, "%s:%s: command CryptoState failed", - SRCNAME, __func__); - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - } - else if (nCommandID == m_nCmdProtoAuto - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - log_debug ("%s:%s: command ProtoAuto called\n", SRCNAME, __func__); - m_pExchExt->m_protoSelection = PROTOCOL_UNKNOWN; - update_protocol_menu (eecb); - } - else if (nCommandID == m_nCmdProtoPgpmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - log_debug ("%s:%s: command ProtoPgpmime called\n", SRCNAME, __func__); - m_pExchExt->m_protoSelection = PROTOCOL_OPENPGP; - update_protocol_menu (eecb); - } - else if (nCommandID == m_nCmdProtoSmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - log_debug ("%s:%s: command ProtoSmime called\n", SRCNAME, __func__); - if (opt.enable_smime) - { - m_pExchExt->m_protoSelection = PROTOCOL_SMIME; - update_protocol_menu (eecb); - } - else - { - MessageBox (hwnd, - _("Support for S/MIME has not been enabled.\n" - "\n" - "To enable S/MIME support, open the option dialog" - " and check \"Enable the S/MIME support\". The" - " option dialog can be found in the main menu at:" - " Extras->Options->GpgOL.\n"), - "GpgOL", MB_ICONHAND|MB_OK); - } - } else if (nCommandID == m_nCmdEncrypt && m_lContext == EECONTEXT_SENDNOTEMESSAGE) { @@ -798,14 +589,6 @@ m_pExchExt->m_gpgSign = !m_pExchExt->m_gpgSign; check_menu (eecb, m_nCmdSign, m_pExchExt->m_gpgSign); } - else if (nCommandID == m_nCmdKeyManager - && m_lContext == EECONTEXT_VIEWER) - { - log_debug ("%s:%s: command KeyManager called\n", SRCNAME, __func__); - if (engine_start_keymanager (hwnd)) - MessageBox (NULL, _("Could not start certificate manager"), - _("GpgOL"), MB_ICONERROR|MB_OK); - } else if (nCommandID == m_nCmdRevertFolder && m_lContext == EECONTEXT_VIEWER) { @@ -953,31 +736,12 @@ { (void)eecb; - if (nCommandID == m_nCmdProtoAuto + show_event_object (eecb, __func__); + + if (nCommandID == m_nCmdEncrypt && m_lContext == EECONTEXT_SENDNOTEMESSAGE) { MessageBox (m_hWnd, - _("Select this option to automatically select the protocol."), - "GpgOL", MB_OK); - } - else if (nCommandID == m_nCmdProtoPgpmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - MessageBox (m_hWnd, - _("Select this option to select the PGP/MIME protocol."), - "GpgOL", MB_OK); - } - else if (nCommandID == m_nCmdProtoSmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - MessageBox (m_hWnd, - _("Select this option to select the S/MIME protocol."), - "GpgOL", MB_OK); - } - else if (nCommandID == m_nCmdEncrypt - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - MessageBox (m_hWnd, _("Select this option to encrypt the message."), "GpgOL", MB_OK); } @@ -988,13 +752,6 @@ _("Select this option to sign the message."), "GpgOL", MB_OK); } - else if (nCommandID == m_nCmdKeyManager - && m_lContext == EECONTEXT_VIEWER) - { - MessageBox (m_hWnd, - _("Select this option to open the certificate manager"), - "GpgOL", MB_OK); - } else return S_FALSE; @@ -1014,44 +771,14 @@ GpgolExtCommands::QueryHelpText(UINT nCommandID, ULONG lFlags, LPTSTR pszText, UINT nCharCnt) { - - if (nCommandID == m_nCmdProtoAuto + + if (nCommandID == m_nCmdEncrypt && m_lContext == EECONTEXT_SENDNOTEMESSAGE) { if (lFlags == EECQHT_STATUS) lstrcpyn (pszText, ".", nCharCnt); if (lFlags == EECQHT_TOOLTIP) lstrcpyn (pszText, - _("Automatically select the protocol for sign/encrypt"), - nCharCnt); - } - else if (nCommandID == m_nCmdProtoPgpmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, - _("Use PGP/MIME for sign/encrypt"), - nCharCnt); - } - else if (nCommandID == m_nCmdProtoSmime - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, - _("Use S/MIME for sign/encrypt"), - nCharCnt); - } - else if (nCommandID == m_nCmdEncrypt - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, _("Encrypt message with GnuPG"), nCharCnt); } @@ -1065,16 +792,6 @@ _("Sign message with GnuPG"), nCharCnt); } - else if (nCommandID == m_nCmdKeyManager - && m_lContext == EECONTEXT_VIEWER) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, - _("Open the GpgOL certificate manager"), - nCharCnt); - } else return S_FALSE; @@ -1144,25 +861,6 @@ if (m_pExchExt->m_gpgSign) pTBB->fsState |= TBSTATE_CHECKED; } - else if (tb_info->cmd_id == m_nCmdProtoAuto) - { - pTBB->fsStyle |= TBSTYLE_CHECK; - if (m_pExchExt->m_protoSelection != PROTOCOL_OPENPGP - && m_pExchExt->m_protoSelection != PROTOCOL_SMIME) - pTBB->fsState |= TBSTATE_CHECKED; - } - else if (tb_info->cmd_id == m_nCmdProtoPgpmime) - { - pTBB->fsStyle |= TBSTYLE_CHECK; - if (m_pExchExt->m_protoSelection == PROTOCOL_OPENPGP) - pTBB->fsState |= TBSTATE_CHECKED; - } - else if (tb_info->cmd_id == m_nCmdProtoSmime) - { - pTBB->fsStyle |= TBSTYLE_CHECK; - if (m_pExchExt->m_protoSelection == PROTOCOL_SMIME) - pTBB->fsState |= TBSTATE_CHECKED; - } return S_OK; } Modified: trunk/src/ext-commands.h =================================================================== --- trunk/src/ext-commands.h 2009-09-28 09:51:56 UTC (rev 310) +++ trunk/src/ext-commands.h 2009-10-28 19:26:06 UTC (rev 311) @@ -45,9 +45,7 @@ UINT m_nCmdProtoSmime; UINT m_nCmdEncrypt; UINT m_nCmdSign; - UINT m_nCmdKeyManager; UINT m_nCmdRevertFolder; - UINT m_nCmdCryptoState; UINT m_nCmdDebug0; UINT m_nCmdDebug1; UINT m_nCmdDebug2; Added: trunk/src/inspectors.cpp =================================================================== --- trunk/src/inspectors.cpp (rev 0) +++ trunk/src/inspectors.cpp 2009-10-28 19:26:06 UTC (rev 311) @@ -0,0 +1,496 @@ +/* inspectors.cpp - Code to handle OOM Inspectors + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "common.h" +#include "oomhelp.h" +#include "myexchext.h" +#include "inspectors.h" +#include "dialogs.h" /* IDB_xxx */ +#include "cmdbarcontrols.h" + +#include "eventsink.h" + + +/* Event sink for an Inspectors collection object. */ +BEGIN_EVENT_SINK(GpgolInspectorsEvents, IOOMInspectorsEvents) + STDMETHOD (NewInspector) (THIS_ LPOOMINSPECTOR); +EVENT_SINK_DEFAULT_DTOR(GpgolInspectorsEvents) +EVENT_SINK_INVOKE(GpgolInspectorsEvents) +{ + HRESULT hr; + (void)lcid; (void)riid; (void)result; (void)exepinfo; (void)argerr; + + if (dispid == 0xf001 && (flags & DISPATCH_METHOD)) + { + if (!parms) + hr = DISP_E_PARAMNOTOPTIONAL; + else if (parms->cArgs != 1) + hr = DISP_E_BADPARAMCOUNT; + else if (parms->rgvarg[0].vt != VT_DISPATCH) + hr = DISP_E_BADVARTYPE; + else + hr = NewInspector ((LPOOMINSPECTOR)parms->rgvarg[0].pdispVal); + } + else + hr = DISP_E_MEMBERNOTFOUND; + return hr; +} +END_EVENT_SINK(GpgolInspectorsEvents, IID_IOOMInspectorsEvents) + + + +/* Event sink for an Inspector object. */ +BEGIN_EVENT_SINK(GpgolInspectorEvents, IOOMInspectorEvents) + STDMETHOD_ (void, Activate) (THIS_); + STDMETHOD_ (void, Close) (THIS_); + STDMETHOD_ (void, Deactivate) (THIS_); +EVENT_SINK_DEFAULT_DTOR(GpgolInspectorEvents) +EVENT_SINK_INVOKE(GpgolInspectorEvents) +{ + HRESULT hr = S_OK; + (void)lcid; (void)riid; (void)result; (void)exepinfo; (void)argerr; + + if ((dispid == 0xf001 || dispid == 0xf006 || dispid == 0xf008) + && (flags & DISPATCH_METHOD)) + { + if (!parms) + hr = DISP_E_PARAMNOTOPTIONAL; + else if (parms->cArgs != 0) + hr = DISP_E_BADPARAMCOUNT; + else if (dispid == 0xf001) + Activate (); + else if (dispid == 0xf006) + Deactivate (); + else if (dispid == 0xf008) + Close (); + } + else + hr = DISP_E_MEMBERNOTFOUND; + return hr; +} +END_EVENT_SINK(GpgolInspectorEvents, IID_IOOMInspectorEvents) + + + +/* To avoid messing around with the OOM (adding extra objects as user + properties and such), we keep our own information structure about + inspectors. */ +struct inspector_info_s +{ + /* We are pretty lame and keep all inspectors in a linked list. */ + struct inspector_info_s *next; + + /* The inspector object. */ + LPOOMINSPECTOR inspector; + + /* The event sink object. This is used by the event methods to + locate the inspector object. */ + LPOOMINSPECTOREVENTS eventsink; + + /* The event sink object for the crypto info button. */ + LPDISPATCH crypto_info_sink; + +}; +typedef struct inspector_info_s *inspector_info_t; + +/* The list of all inspectors and a lock for it. */ +static inspector_info_t all_inspectors; +static HANDLE all_inspectors_lock; + +/* Initialize this module. Returns 0 on success. Called once by dllinit. */ +int +initialize_inspectors (void) +{ + SECURITY_ATTRIBUTES sa; + + memset (&sa, 0, sizeof sa); + sa.bInheritHandle = FALSE; + sa.lpSecurityDescriptor = NULL; + sa.nLength = sizeof sa; + all_inspectors_lock = CreateMutex (&sa, FALSE, NULL); + return !all_inspectors_lock; +} + + +/* Acquire the all_inspectors_lock. No error is returned because we + can't do anything anyway. */ +static void +lock_all_inspectors (void) +{ + int ec = WaitForSingleObject (all_inspectors_lock, INFINITE); + if (ec != WAIT_OBJECT_0) + { + log_error ("%s:%s: waiting on mutex failed: ec=%#x\n", + SRCNAME, __func__, ec); + fatal_error ("%s:%s: waiting on mutex failed: ec=%#x\n", + SRCNAME, __func__, ec); + } +} + + +/* Release the all_inspectors_lock. No error is returned because this + is a fatal error anyway and there is no way to clean up. */ +static void +unlock_all_inspectors (void) +{ + if (!ReleaseMutex (all_inspectors_lock)) + { + log_error_w32 (-1, "%s:%s: ReleaseMutex failed", SRCNAME, __func__); + fatal_error ("%s:%s: ReleaseMutex failed", SRCNAME, __func__); + } +} + + +/* Register the inspector object INSPECTOR along with its event SINK. */ +static void +register_inspector (LPOOMINSPECTOR inspector, LPOOMINSPECTOREVENTS sink) +{ + inspector_info_t item; + + item = (inspector_info_t)xcalloc (1, sizeof *item); + lock_all_inspectors (); + inspector->AddRef (); + item->inspector = inspector; + + sink->AddRef (); + item->eventsink = sink; + + item->next = all_inspectors; + all_inspectors = item; + + unlock_all_inspectors (); +} + + +/* Deregister the inspector with the event SINK. */ +static void +deregister_inspector (LPOOMINSPECTOREVENTS sink) +{ + inspector_info_t r, rprev; + + if (!sink) + return; + + lock_all_inspectors (); + for (r = all_inspectors, rprev = NULL; r; rprev = r, r = r->next) + if (r->eventsink == sink) + { + if (!rprev) + all_inspectors = r->next; + else + rprev->next = r->next; + r->next = NULL; + break; + } + unlock_all_inspectors (); + if (!r) + { From cvs at cvs.gnupg.org Thu Oct 29 19:49:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 29 Oct 2009 19:49:32 +0100 Subject: [svn] GpgOL - r312 - in trunk: po src Message-ID: Author: wk Date: 2009-10-29 19:49:32 +0100 (Thu, 29 Oct 2009) New Revision: 312 Added: trunk/src/decrypt-16.bmp trunk/src/decrypt-16m.bmp trunk/src/decrypt-verify-16.bmp trunk/src/decrypt-verify-16m.bmp trunk/src/encrypt-16.bmp trunk/src/key-manager-16.bmp trunk/src/key-manager-16m.bmp trunk/src/key-manager-32.bmp trunk/src/key-manager-32m.bmp trunk/src/sign-16.bmp trunk/src/sign-16m.bmp trunk/src/verify-16.bmp trunk/src/verify-16m.bmp Removed: trunk/src/decrypt-mask.bmp trunk/src/decrypt-verify-mask.bmp trunk/src/decrypt-verify.bmp trunk/src/decrypt.bmp trunk/src/encrypt.bmp trunk/src/key-manager-mask.bmp trunk/src/key-manager.bmp trunk/src/sign-mask.bmp trunk/src/sign.bmp trunk/src/verify-mask.bmp trunk/src/verify.bmp Modified: trunk/po/de.po trunk/po/sv.po trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/cmdbarcontrols.cpp trunk/src/dialogs.h trunk/src/dialogs.rc trunk/src/explorers.cpp trunk/src/explorers.h trunk/src/ext-commands.cpp trunk/src/ext-commands.h trunk/src/inspectors.cpp trunk/src/inspectors.h trunk/src/oomhelp.cpp trunk/src/oomhelp.h trunk/src/revert.cpp trunk/src/revert.h trunk/src/util.h Log: All controls are now done via the OOM model. Sign and encrypt buttons have no action yet. Some other functions are not yet functional. All 16px icons are integrated. Prepared for other sized icons. [The diff below has been truncated] Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/ChangeLog 2009-10-29 18:49:32 UTC (rev 312) @@ -1,3 +1,9 @@ +2009-10-29 Werner Koch + + * ext-commands.cpp: Remove m_nCmdDebugN, m_nCmdRevertFolder, + m_nCmdSign, m_nCmdEncrypt and all related code. Now handled in + inspectors.cpp. + 2009-10-28 Werner Koch * ext-commands.cpp: Remove m_nCmdCryptoState and all related code; Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/Makefile.am 2009-10-29 18:49:32 UTC (rev 312) @@ -15,15 +15,16 @@ bin_PROGRAMS = gpgol #treeview -EXTRA_DIST = versioninfo.rc.in mapi32.def $(unused_sources) Outlook.gpl \ - logo.bmp encrypt.bmp \ - proto-auto.bmp proto-pgpmime.bmp proto-smime.bmp \ - cryptostate.bmp \ - key-manager.bmp key-manager-mask.bmp \ - decrypt.bmp decrypt-mask.bmp \ - verify.bmp verify-mask.bmp \ - decrypt-verify.bmp decrypt-verify-mask.bmp \ - sign.bmp sign-mask.bmp +EXTRA_DIST = \ + versioninfo.rc.in mapi32.def $(unused_sources) Outlook.gpl \ + encrypt-16.bmp encrypt-16m.bmp \ + sign-16.bmp sign-16m.bmp \ + key-manager-16.bmp key-manager-16m.bmp \ + key-manager-32.bmp key-manager-32m.bmp \ + decrypt-16.bmp decrypt-16m.bmp \ + verify-16.bmp verify-16m.bmp \ + decrypt-verify-16.bmp decrypt-verify-16m.bmp \ + logo.bmp EXEEXT = .dll Modified: trunk/src/cmdbarcontrols.cpp =================================================================== --- trunk/src/cmdbarcontrols.cpp 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/cmdbarcontrols.cpp 2009-10-29 18:49:32 UTC (rev 312) @@ -28,6 +28,7 @@ #include "oomhelp.h" #include "cmdbarcontrols.h" #include "inspectors.h" +#include "explorers.h" #include "engine.h" #include "eventsink.h" @@ -37,6 +38,7 @@ Click event. */ BEGIN_EVENT_SINK(GpgolCommandBarButtonEvents, IOOMCommandBarButtonEvents) STDMETHOD (Click) (THIS_ LPDISPATCH, PBOOL); +EVENT_SINK_DEFAULT_CTOR(GpgolCommandBarButtonEvents) EVENT_SINK_DEFAULT_DTOR(GpgolCommandBarButtonEvents) EVENT_SINK_INVOKE(GpgolCommandBarButtonEvents) { @@ -69,34 +71,32 @@ -static int -tagcmp (const char *a, const char *b) -{ - return strncmp (a, b, strlen (b)); -} - - /* This is the event sink for a button click. */ STDMETHODIMP GpgolCommandBarButtonEvents::Click (LPDISPATCH button, PBOOL cancel_default) { char *tag; + int instid; (void)cancel_default; - log_debug ("%s:%s: Called", SRCNAME, __func__); + tag = get_oom_string (button, "Tag"); + instid = get_oom_int (button, "InstanceId"); { char *tmp = get_object_name (button); - log_debug ("%s:%s: button is %p (%s)", - SRCNAME, __func__, button, tmp? tmp:"(null)"); + log_debug ("%s:%s: button is %p (%s) tag is (%s) instid %d", + SRCNAME, __func__, button, + tmp? tmp:"(null)", + tag? tag:"(null)", instid); xfree (tmp); } - tag = get_oom_string (button, "Tag"); - log_debug ("%s:%s: button's tag is (%s)", - SRCNAME, __func__, tag? tag:"(null)"); if (!tag) ; + else if (!tagcmp (tag, "GpgOL_Inspector")) + { + proc_inspector_button_click (button, tag, instid); + } else if (!tagcmp (tag, "GpgOL_Start_Key_Manager")) { /* FIXME: We don't have the current window handle. */ @@ -104,25 +104,9 @@ MessageBox (NULL, _("Could not start certificate manager"), _("GpgOL"), MB_ICONERROR|MB_OK); } - else if (!tagcmp (tag, "GpgOL_Inspector_Crypto_Info")) + else if (!tagcmp (tag, "GpgOL_Revert_Folder")) { - /* FIXME: We should invoke the decrypt/verify again. */ - update_inspector_crypto_info (button); -#if 0 /* This is the code we used to use. */ - log_debug ("%s:%s: command CryptoState called\n", SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - if (message_incoming_handler (message, hwnd, true)) - message_display_handler (eecb, hwnd); - } - else - log_debug_w32 (hr, "%s:%s: command CryptoState failed", - SRCNAME, __func__); - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); -#endif - + run_explorer_revert_folder (button); } xfree (tag); Copied: trunk/src/decrypt-16.bmp (from rev 311, trunk/src/decrypt.bmp) =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-16.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Copied: trunk/src/decrypt-16m.bmp (from rev 311, trunk/src/decrypt-mask.bmp) =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-16m.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Deleted: trunk/src/decrypt-mask.bmp Copied: trunk/src/decrypt-verify-16.bmp (from rev 311, trunk/src/decrypt-verify.bmp) =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-verify-16.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Copied: trunk/src/decrypt-verify-16m.bmp (from rev 311, trunk/src/decrypt-verify-mask.bmp) =================================================================== (Binary files differ) Property changes on: trunk/src/decrypt-verify-16m.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Deleted: trunk/src/decrypt-verify-mask.bmp Deleted: trunk/src/decrypt-verify.bmp Deleted: trunk/src/decrypt.bmp Modified: trunk/src/dialogs.h =================================================================== --- trunk/src/dialogs.h 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/dialogs.h 2009-10-29 18:49:32 UTC (rev 312) @@ -7,29 +7,63 @@ #define DIALOGS_H -/* Ids used for bitmaps. - Note: FOO_MASK must have a value of FOO + 1. */ -#define IDB_ENCRYPT 3004 -#define IDB_SIGN 3006 -#define IDB_SIGN_MASK 3007 -#define IDB_ADD_KEYS 3008 -#define IDB_KEY_MANAGER 3010 -#define IDB_KEY_MANAGER_MASK 3011 -#define IDB_BANNER 3012 /* The g10 Code logo. */ -#define IDB_BANNER_HI 3014 /* Not used. */ -#define IDB_CRYPTO_STATE 3016 -#define IDB_PROTO_AUTO 3018 /* Not used. */ -#define IDB_PROTO_PGPMIME 3020 /* Not used. */ -#define IDB_PROTO_SMIME 3022 /* Not used. */ -#define IDB_PROTO_SMIME_MASK 3023 /* Not used. */ -#define IDB_DECRYPT 3024 -#define IDB_DECRYPT_MASK 3025 -#define IDB_VERIFY 3026 -#define IDB_VERIFY_MASK 3027 -#define IDB_DECRYPT_VERIFY 3028 -#define IDB_DECRYPT_VERIFY_MASK 3029 +/* Ids used for bitmaps. There is some magic in the identifiers: In + the code we only use values like 3000, the icon code then uses the + current system pixel size to the Id and tries to load this one. + The mask is always the next id. */ +#define IDB_ENCRYPT 3000 +#define IDB_ENCRYPT_16 3016 +#define IDB_ENCRYPT_16M 3017 +#define IDB_ENCRYPT_32 3032 +#define IDB_ENCRYPT_32M 3033 +#define IDB_ENCRYPT_64 3064 +#define IDB_ENCRYPT_64M 3065 +#define IDB_SIGN 3100 +#define IDB_SIGN_16 3116 +#define IDB_SIGN_16M 3117 +#define IDB_SIGN_32 3132 +#define IDB_SIGN_32M 3133 +#define IDB_SIGN_64 3164 +#define IDB_SIGN_64M 3165 +#define IDB_KEY_MANAGER 3200 +#define IDB_KEY_MANAGER_16 3216 +#define IDB_KEY_MANAGER_16M 3217 +#define IDB_KEY_MANAGER_32 3232 +#define IDB_KEY_MANAGER_32M 3233 +#define IDB_KEY_MANAGER_64 3264 +#define IDB_KEY_MANAGER_64M 3265 + +#define IDB_DECRYPT 3300 +#define IDB_DECRYPT_16 3316 +#define IDB_DECRYPT_16M 3317 +#define IDB_DECRYPT_32 3332 +#define IDB_DECRYPT_32M 3333 +#define IDB_DECRYPT_64 3364 +#define IDB_DECRYPT_64M 3365 + +#define IDB_VERIFY 3400 +#define IDB_VERIFY_16 3416 +#define IDB_VERIFY_16M 3417 +#define IDB_VERIFY_32 3432 +#define IDB_VERIFY_32M 3433 +#define IDB_VERIFY_64 3464 +#define IDB_VERIFY_64M 3465 + +#define IDB_DECRYPT_VERIFY 3500 +#define IDB_DECRYPT_VERIFY_16 3516 +#define IDB_DECRYPT_VERIFY_16M 3517 +#define IDB_DECRYPT_VERIFY_32 3532 +#define IDB_DECRYPT_VERIFY_32M 3533 +#define IDB_DECRYPT_VERIFY_64 3564 +#define IDB_DECRYPT_VERIFY_64M 3565 + + +/* Special */ +#define IDB_BANNER 3900 /* The g10 Code logo. */ + + /* Ids used for the main config dialog. */ #define IDD_GPG_OPTIONS 4001 #define IDC_TIME_PHRASES 4010 Modified: trunk/src/dialogs.rc =================================================================== --- trunk/src/dialogs.rc 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/dialogs.rc 2009-10-29 18:49:32 UTC (rev 312) @@ -22,32 +22,56 @@ #include "afxres.h" -/* To create these bitmaps, you need to use an Outlook specific - palette. A palette file for The Gimp is included as - Outlook.gpl. */ -/*IDB_DECRYPT BITMAP DISCARDABLE "decrypt.bmp"*/ -IDB_ENCRYPT BITMAP DISCARDABLE "encrypt.bmp" +IDB_ENCRYPT_16 BITMAP DISCARDABLE "encrypt-16.bmp" +IDB_ENCRYPT_16M BITMAP DISCARDABLE "encrypt-16m.bmp" +//IDB_ENCRYPT_32 BITMAP DISCARDABLE +//IDB_ENCRYPT_32M BITMAP DISCARDABLE +//IDB_ENCRYPT_64 BITMAP DISCARDABLE +//IDB_ENCRYPT_64M BITMAP DISCARDABLE + +IDB_SIGN_16 BITMAP DISCARDABLE "sign-16.bmp" +IDB_SIGN_16M BITMAP DISCARDABLE "sign-16m.bmp" +//IDB_SIGN_32 BITMAP DISCARDABLE +//IDB_SIGN_32M BITMAP DISCARDABLE +//IDB_SIGN_64 BITMAP DISCARDABLE +//IDB_SIGN_64M BITMAP DISCARDABLE + +IDB_KEY_MANAGER_16 BITMAP DISCARDABLE "key-manager-16.bmp" +IDB_KEY_MANAGER_16M BITMAP DISCARDABLE "key-manager-16m.bmp" +IDB_KEY_MANAGER_32 BITMAP DISCARDABLE "key-manager-32.bmp" +IDB_KEY_MANAGER_32M BITMAP DISCARDABLE "key-manager-32m.bmp" +//IDB_KEY_MANAGER_64 BITMAP DISCARDABLE +//IDB_KEY_MANAGER_64M BITMAP DISCARDABLE + +IDB_DECRYPT_16 BITMAP DISCARDABLE "decrypt-16.bmp" +IDB_DECRYPT_16M BITMAP DISCARDABLE "decrypt-16m.bmp" +//IDB_DECRYPT_32 BITMAP DISCARDABLE +//IDB_DECRYPT_32M BITMAP DISCARDABLE +//IDB_DECRYPT_64 BITMAP DISCARDABLE +//IDB_DECRYPT_64M BITMAP DISCARDABLE + +IDB_VERIFY_16 BITMAP DISCARDABLE "verify-16.bmp" +IDB_VERIFY_16M BITMAP DISCARDABLE "verify-16m.bmp" +//IDB_VERIFY_32 BITMAP DISCARDABLE +//IDB_VERIFY_32M BITMAP DISCARDABLE +//IDB_VERIFY_64 BITMAP DISCARDABLE +//IDB_VERIFY_64M BITMAP DISCARDABLE + +IDB_DECRYPT_VERIFY_16 BITMAP DISCARDABLE "decrypt-verify-16.bmp" +IDB_DECRYPT_VERIFY_16M BITMAP DISCARDABLE "decrypt-verify-16m.bmp" +//IDB_DECRYPT_VERIFY_32 BITMAP DISCARDABLE +//IDB_DECRYPT_VERIFY_32M BITMAP DISCARDABLE +//IDB_DECRYPT_VERIFY_64 BITMAP DISCARDABLE +//IDB_DECRYPT_VERIFY_64M BITMAP DISCARDABLE + + + + IDB_BANNER BITMAP DISCARDABLE "logo.bmp" -IDB_CRYPTO_STATE BITMAP DISCARDABLE "cryptostate.bmp" -IDB_PROTO_AUTO BITMAP DISCARDABLE "proto-auto.bmp" -IDB_PROTO_PGPMIME BITMAP DISCARDABLE "proto-pgpmime.bmp" -IDB_PROTO_SMIME BITMAP DISCARDABLE "proto-smime.bmp" -IDB_PROTO_SMIME_MASK BITMAP DISCARDABLE "proto-smime-mask.bmp" -IDB_KEY_MANAGER BITMAP DISCARDABLE "key-manager.bmp" -IDB_KEY_MANAGER_MASK BITMAP DISCARDABLE "key-manager-mask.bmp" -IDB_DECRYPT BITMAP DISCARDABLE "decrypt.bmp" -IDB_DECRYPT_MASK BITMAP DISCARDABLE "decrypt-mask.bmp" -IDB_VERIFY BITMAP DISCARDABLE "verify.bmp" -IDB_VERIFY_MASK BITMAP DISCARDABLE "verify-mask.bmp" -IDB_DECRYPT_VERIFY BITMAP DISCARDABLE "decrypt-verify.bmp" -IDB_DECRYPT_VERIFY_MASK BITMAP DISCARDABLE "decrypt-verify-mask.bmp" -IDB_SIGN BITMAP DISCARDABLE "sign.bmp" -IDB_SIGN_MASK BITMAP DISCARDABLE "sign-mask.bmp" - IDD_GPG_OPTIONS DIALOG DISCARDABLE 0, 0, 266, 274 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "GpgOL" Copied: trunk/src/encrypt-16.bmp (from rev 311, trunk/src/encrypt.bmp) =================================================================== (Binary files differ) Property changes on: trunk/src/encrypt-16.bmp ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Deleted: trunk/src/encrypt.bmp Modified: trunk/src/explorers.cpp =================================================================== --- trunk/src/explorers.cpp 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/explorers.cpp 2009-10-29 18:49:32 UTC (rev 312) @@ -29,11 +29,13 @@ #include "explorers.h" #include "dialogs.h" /* IDB_xxx */ #include "cmdbarcontrols.h" +#include "revert.h" #include "eventsink.h" BEGIN_EVENT_SINK(GpgolExplorersEvents, IOOMExplorersEvents) STDMETHOD (NewExplorer) (THIS_ LPOOMEXPLORER); +EVENT_SINK_DEFAULT_CTOR(GpgolExplorersEvents) EVENT_SINK_DEFAULT_DTOR(GpgolExplorersEvents) EVENT_SINK_INVOKE(GpgolExplorersEvents) { @@ -77,7 +79,7 @@ void add_explorer_controls (LPOOMEXPLORER explorer) { - LPDISPATCH pObj, pDisp, pTmp; + LPDISPATCH controls, button, obj; log_debug ("%s:%s: Enter", SRCNAME, __func__); @@ -86,18 +88,18 @@ called from a second thread. */ /* Check that our controls do not already exist. */ - pObj = get_oom_object (explorer, "CommandBars"); - if (!pObj) + obj = get_oom_object (explorer, "CommandBars"); + if (!obj) { log_debug ("%s:%s: CommandBars not found", SRCNAME, __func__); return; } - pDisp = get_oom_control_bytag (pObj, "GpgOL_Start_Key_Manager"); - pObj->Release (); - pObj = NULL; - if (pDisp) + button = get_oom_control_bytag (obj, "GpgOL_Start_Key_Manager"); + obj->Release (); + obj = NULL; + if (button) { - pDisp->Release (); + button->Release (); log_debug ("%s:%s: Leave (Controls are already added)", SRCNAME, __func__); return; @@ -108,57 +110,115 @@ Outlooked crashed. Quite likely my error but I was not able to find the problem. */ - /* Create the Start-Key-Manager menu entry. */ - pDisp = get_oom_object (explorer, - "CommandBars.FindControl(,30007).get_Controls"); - if (!pDisp) + /* Create the Start-Key-Manager menu entries. */ + controls = get_oom_object (explorer, + "CommandBars.FindControl(,30007).get_Controls"); + if (!controls) log_debug ("%s:%s: Menu Popup Extras not found\n", SRCNAME, __func__); else { - pTmp = add_oom_button (pDisp); - pDisp->Release (); - pDisp = pTmp; - if (pDisp) + button = add_oom_button (controls); + if (button) { - put_oom_string (pDisp, "Tag", "GpgOL_Start_Key_Manager"); - put_oom_int (pDisp, "Style", msoButtonIconAndCaption ); - put_oom_string (pDisp, "Caption", _("GnuPG Certificate &Manager")); - put_oom_string (pDisp, "TooltipText", - _("Open the certificate manager")); - put_oom_icon (pDisp, IDB_KEY_MANAGER, 16); + put_oom_string (button, "Tag", "GpgOL_Start_Key_Manager"); + put_oom_bool (button, "BeginGroup", true); + put_oom_int (button, "Style", msoButtonIconAndCaption ); + put_oom_string (button, "Caption", _("GnuPG Certificate &Manager")); + put_oom_icon (button, IDB_KEY_MANAGER, 16); - install_GpgolCommandBarButtonEvents_sink (pDisp); - pDisp->Release (); + install_GpgolCommandBarButtonEvents_sink (button); + /* Fixme: Save the returned object for an Unadvice. */ + button->Release (); } + + button = add_oom_button (controls); + if (button) + { + put_oom_string (button, "Tag", "GpgOL_Revert_Folder"); + put_oom_int (button, "Style", msoButtonCaption ); + put_oom_string (button, "Caption", + _("Remove GpgOL flags from this folder")); + + install_GpgolCommandBarButtonEvents_sink (button); + /* Fixme: Save the returned object for an Unadvice. */ + button->Release (); + } + + controls->Release (); + controls = NULL; } /* Create the Start-Key-Manager toolbar icon. Not ethat we need to use a different tag name here. If we won't do that event sink would be called twice. */ - pDisp = get_oom_object (explorer, + controls = get_oom_object (explorer, "CommandBars.Item(Standard).get_Controls"); - if (!pDisp) + if (!controls) log_debug ("%s:%s: CommandBar \"Standard\" not found\n", SRCNAME, __func__); else { - pTmp = add_oom_button (pDisp); - pDisp->Release (); - pDisp = pTmp; - if (pDisp) + button = add_oom_button (controls); + if (button) { - put_oom_string (pDisp, "Tag", "GpgOL_Start_Key_Manager at t"); - put_oom_int (pDisp, "Style", msoButtonIcon ); - put_oom_string (pDisp, "TooltipText", + put_oom_string (button, "Tag", "GpgOL_Start_Key_Manager at t"); + put_oom_int (button, "Style", msoButtonIcon ); + put_oom_string (button, "TooltipText", _("Open the certificate manager")); - put_oom_icon (pDisp, IDB_KEY_MANAGER, 16); + put_oom_icon (button, IDB_KEY_MANAGER, 16); - install_GpgolCommandBarButtonEvents_sink (pDisp); + install_GpgolCommandBarButtonEvents_sink (button); /* Fixme: store the event sink object somewhere. */ - pDisp->Release (); + button->Release (); } + controls->Release (); } log_debug ("%s:%s: Leave", SRCNAME, __func__); } + + +void +run_explorer_revert_folder (LPDISPATCH button) +{ + LPDISPATCH obj; + + log_debug ("%s:%s: Enter", SRCNAME, __func__); + + /* Notify the user that the general GpgOl function will be disabled + when calling this function. */ + if ( opt.disable_gpgol + || (MessageBox + (NULL/* FIXME: need the hwnd */, + _("You are about to start the process of reversing messages " + "created by GpgOL to prepare deinstalling of GpgOL. " + "Running this command will put GpgOL into a disabled state " + "so that messages are not anymore processed by GpgOL.\n" + "\n" + "You should convert all folders one after the other with " + "this command, close Outlook and then deinstall GpgOL.\n" + "\n" + "Note that if you start Outlook again with GpgOL still " + "being installed, GpgOL will again process messages."), + _("GpgOL"), MB_ICONWARNING|MB_OKCANCEL) == IDOK)) + { + if ( MessageBox + (NULL /* Fixme: need hwnd */, + _("Do you want to revert this folder?"), + _("GpgOL"), MB_ICONQUESTION|MB_YESNO) == IDYES ) + { + if (!opt.disable_gpgol) + opt.disable_gpgol = 1; + + obj = get_oom_object (button, + "get_Parent.get_Parent.get_Parent.get_Parent" + ".get_CurrentFolder"); + if (obj) + { + gpgol_folder_revert (obj); + obj->Release (); + } + } + } +} Modified: trunk/src/explorers.h =================================================================== --- trunk/src/explorers.h 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/explorers.h 2009-10-29 18:49:32 UTC (rev 312) @@ -86,6 +86,8 @@ void add_explorer_controls (LPOOMEXPLORER explorer); +void run_explorer_revert_folder (LPDISPATCH button); + #endif /*EXPLORERS_H*/ Modified: trunk/src/ext-commands.cpp =================================================================== --- trunk/src/ext-commands.cpp 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/ext-commands.cpp 2009-10-29 18:49:32 UTC (rev 312) @@ -38,8 +38,8 @@ #include "ol-ext-callback.h" #include "message.h" #include "engine.h" -#include "ext-commands.h" #include "revert.h" +#include "ext-commands.h" #include "explorers.h" #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \ @@ -99,17 +99,7 @@ m_pExchExt = pParentInterface; m_lRef = 0; m_lContext = 0; - m_nCmdProtoAuto = 0; - m_nCmdProtoPgpmime = 0; - m_nCmdProtoSmime = 0; - m_nCmdEncrypt = 0; - m_nCmdSign = 0; - m_nCmdRevertFolder = 0; - m_nCmdDebug0 = 0; - m_nCmdDebug1 = 0; - m_nCmdDebug2 = 0; - m_nCmdDebug3 = 0; - m_toolbar_info = NULL; + m_toolbar_info = NULL; m_hWnd = NULL; if (!bitmaps_initialized) @@ -426,30 +416,9 @@ /* Now install menu and toolbar items. */ if (m_lContext == EECONTEXT_READNOTEMESSAGE) { - add_menu (eecb, pnCommandIDBase, - "@", NULL, - (opt.enable_debug && !opt.disable_gpgol)? - "GpgOL Debug-1 (open_inspector)":"", &m_nCmdDebug1, - (opt.enable_debug && !opt.disable_gpgol)? - "GpgOL Debug-2 (change msg class)":"", &m_nCmdDebug2, - opt.enable_debug? "GpgOL Debug-3 (revert message class)":"", - &m_nCmdDebug3, - NULL); - } else if (m_lContext == EECONTEXT_SENDNOTEMESSAGE && !opt.disable_gpgol) { - add_menu (eecb, pnCommandIDBase, - "@", NULL, - _("&encrypt message with GnuPG"), &m_nCmdEncrypt, - _("&sign message with GnuPG"), &m_nCmdSign, - NULL ); - - add_toolbar (pTBEArray, nTBECnt, - "Encrypt", IDB_ENCRYPT, m_nCmdEncrypt, - "Sign", IDB_SIGN, m_nCmdSign, - NULL, 0, 0); - m_pExchExt->m_protoSelection = opt.default_protocol; if (draft_info && draft_info[0] == 'E') @@ -468,15 +437,9 @@ if (force_encrypt) m_pExchExt->m_gpgEncrypt = true; - check_menu (eecb, m_nCmdEncrypt, m_pExchExt->m_gpgEncrypt); - check_menu (eecb, m_nCmdSign, m_pExchExt->m_gpgSign); } else if (m_lContext == EECONTEXT_VIEWER) { - add_menu (eecb, pnCommandIDBase, - "@", NULL, - _("Remove GpgOL flags from this folder"), &m_nCmdRevertFolder, - NULL); } @@ -575,109 +538,6 @@ log_debug ("%s:%s: command Forward called\n", SRCNAME, __func__); return S_FALSE; /* Pass it on. */ } - else if (nCommandID == m_nCmdEncrypt - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - log_debug ("%s:%s: command Encrypt called\n", SRCNAME, __func__); - m_pExchExt->m_gpgEncrypt = !m_pExchExt->m_gpgEncrypt; - check_menu (eecb, m_nCmdEncrypt, m_pExchExt->m_gpgEncrypt); - } - else if (nCommandID == m_nCmdSign - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - log_debug ("%s:%s: command Sign called\n", SRCNAME, __func__); - m_pExchExt->m_gpgSign = !m_pExchExt->m_gpgSign; - check_menu (eecb, m_nCmdSign, m_pExchExt->m_gpgSign); - } - else if (nCommandID == m_nCmdRevertFolder - && m_lContext == EECONTEXT_VIEWER) - { - log_debug ("%s:%s: command ReverFoldert called\n", SRCNAME, __func__); - /* Notify the user that the general GpgOl fucntionaly will be - disabled when calling this function the first time. */ - if ( opt.disable_gpgol - || (MessageBox - (hwnd, - _("You are about to start the process of reversing messages " - "created by GpgOL to prepare deinstalling of GpgOL. " - "Running this command will put GpgOL into a disabled state " - "so that messages are not anymore processed by GpgOL.\n" - "\n" - "You should convert all folders one after the other with " - "this command, close Outlook and then deinstall GpgOL.\n" - "\n" - "Note that if you start Outlook again with GpgOL still " - "being installed, GpgOL will again process messages."), - _("GpgOL"), MB_ICONWARNING|MB_OKCANCEL) == IDOK)) - { - if ( MessageBox - (hwnd, - _("Do you want to revert this folder?"), - _("GpgOL"), MB_ICONQUESTION|MB_YESNO) == IDYES ) - { - if (!opt.disable_gpgol) - opt.disable_gpgol = 1; - - gpgol_folder_revert (eecb); - } - } - } - else if (opt.enable_debug && nCommandID == m_nCmdDebug0 - && m_lContext == EECONTEXT_READNOTEMESSAGE) - { - log_debug ("%s:%s: command Debug0 (showInfo) called\n", - SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - message_show_info (message, hwnd); - } - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - } - else if (opt.enable_debug && nCommandID == m_nCmdDebug1 - && m_lContext == EECONTEXT_READNOTEMESSAGE) - { - log_debug ("%s:%s: command Debug1 (open inspector) called\n", - SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - open_inspector (eecb, message); - } - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - } - else if (opt.enable_debug && nCommandID == m_nCmdDebug2 - && m_lContext == EECONTEXT_READNOTEMESSAGE) - { - log_debug ("%s:%s: command Debug2 (change message class) called\n", - SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - /* We sync here. */ - mapi_change_message_class (message, 1); - } - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - } - else if (opt.enable_debug && nCommandID == m_nCmdDebug3 - && m_lContext == EECONTEXT_READNOTEMESSAGE) - { - log_debug ("%s:%s: command Debug3 (revert_message_class) called\n", - SRCNAME, __func__); - hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); - if (SUCCEEDED (hr)) - { - int rc = gpgol_message_revert (message, 1, - KEEP_OPEN_READWRITE|FORCE_SAVE); - log_debug ("%s:%s: gpgol_message_revert returns %d\n", - SRCNAME, __func__, rc); - } - ul_release (message, __func__, __LINE__); - ul_release (mdb, __func__, __LINE__); - } else if (nCommandID == EECMDID_SaveMessage && m_lContext == EECONTEXT_SENDNOTEMESSAGE) { @@ -738,24 +598,7 @@ show_event_object (eecb, __func__); - if (nCommandID == m_nCmdEncrypt - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - MessageBox (m_hWnd, - _("Select this option to encrypt the message."), - "GpgOL", MB_OK); - } - else if (nCommandID == m_nCmdSign - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - MessageBox (m_hWnd, - _("Select this option to sign the message."), - "GpgOL", MB_OK); - } - else - return S_FALSE; - - return S_OK; + return S_FALSE; } @@ -772,30 +615,7 @@ LPTSTR pszText, UINT nCharCnt) { - if (nCommandID == m_nCmdEncrypt - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, - _("Encrypt message with GnuPG"), - nCharCnt); - } - else if (nCommandID == m_nCmdSign - && m_lContext == EECONTEXT_SENDNOTEMESSAGE) - { - if (lFlags == EECQHT_STATUS) - lstrcpyn (pszText, ".", nCharCnt); - if (lFlags == EECQHT_TOOLTIP) - lstrcpyn (pszText, - _("Sign message with GnuPG"), - nCharCnt); - } - else - return S_FALSE; - - return S_OK; + return S_FALSE; } @@ -849,19 +669,6 @@ n = description_size; lstrcpyn (description, tb_info->desc, n); - if (tb_info->cmd_id == m_nCmdEncrypt) - { - pTBB->fsStyle |= TBSTYLE_CHECK; - if (m_pExchExt->m_gpgEncrypt) - pTBB->fsState |= TBSTATE_CHECKED; - } - else if (tb_info->cmd_id == m_nCmdSign) - { - pTBB->fsStyle |= TBSTYLE_CHECK; - if (m_pExchExt->m_gpgSign) - pTBB->fsState |= TBSTATE_CHECKED; - } - return S_OK; } Modified: trunk/src/ext-commands.h =================================================================== --- trunk/src/ext-commands.h 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/ext-commands.h 2009-10-29 18:49:32 UTC (rev 312) @@ -40,17 +40,6 @@ ULONG m_lRef; ULONG m_lContext; - UINT m_nCmdProtoAuto; - UINT m_nCmdProtoPgpmime; - UINT m_nCmdProtoSmime; - UINT m_nCmdEncrypt; - UINT m_nCmdSign; - UINT m_nCmdRevertFolder; - UINT m_nCmdDebug0; - UINT m_nCmdDebug1; - UINT m_nCmdDebug2; - UINT m_nCmdDebug3; - /* A list of all active toolbar items. */ toolbar_info_t m_toolbar_info; Modified: trunk/src/inspectors.cpp =================================================================== --- trunk/src/inspectors.cpp 2009-10-28 19:26:06 UTC (rev 311) +++ trunk/src/inspectors.cpp 2009-10-29 18:49:32 UTC (rev 312) @@ -37,6 +37,7 @@ /* Event sink for an Inspectors collection object. */ BEGIN_EVENT_SINK(GpgolInspectorsEvents, IOOMInspectorsEvents) STDMETHOD (NewInspector) (THIS_ LPOOMINSPECTOR); +EVENT_SINK_DEFAULT_CTOR(GpgolInspectorsEvents) EVENT_SINK_DEFAULT_DTOR(GpgolInspectorsEvents) EVENT_SINK_INVOKE(GpgolInspectorsEvents) { @@ -67,6 +68,11 @@ STDMETHOD_ (void, Activate) (THIS_); STDMETHOD_ (void, Close) (THIS_); STDMETHOD_ (void, Deactivate) (THIS_); + bool m_first_activate_seen; +EVENT_SINK_CTOR(GpgolInspectorEvents) +{ + m_first_activate_seen = false; +} EVENT_SINK_DEFAULT_DTOR(GpgolInspectorEvents) EVENT_SINK_INVOKE(GpgolInspectorEvents) { @@ -95,6 +101,18 @@ +/* A linked list as a simple collection of button. */ +struct button_list_s +{ + struct button_list_s *next; + LPDISPATCH sink; + LPDISPATCH button; + int instid; + char tag[1]; /* Variable length string. */ +}; +typedef struct button_list_s *button_list_t; + + /* To avoid messing around with the OOM (adding extra objects as user properties and such), we keep our own information structure about inspectors. */ @@ -110,8 +128,8 @@ locate the inspector object. */ LPOOMINSPECTOREVENTS eventsink; - /* The event sink object for the crypto info button. */ - LPDISPATCH crypto_info_sink; + /* A list of all the buttons. */ + button_list_t buttons; }; typedef struct inspector_info_s *inspector_info_t; @@ -120,6 +138,11 @@ static inspector_info_t all_inspectors; static HANDLE all_inspectors_lock; + +static void update_crypto_info (LPDISPATCH button); + + + /* Initialize this module. Returns 0 on success. Called once by dllinit. */ int initialize_inspectors (void) @@ -164,6 +187,34 @@ } +/* Add SINK and BUTTON to the list at LISTADDR. The list takes + ownership of SINK and BUTTON, thus the caller may not use OBJ or + OBJ2 after this call. If TAG is given it is stored as well. */ +static void +move_to_button_list (button_list_t *listaddr, + LPDISPATCH sink, LPDISPATCH button, const char *tag) +{ + button_list_t item; + int instid; + + if (!tag) + tag = ""; + + instid = button? get_oom_int (button, "InstanceId"): 0; + + // log_debug ("%s:%s: sink=%p btn=%p tag=(%s) instid=%d", + // SRCNAME, __func__, sink, button, tag, instid); + + item = (button_list_t)xcalloc (1, sizeof *item + strlen (tag)); + item->sink = sink; + item->button = button; + item->instid = instid; + strcpy (item->tag, tag); + item->next = *listaddr; + *listaddr = item; +} + + /* Register the inspector object INSPECTOR along with its event SINK. */ static void register_inspector (LPOOMINSPECTOR inspector, LPOOMINSPECTOREVENTS sink) @@ -190,6 +241,7 @@ deregister_inspector (LPOOMINSPECTOREVENTS sink) { inspector_info_t r, rprev; + button_list_t ol, ol2; if (!sink) return; @@ -215,8 +267,17 @@ r->eventsink = NULL; if (r->inspector) r->inspector->Release (); - if (r->crypto_info_sink) - r->crypto_info_sink->Release (); + + for (ol = r->buttons; ol; ol = ol2) + { + ol2 = ol->next; + if (ol->sink) + ol->sink->Release (); + if (ol->button) + ol->button->Release (); + xfree (ol); + } + xfree (r); } @@ -242,7 +303,43 @@ } +/* Search through all objects and find the inspector which has a + button with the instanceId INSTID. The find the button with TAG in + that inspector and return it. Caller must release the returned + button. Returns NULL if not found. */ +static LPDISPATCH +get_button_by_instid_and_tag (int instid, const char *tag) +{ + LPDISPATCH result = NULL; + inspector_info_t iinfo; + button_list_t ol; + // log_debug ("%s:%s: inst=%d tag=(%s)",SRCNAME, __func__, instid, tag); + + lock_all_inspectors (); + + for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next) + for (ol = iinfo->buttons; ol; ol = ol->next) + if (ol->instid == instid) + { + /* Found the inspector. Now look for the tag. */ + for (ol = iinfo->buttons; ol; ol = ol->next) + if (ol->tag && !strcmp (ol->tag, tag)) + { + result = ol->button; + if (result) + result->AddRef (); + break; + } + break; + } + + unlock_all_inspectors (); + return result; +} + + + /* The method called by outlook for each new inspector. Note that Outlook sometimes reuses Inspectro objects thus this event is not an indication for a newly opened Inspector. */ @@ -261,7 +358,6 @@ { register_inspector (inspector, (LPOOMINSPECTOREVENTS)obj); obj->Release (); - add_inspector_controls (inspector); } inspector->Release (); return S_OK; @@ -284,6 +380,7 @@ GpgolInspectorEvents::Activate (void) { LPDISPATCH obj, button; + LPOOMINSPECTOR inspector; log_debug ("%s:%s: Called", SRCNAME, __func__); @@ -296,7 +393,18 @@ log_error ("%s:%s: Object not set", SRCNAME, __func__); return; } + inspector = (LPOOMINSPECTOR)m_object; + /* If this is the first activate for the inspector, we add the + controls. We do it only now to be sure that everything has been + initialized. Doing that in GpgolInspectorsEvents::NewInspector + is not suggested due to claims from some mailing lists. */ + if (!m_first_activate_seen) + { + m_first_activate_seen = true; + add_inspector_controls (inspector); + } + /* Update the crypt info. */ obj = get_oom_object (m_object, "CommandBars"); if (!obj) @@ -307,7 +415,7 @@ obj->Release (); if (button) { - update_inspector_crypto_info (button); + update_crypto_info (button); button->Release (); } } @@ -323,14 +431,37 @@ } +/* Check whether we are in composer or read mode. */ +static bool +is_inspector_in_composer_mode (LPDISPATCH inspector) +{ + LPDISPATCH obj; + bool in_composer; + + obj = get_oom_object (inspector, "get_CurrentItem"); + if (obj) + { + /* We are in composer mode if the "Sent" property is false and + the class is 43. */ + in_composer = (!get_oom_bool (obj, "Sent") + && get_oom_int (obj, "Class") == 43); + obj->Release (); + } + else + in_composer = false; + return in_composer; +} - +/* Add all the controls. */ void add_inspector_controls (LPOOMINSPECTOR inspector) { - LPDISPATCH pObj, pDisp, pTmp; + LPDISPATCH obj, controls, button; inspector_info_t inspinfo; + button_list_t buttonlist = NULL; + const char *tag; + int in_composer; log_debug ("%s:%s: Enter", SRCNAME, __func__); @@ -341,75 +472,206 @@ to keep a lock per inspector. */ /* Check that our controls do not already exist. */ - pObj = get_oom_object (inspector, "CommandBars"); - if (!pObj) + obj = get_oom_object (inspector, "CommandBars"); + if (!obj) { - log_debug ("%s:%s: CommandBars not found", SRCNAME, __func__); + log_error ("%s:%s: CommandBars not found", SRCNAME, __func__); return; } - pDisp = get_oom_control_bytag (pObj, "GpgOL_Inspector_Crypto_Info"); - pObj->Release (); - pObj = NULL; - if (pDisp) + button= get_oom_control_bytag (obj, "GpgOL_Inspector_Crypto_Info"); + obj->Release (); + if (button) { - pDisp->Release (); + button->Release (); log_debug ("%s:%s: Leave (Controls are already added)", SRCNAME, __func__); return; } - /* Create our controls. */ - pDisp = get_oom_object (inspector, - "CommandBars.Item(Standard).get_Controls"); - if (!pDisp) - log_debug ("%s:%s: CommandBar \"Standard\" not found\n", - SRCNAME, __func__); - else + /* Check whether we are in composer or read mode. */ + in_composer = is_inspector_in_composer_mode (inspector); + + /* Add buttons to the Format menu but only in composer mode. */ + if (in_composer) { - pTmp = add_oom_button (pDisp); - pDisp->Release (); - pDisp = pTmp; - if (pDisp) + controls = get_oom_object + (inspector, "CommandBars.FindControl(,30006).get_Controls"); + if (!controls) + log_debug ("%s:%s: Menu Popup Format not found\n", SRCNAME, __func__); + else { - put_oom_string (pDisp, "Tag", "GpgOL_Inspector_Crypto_Info"); - put_oom_int (pDisp, "Style", msoButtonIcon ); - put_oom_string (pDisp, "TooltipText", - _("Indicates the crypto status of the message")); - put_oom_icon (pDisp, IDB_SIGN, 16); - - pObj = install_GpgolCommandBarButtonEvents_sink (pDisp); - pDisp->Release (); - inspinfo = get_inspector_info (inspector); - if (inspinfo) + button = opt.disable_gpgol? NULL : add_oom_button (controls); + if (button) { - inspinfo->crypto_info_sink = pObj; - unlock_all_inspectors (); + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt")); + put_oom_bool (button, "BeginGroup", true); + put_oom_int (button, "Style", msoButtonIconAndCaption ); + put_oom_string (button, "Caption", + _("&encrypt message with GnuPG")); + put_oom_icon (button, IDB_ENCRYPT, 16); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); } - else + + button = opt.disable_gpgol? NULL : add_oom_button (controls); + if (button) { - log_error ("%s:%s: inspector not registered", SRCNAME, __func__); - pObj->Release (); /* Get rid of the sink. */ + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign")); + put_oom_int (button, "Style", msoButtonIconAndCaption ); + put_oom_string (button, "Caption", _("&sign message with GnuPG")); + put_oom_icon (button, IDB_SIGN, 16); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); } + + controls->Release (); } } + - /* FIXME: Menuswe need to add: */ - // (opt.disable_gpgol || not_a_gpgol_message)? - // "" : _("GpgOL Decrypt/Verify"), &m_nCmdCryptoState, - // opt.enable_debug? "GpgOL Debug-0 (display crypto info)":"", - // &m_nCmdDebug0, + /* Add buttons to the Extra menu. */ + controls = get_oom_object (inspector, + "CommandBars.FindControl(,30007).get_Controls"); + if (!controls) + log_debug ("%s:%s: Menu Popup Extras not found\n", SRCNAME, __func__); + else + { + button = in_composer? NULL : add_oom_button (controls); + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Verify")); + put_oom_int (button, "Style", msoButtonIconAndCaption ); + put_oom_string (button, "Caption", _("GpgOL Decrypt/Verify")); + put_oom_icon (button, IDB_DECRYPT_VERIFY, 16); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + button = opt.enable_debug? add_oom_button (controls) : NULL; + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-0")); + put_oom_int (button, "Style", msoButtonCaption ); + put_oom_string (button, "Caption", + "GpgOL Debug-0 (display crypto info)"); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + button = opt.enable_debug? add_oom_button (controls) : NULL; + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-1")); + put_oom_int (button, "Style", msoButtonCaption ); + put_oom_string (button, "Caption", + "GpgOL Debug-1 (open_inspector)"); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + + button = opt.enable_debug? add_oom_button (controls) : NULL; + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-2")); + put_oom_int (button, "Style", msoButtonCaption ); + put_oom_string (button, "Caption", + "GpgOL Debug-2 (change message class)"); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + + controls->Release (); + } + + + /* Create the toolbar buttons. */ + controls = get_oom_object (inspector, + "CommandBars.Item(Standard).get_Controls"); + if (!controls) + log_error ("%s:%s: CommandBar \"Standard\" not found\n", + SRCNAME, __func__); + else + { + button = (opt.disable_gpgol || !in_composer + ? NULL : add_oom_button (controls)); + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt at t")); + put_oom_int (button, "Style", msoButtonIcon ); + put_oom_string (button, "Caption", _("Encrypt message with GnuPG")); + put_oom_icon (button, IDB_ENCRYPT, 16); + put_oom_int (button, "State", msoButtonMixed ); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + + button = (opt.disable_gpgol || !in_composer + ? NULL : add_oom_button (controls)); + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign at t")); + put_oom_int (button, "Style", msoButtonIcon); + put_oom_string (button, "Caption", _("Sign message with GnuPG")); + put_oom_icon (button, IDB_SIGN, 16); + put_oom_int (button, "State", msoButtonDown); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + + button = in_composer? NULL : add_oom_button (controls); + if (button) + { + put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Crypto_Info")); + put_oom_int (button, "Style", msoButtonIcon); + + obj = install_GpgolCommandBarButtonEvents_sink (button); + move_to_button_list (&buttonlist, obj, button, tag); + } + + controls->Release (); + } + + + /* Save the buttonlist. */ + inspinfo = get_inspector_info (inspector); + if (inspinfo) + { + inspinfo->buttons = buttonlist; + unlock_all_inspectors (); + } + else + { + button_list_t ol, ol2; + + log_error ("%s:%s: inspector not registered", SRCNAME, __func__); + for (ol = buttonlist; ol; ol = ol2) + { + ol2 = ol->next; + if (ol->sink) + ol->sink->Release (); + if (ol->button) + ol->button->Release (); + xfree (ol); + } + } log_debug ("%s:%s: Leave", SRCNAME, __func__); } /* Update the crypto info icon. */ -void -update_inspector_crypto_info (LPDISPATCH button) +static void +update_crypto_info (LPDISPATCH button) { - LPDISPATCH obj; + LPDISPATCH inspector; char *msgcls = NULL;; const char *s; int in_composer = 0; @@ -422,13 +684,13 @@ versions via mapi_get_message_type and mapi_test_sig_status in UserProperties and use them instead of a direct lookup of the messageClass. */ - obj = get_oom_object (button, "get_Parent.get_Parent.get_CurrentItem"); - if (obj) + + inspector = get_oom_object (button, "get_Parent.get_Parent.get_CurrentItem"); + if (inspector) { - msgcls = get_oom_string (obj, "MessageClass"); - /* If "Sent" is false we are in composer mode */ - in_composer = !get_oom_bool (obj, "Sent"); - obj->Release (); + msgcls = get_oom_string (inspector, "MessageClass"); + in_composer = is_inspector_in_composer_mode (inspector); + inspector->Release (); } if (msgcls) { @@ -494,3 +756,131 @@ } } + +/* Toggle a button and return the new state. */ +static int +toggle_button (LPDISPATCH button, const char *tag, int instid) +{ + int state = get_oom_int (button, "State"); + char tag2[256]; + LPDISPATCH button2; + + log_debug ("%s:%s: button `%s' state is %d", SRCNAME, tag, __func__, state); + state = (state == msoButtonUp)? msoButtonDown : msoButtonUp; + put_oom_int (button, "State", state); + + /* Toggle the other button. */ + mem2str (tag2, tag, sizeof tag2 - 2); + if (*tag2 && tag2[1] && !strcmp (tag2+strlen(tag2)-2, "@t")) + tag2[strlen(tag2)-2] = 0; /* Remove the "@t". */ + else + strcat (tag2, "@t"); /* Append a "@t". */ + + button2 = get_button_by_instid_and_tag (instid, tag2); + if (!button2) + log_debug ("%s:%s: button `%s' not found", SRCNAME, __func__, tag2); + else + { + put_oom_int (button2, "State", state); + button2->Release (); + } + return state; +} + + +/* Called for a click on an inspector button. BUTTON is the button + object and TAG is the tag value (which is guaranteed not to be + NULL). INSTID is the instance ID of the button. */ +void +proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid) +{ + if (!tagcmp (tag, "GpgOL_Inspector_Encrypt")) + { + toggle_button (button, tag, instid); + } + else if (!tagcmp (tag, "GpgOL_Inspector_Sign")) + { + toggle_button (button, tag, instid); + } + else if (!tagcmp (tag, "GpgOL_Inspector_Verify")) + { + /* FIXME: We need to invoke decrypt/verify again. */ + } + else if (!tagcmp (tag, "GpgOL_Inspector_Crypto_Info")) + { + /* FIXME: We should invoke the decrypt/verify again. */ + update_crypto_info (button); +#if 0 /* This is the code we used to use. */ + log_debug ("%s:%s: command CryptoState called\n", SRCNAME, __func__); + hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); + if (SUCCEEDED (hr)) + { + if (message_incoming_handler (message, hwnd, true)) + message_display_handler (eecb, hwnd); + } + else + log_debug_w32 (hr, "%s:%s: command CryptoState failed", + SRCNAME, __func__); + ul_release (message, __func__, __LINE__); + ul_release (mdb, __func__, __LINE__); +#endif + } + else if (!tagcmp (tag, "GpgOL_Inspector_Debug-0")) + { + /* Show crypto info. */ + log_debug ("%s:%s: command Debug0 (showInfo) called\n", + SRCNAME, __func__); + // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); + // if (SUCCEEDED (hr)) + // { + // message_show_info (message, hwnd); + // } + // ul_release (message, __func__, __LINE__); + // ul_release (mdb, __func__, __LINE__); + } + else if (!tagcmp (tag, "GpgOL_Inspector_Debug-1")) + { + /* Open inspector. */ + log_debug ("%s:%s: command Debug1 (open inspector) called\n", + SRCNAME, __func__); + // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); + // if (SUCCEEDED (hr)) + // { + // open_inspector (eecb, message); + // } + // ul_release (message, __func__, __LINE__); + // ul_release (mdb, __func__, __LINE__); + } From cvs at cvs.gnupg.org Fri Oct 30 11:34:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 30 Oct 2009 11:34:52 +0100 Subject: [svn] GpgOL - r313 - trunk/forms Message-ID: Author: wk Date: 2009-10-30 11:34:51 +0100 (Fri, 30 Oct 2009) New Revision: 313 Modified: trunk/forms/encr-l.ico trunk/forms/encr-s.ico trunk/forms/sign-l.ico trunk/forms/sign-s.ico Log: Updated icons. Modified: trunk/forms/encr-l.ico =================================================================== (Binary files differ) Modified: trunk/forms/encr-s.ico =================================================================== (Binary files differ) Modified: trunk/forms/sign-l.ico =================================================================== (Binary files differ) Modified: trunk/forms/sign-s.ico =================================================================== (Binary files differ) From cvs at cvs.gnupg.org Fri Oct 30 15:13:22 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 30 Oct 2009 15:13:22 +0100 Subject: [svn] assuan - r312 - trunk/src Message-ID: Author: marcus Date: 2009-10-30 15:13:22 +0100 (Fri, 30 Oct 2009) New Revision: 312 Modified: trunk/src/ChangeLog trunk/src/system.c Log: 2009-10-30 Marcus Brinkmann * system.c (_assuan_spawn): Check fd_child_list before dumping it. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-20 15:50:59 UTC (rev 311) +++ trunk/src/ChangeLog 2009-10-30 14:13:22 UTC (rev 312) @@ -1,3 +1,7 @@ +2009-10-30 Marcus Brinkmann + + * system.c (_assuan_spawn): Check fd_child_list before dumping it. + 2009-10-20 Marcus Brinkmann * assuan.h (__assuan_usleep): Add declaration. Modified: trunk/src/system.c =================================================================== --- trunk/src/system.c 2009-10-20 15:50:59 UTC (rev 311) +++ trunk/src/system.c 2009-10-30 14:13:22 UTC (rev 312) @@ -783,10 +783,13 @@ } } i = 0; - while (fd_child_list[i] != ASSUAN_INVALID_FD) + if (fd_child_list) { - TRACE_LOG2 ("fd_child_list[%2i] = 0x%x", i, fd_child_list[i]); - i++; + while (fd_child_list[i] != ASSUAN_INVALID_FD) + { + TRACE_LOG2 ("fd_child_list[%2i] = 0x%x", i, fd_child_list[i]); + i++; + } } res = (ctx->system.spawn) (ctx, r_pid, name, argv, fd_in, fd_out, From cvs at cvs.gnupg.org Fri Oct 30 15:13:42 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 30 Oct 2009 15:13:42 +0100 Subject: [svn] gpgme - r1409 - trunk Message-ID: Author: marcus Date: 2009-10-30 15:13:42 +0100 (Fri, 30 Oct 2009) New Revision: 1409 Modified: trunk/TODO Log: Some additions. Modified: trunk/TODO =================================================================== --- trunk/TODO 2009-10-28 16:39:19 UTC (rev 1408) +++ trunk/TODO 2009-10-30 14:13:42 UTC (rev 1409) @@ -14,6 +14,7 @@ and parse SUBPACKET status lines. * ABI's to break: +** Old opassuan interface. ** Implementation: Remove support for old style error codes in conversion.c::_gpgme_map_gnupg_error. ** gpgme_edit_cb_t: Add "processed" return argument @@ -104,7 +105,8 @@ about where to guarantee what (ie, what happens if start fails, are the fds unregistered immediately - i think so?) Note that we need support in gpgsm to set include-certs to default - as RESET does not reset it. + as RESET does not reset it, also for no_encrypt_to and probably + other options. ** Optimize the case where a data object has an underlying fd we can pass directly to the engine. This will be automatic with socket I/O and descriptor passing. From cvs at cvs.gnupg.org Fri Oct 30 15:21:08 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 30 Oct 2009 15:21:08 +0100 Subject: [svn] gpgme - r1410 - in trunk: . src Message-ID: Author: marcus Date: 2009-10-30 15:21:08 +0100 (Fri, 30 Oct 2009) New Revision: 1410 Added: trunk/src/gpgme-tool.c Modified: trunk/ChangeLog trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/assuan-support.c trunk/src/conversion.c trunk/src/debug.h trunk/src/engine-assuan.c trunk/src/engine-g13.c trunk/src/g13.c trunk/src/gpgme.c trunk/src/ops.h trunk/src/signers.c trunk/src/version.c Log: 2009-10-30 Marcus Brinkmann * configure.ac: Check for argp.h and error_t. src/ 2009-10-30 Marcus Brinkmann * Makefile.am (noinst_PROGRAMS): New target gpgme-tool. (gpgme_tool_LDADD): New variable. * gpgme-tool.c: New file. * ops.h (_gpgme_sig_notation_clearm _gpgme_signers_clear): New prototypes. * gpgme.c (gpgme_set_protocol): Allow GPGME_PROTOCOL_GPGCONF (when had that gone missing?). (_gpgme_sig_notation_clear): New function without debug output. (gpgme_release): Call it and _gpgme_signers_clear. * signers.c (_gpgme_signers_clear): New function without debug output. * g13.c (gpgme_op_vfs_mount): Add debug output. * assuan-support.c (my_spawn): Allow fd_child_list to be NULL. * conversion.c (_gpgme_encode_percent_string): Fix infinite loop. * debug.h: Put tag in front of debug lines, should make for nicer output. * engine-assuan.c (llass_new): Use our new system hooks for libassuan. * engine-g13.c (g13_new): Remove redundant assuan context allocation. * version.c (gpgme_check_version_internal): Delay debug output until after gpgme_check_version was called. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/ChangeLog 2009-10-30 14:21:08 UTC (rev 1410) @@ -1,3 +1,7 @@ +2009-10-30 Marcus Brinkmann + + * configure.ac: Check for argp.h and error_t. + 2009-10-26 Marcus Brinkmann * configure.ac (NEED_GPG_VERSION_DEFAULT): Bump to 1.4.0 as 1.3.0 Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/ChangeLog 2009-10-30 14:21:08 UTC (rev 1410) @@ -1,3 +1,25 @@ +2009-10-30 Marcus Brinkmann + + * Makefile.am (noinst_PROGRAMS): New target gpgme-tool. + (gpgme_tool_LDADD): New variable. + * gpgme-tool.c: New file. + * ops.h (_gpgme_sig_notation_clearm _gpgme_signers_clear): New + prototypes. + * gpgme.c (gpgme_set_protocol): Allow GPGME_PROTOCOL_GPGCONF (when + had that gone missing?). + (_gpgme_sig_notation_clear): New function without debug output. + (gpgme_release): Call it and _gpgme_signers_clear. + * signers.c (_gpgme_signers_clear): New function without debug output. + * g13.c (gpgme_op_vfs_mount): Add debug output. + * assuan-support.c (my_spawn): Allow fd_child_list to be NULL. + * conversion.c (_gpgme_encode_percent_string): Fix infinite loop. + * debug.h: Put tag in front of debug lines, should make for nicer + output. + * engine-assuan.c (llass_new): Use our new system hooks for libassuan. + * engine-g13.c (g13_new): Remove redundant assuan context allocation. + * version.c (gpgme_check_version_internal): Delay debug output + until after gpgme_check_version was called. + 2009-10-28 Marcus Brinkmann * signers.c, encrypt-sign.c, encrypt.c, delete.c, keylist.c, Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/configure.ac 2009-10-30 14:21:08 UTC (rev 1410) @@ -850,6 +850,14 @@ sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'` AC_SUBST(LTLIBOBJS) +# Some checks for gpgme-tool +AC_CHECK_HEADER([argp.h]) +AC_CHECK_TYPES([error_t], [], + [AC_DEFINE([error_t], [int], + [Define to a type to use for `error_t' if it is not otherwise available.])], + [#include ]) + + # Last check. die=no if test "$require_libassuan" = "no"; then Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/Makefile.am 2009-10-30 14:21:08 UTC (rev 1410) @@ -153,7 +153,6 @@ # wrapper process. libexec_PROGRAMS = gpgme-w32spawn - LTRCCOMPILE = $(LIBTOOL) --mode=compile $(RC) \ `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ sed -e 's/-I/--include-dir /g;s/-D/--define /g'` @@ -226,6 +225,9 @@ @GPG_ERROR_LIBS@ @QT4_CORE_LIBS@ endif +noinst_PROGRAMS = gpgme-tool +gpgme_tool_LDADD = libgpgme.la + status-table.h : gpgme.h $(srcdir)/mkstatus < $(builddir)/gpgme.h > status-table.h Modified: trunk/src/assuan-support.c =================================================================== --- trunk/src/assuan-support.c 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/assuan-support.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -117,19 +117,25 @@ return gpg_error (GPG_ERR_NOT_IMPLEMENTED); i = 0; - while (fd_child_list[i] != ASSUAN_INVALID_FD) - i++; + if (fd_child_list) + { + while (fd_child_list[i] != ASSUAN_INVALID_FD) + i++; + } /* fd_in, fd_out, terminator */ i += 3; fd_items = malloc (sizeof (struct spawn_fd_item_s) * i); if (! fd_items) return gpg_error_from_syserror (); i = 0; - while (fd_child_list[i] != ASSUAN_INVALID_FD) + if (fd_child_list) { - fd_items[i].fd = fd_child_list[i]; - fd_items[i].dup_to = -1; - i++; + while (fd_child_list[i] != ASSUAN_INVALID_FD) + { + fd_items[i].fd = fd_child_list[i]; + fd_items[i].dup_to = -1; + i++; + } } if (fd_in != ASSUAN_INVALID_FD) { @@ -151,10 +157,13 @@ { i = 0; - while (fd_child_list[i] != ASSUAN_INVALID_FD) + if (fd_child_list) { - fd_child_list[i] = fd_items[i].peer_name; - i++; + while (fd_child_list[i] != ASSUAN_INVALID_FD) + { + fd_child_list[i] = fd_items[i].peer_name; + i++; + } } } free (fd_items); Modified: trunk/src/conversion.c =================================================================== --- trunk/src/conversion.c 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/conversion.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -272,6 +272,7 @@ destlen += 3; else destlen++; + str++; } /* Terminating nul byte. */ destlen++; Modified: trunk/src/debug.h =================================================================== --- trunk/src/debug.h 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/debug.h 2009-10-30 14:21:08 UTC (rev 1410) @@ -89,155 +89,155 @@ #define TRACE_BEG(lvl, name, tag) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func), 0 #define TRACE_BEG0(lvl, name, tag, fmt) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func), 0 #define TRACE_BEG1(lvl, name, tag, fmt, arg1) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1), 0 #define TRACE_BEG2(lvl, name, tag, fmt, arg1, arg2) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2), 0 #define TRACE_BEG3(lvl, name, tag, fmt, arg1, arg2, arg3) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3), 0 #define TRACE_BEG4(lvl, name, tag, fmt, arg1, arg2, arg3, arg4) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4), 0 #define TRACE_BEG5(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5), 0 #define TRACE_BEG7(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \ arg5, arg6, arg7) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5, \ + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5, \ arg6, arg7), 0 #define TRACE_BEG8(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, \ arg5, arg6, arg7, arg8) \ _TRACE (lvl, name, tag); \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): enter: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5, \ + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: enter: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5, \ arg6, arg7, arg8), 0 #define TRACE(lvl, name, tag) \ - _gpgme_debug (lvl, "%s (%s=%p): call\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag), 0 + _gpgme_debug (lvl, "[%s=%p] %s: call\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name), 0 #define TRACE0(lvl, name, tag, fmt) \ - _gpgme_debug (lvl, "%s (%s=%p): call: " fmt "\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag), 0 + _gpgme_debug (lvl, "[%s=%p] %s: call: " fmt "\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name), 0 #define TRACE1(lvl, name, tag, fmt, arg1) \ - _gpgme_debug (lvl, "%s (%s=%p): call: " fmt "\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1), 0 + _gpgme_debug (lvl, "[%s=%p] %s: call: " fmt "\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name, arg1), 0 #define TRACE2(lvl, name, tag, fmt, arg1, arg2) \ - _gpgme_debug (lvl, "%s (%s=%p): call: " fmt "\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \ + _gpgme_debug (lvl, "[%s=%p] %s: call: " fmt "\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name, arg1, \ arg2), 0 #define TRACE3(lvl, name, tag, fmt, arg1, arg2, arg3) \ - _gpgme_debug (lvl, "%s (%s=%p): call: " fmt "\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \ + _gpgme_debug (lvl, "[%s=%p] %s: call: " fmt "\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name, arg1, \ arg2, arg3), 0 #define TRACE6(lvl, name, tag, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \ - _gpgme_debug (lvl, "%s (%s=%p): call: " fmt "\n", \ - name, STRINGIFY (tag), (void *) (uintptr_t) tag, arg1, \ + _gpgme_debug (lvl, "[%s=%p] %s: call: " fmt "\n", \ + STRINGIFY (tag), (void *) (uintptr_t) tag, name, arg1, \ arg2, arg3, arg4, arg5, arg6), 0 #define TRACE_ERR(err) \ err == 0 ? (TRACE_SUC ()) : \ - (_gpgme_debug (_gpgme_trace_level, "%s (%s=%p): error: %s <%s>\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, gpgme_strerror (err), \ + (_gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: error: %s <%s>\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, gpgme_strerror (err), \ gpgme_strsource (err)), (err)) /* The cast to void suppresses GCC warnings. */ #define TRACE_SYSRES(res) \ res >= 0 ? ((void) (TRACE_SUC1 ("result=%i", res)), (res)) : \ - (_gpgme_debug (_gpgme_trace_level, "%s (%s=%p): error: %s\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, strerror (errno)), (res)) + (_gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: error: %s\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, strerror (errno)), (res)) #define TRACE_SYSERR(res) \ res == 0 ? ((void) (TRACE_SUC1 ("result=%i", res)), (res)) : \ - (_gpgme_debug (_gpgme_trace_level, "%s (%s=%p): error: %s\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, strerror (res)), (res)) + (_gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: error: %s\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, strerror (res)), (res)) #define TRACE_SUC() \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): leave\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: leave\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func), 0 #define TRACE_SUC0(fmt) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): leave: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: leave: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func), 0 #define TRACE_SUC1(fmt, arg1) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): leave: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: leave: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1), 0 #define TRACE_SUC2(fmt, arg1, arg2) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): leave: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: leave: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2), 0 #define TRACE_SUC5(fmt, arg1, arg2, arg3, arg4, arg5) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): leave: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: leave: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5), 0 #define TRACE_LOG(fmt) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func), 0 #define TRACE_LOG1(fmt, arg1) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1), 0 #define TRACE_LOG2(fmt, arg1, arg2) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2), 0 #define TRACE_LOG3(fmt, arg1, arg2, arg3) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3), 0 #define TRACE_LOG4(fmt, arg1, arg2, arg3, arg4) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4), 0 #define TRACE_LOG5(fmt, arg1, arg2, arg3, arg4, arg5) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5), 0 + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5), 0 #define TRACE_LOG6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \ - _gpgme_debug (_gpgme_trace_level, "%s (%s=%p): check: " fmt "\n", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, arg1, arg2, arg3, arg4, arg5, \ + _gpgme_debug (_gpgme_trace_level, "[%s=%p] %s: check: " fmt "\n", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, arg1, arg2, arg3, arg4, arg5, \ arg6), 0 #define TRACE_LOGBUF(buf, len) \ - _gpgme_debug_buffer (_gpgme_trace_level, "%s (%s=%p): check: %s", \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag, buf, len) + _gpgme_debug_buffer (_gpgme_trace_level, "[%s=%p] %s: check: %s", \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func, buf, len) #define TRACE_SEQ(hlp,fmt) \ _gpgme_debug_begin (&(hlp), _gpgme_trace_level, \ - "%s (%s=%p): check: " fmt, \ - _gpgme_trace_func, _gpgme_trace_tagname, \ - _gpgme_trace_tag) + "[%s=%p] %s: check: " fmt, \ + _gpgme_trace_tagname, _gpgme_trace_tag, \ + _gpgme_trace_func) #define TRACE_ADD0(hlp,fmt) \ _gpgme_debug_add (&(hlp), fmt) #define TRACE_ADD1(hlp,fmt,a) \ Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/engine-assuan.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -233,9 +233,13 @@ llass->opt.gpg_agent = 1; } - err = assuan_new (&llass->assuan_ctx); + err = assuan_new_ext (&llass->assuan_ctx, GPG_ERR_SOURCE_GPGME, + &_gpgme_assuan_malloc_hooks, _gpgme_assuan_log_cb, + NULL); if (err) goto leave; + assuan_ctx_set_system_hooks (llass->assuan_ctx, &_gpgme_assuan_system_hooks); + err = assuan_socket_connect (llass->assuan_ctx, file_name, 0); if (err) goto leave; Modified: trunk/src/engine-g13.c =================================================================== --- trunk/src/engine-g13.c 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/engine-g13.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -230,10 +230,6 @@ g13->status_cb.tag = 0; g13->status_cb.data = g13; - err = assuan_new (&g13->assuan_ctx); - if (err) - goto leave; - argc = 0; argv[argc++] = "g13"; if (home_dir) Modified: trunk/src/g13.c =================================================================== --- trunk/src/g13.c 2009-10-30 14:13:42 UTC (rev 1409) +++ trunk/src/g13.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -25,6 +25,7 @@ #include #include "gpgme.h" +#include "debug.h" #include "context.h" #include "ops.h" #include "util.h" @@ -135,9 +136,9 @@ or destroyed. This is a synchronous convenience interface, which automatically returns an operation error if there is no transmission error. */ -gpgme_error_t -gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, - const char *mount_dir, int flags, gpgme_error_t *op_err) +static gpgme_error_t +_gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, + const char *mount_dir, int flags, gpgme_error_t *op_err) { gpg_error_t err; char *cmd; @@ -194,3 +195,15 @@ return err; } + +gpgme_error_t +gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file, + const char *mount_dir, int flags, gpgme_error_t *op_err) +{ + TRACE_BEG4 (DEBUG_CTX, "gpgme_op_vfs_mount", ctx, + "container=%s, mount_dir=%s, flags=0x%x, op_err=%p", + container_file, mount_dir, flags, op_err); + return TRACE_ERR (_gpgme_op_vfs_mount (ctx, container_file, mount_dir, + flags, op_err)); +} + Added: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c (rev 0) +++ trunk/src/gpgme-tool.c 2009-10-30 14:21:08 UTC (rev 1410) @@ -0,0 +1,2012 @@ +/* gpgme-tool.c - GnuPG Made Easy. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 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 Lesser General Public License as + published by the Free Software Foundation; either version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser 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. */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ARGP_H +#include +#endif + +#include "gpgme.h" + + +#ifndef HAVE_ARGP_H +/* Minimal argp implementation. */ + +/* Differences to ARGP: + argp_program_version: Required. + argp_program_bug_address: Required. + argp_program_version_hook: Not supported. + argp_err_exit_status: Required. + struct argp: Children and help_filter not supported. + argp_domain: Not supported. + struct argp_option: Group not supported. Options are printed in + order given. Flags OPTION_ALIAS, OPTION_DOC and OPTION_NO_USAGE + are not supported. + argp_parse: No flags are supported (ARGP_PARSE_ARGV0, ARGP_NO_ERRS, + ARGP_NO_ARGS, ARGP_IN_ORDER, ARGP_NO_HELP, ARGP_NO_EXIT, + ARGP_LONG_ONLY, ARGP_SILENT). ARGP must not be NULL. + argp_help: Flag ARGP_HELP_LONG_ONLY not supported. + argp_state: argc, argv, next may not be modified and should not be used. */ + +extern const char *argp_program_version; +extern const char *argp_program_bug_address; +extern error_t argp_err_exit_status; + +struct argp_option +{ + const char *name; + int key; + const char *arg; +#define OPTION_ARG_OPTIONAL 0x1 +#define OPTION_HIDDEN 0x2 + int flags; + const char *doc; + int group; +}; + +struct argp; +struct argp_state +{ + const struct argp *const root_argp; + int argc; + char **argv; + int next; + unsigned flags; + unsigned arg_num; + int quoted; + void *input; + void **child_inputs; + void *hook; + char *name; + FILE *err_stream; + FILE *out_stream; + void *pstate; +}; + +#define ARGP_ERR_UNKNOWN E2BIG +#define ARGP_KEY_ARG 0 +#define ARGP_KEY_ARGS 0x1000006 +#define ARGP_KEY_END 0x1000001 +#define ARGP_KEY_NO_ARGS 0x1000002 +#define ARGP_KEY_INIT 0x1000003 +#define ARGP_KEY_FINI 0x1000007 +#define ARGP_KEY_SUCCESS 0x1000004 +#define ARGP_KEY_ERROR 0x1000005 +typedef error_t (*argp_parser_t) (int key, char *arg, struct argp_state *state); + +struct argp +{ + const struct argp_option *options; + argp_parser_t parser; + const char *args_doc; + const char *doc; + + const struct argp_child *children; + char *(*help_filter) (int key, const char *text, void *input); + const char *argp_domain; +}; + +#define ARGP_HELP_USAGE ARGP_HELP_SHORT_USAGE +#define ARGP_HELP_SHORT_USAGE 0x02 +#define ARGP_HELP_SEE 0x04 +#define ARGP_HELP_LONG 0x08 +#define ARGP_HELP_PRE_DOC 0x10 +#define ARGP_HELP_POST_DOC 0x20 +#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) +#define ARGP_HELP_BUG_ADDR 0x40 +#define ARGP_HELP_EXIT_ERR 0x100 +#define ARGP_HELP_EXIT_OK 0x200 +#define ARGP_HELP_STD_ERR (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +#define ARGP_HELP_STD_USAGE \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +#define ARGP_HELP_STD_HELP \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ + | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) + + +char * +_argp_pname (char *name) +{ + char *pname = name; + char *bname = strrchr (pname, '/'); + if (! bname) + bname = strrchr (pname, '\\'); + if (bname) + pname = bname + 1; + return pname; +} + + +void +_argp_state_help (const struct argp *argp, const struct argp_state *state, + FILE *stream, unsigned flags, char *name) +{ + if (state) + name = state->name; + + if (flags & ARGP_HELP_SHORT_USAGE) + fprintf (stream, "Usage: %s [OPTIONS...] %s\n", name, argp->args_doc); + if (flags & ARGP_HELP_SEE) + fprintf (stream, "Try `%s --help' or `%s --usage' for more information.\n", + name, name); + if (flags & ARGP_HELP_PRE_DOC) + { + char buf[1024]; + char *end; + strncpy (buf, argp->doc, sizeof (buf)); + buf[sizeof (buf) - 1] = '\0'; + end = strchr (buf, '\v'); + if (end) + *end = '\0'; + fprintf (stream, "%s\n%s", buf, buf[0] ? "\n" : ""); + } + if (flags & ARGP_HELP_LONG) + { + const struct argp_option *opt = argp->options; + while (opt->key) + { + #define NSPACES 29 + char spaces[NSPACES + 1] = " "; + int len = 0; + fprintf (stream, " "); + len += 2; + if (isascii (opt->key)) + { + fprintf (stream, "-%c", opt->key); + len += 2; + if (opt->name) + { + fprintf (stream, ", "); + len += 2; + } + } + if (opt->name) + { + fprintf (stream, "--%s", opt->name); + len += 2 + strlen (opt->name); + } + if (opt->arg && (opt->flags & OPTION_ARG_OPTIONAL)) + { + fprintf (stream, "[=%s]", opt->arg); + len += 3 + strlen (opt->arg); + } + else if (opt->arg) + { + fprintf (stream, "=%s", opt->arg); + len += 1 + strlen (opt->arg); + } + if (len >= NSPACES) + len = NSPACES - 1; + spaces[NSPACES - len] = '\0'; + fprintf (stream, "%s%s\n", spaces, opt->doc); + opt++; + } + fprintf (stream, " -?, --help Give this help list\n"); + fprintf (stream, " --usage Give a short usage " + "message\n"); + } + if (flags & ARGP_HELP_POST_DOC) + { + char buf[1024]; + char *end; + strncpy (buf, argp->doc, sizeof (buf)); + buf[sizeof (buf) - 1] = '\0'; + end = strchr (buf, '\v'); + if (end) + { + end++; + if (*end) + fprintf (stream, "\n%s\n", end); + } + fprintf (stream, "\nMandatory or optional arguments to long options are also mandatory or optional\n"); + fprintf (stream, "for any corresponding short options.\n"); + } + if (flags & ARGP_HELP_BUG_ADDR) + fprintf (stream, "\nReport bugs to %s.\n", argp_program_bug_address); + + if (flags & ARGP_HELP_EXIT_ERR) + exit (argp_err_exit_status); + if (flags & ARGP_HELP_EXIT_OK) + exit (0); +} + + +void +argp_usage (const struct argp_state *state) +{ + _argp_state_help (state->root_argp, state, state->err_stream, + ARGP_HELP_STD_USAGE, state->name); +} + + +void +argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) +{ + _argp_state_help (state->root_argp, state, stream, flags, state->name); +} + + +void +argp_error (const struct argp_state *state, const char *fmt, ...) +{ + va_list ap; + + fprintf (state->err_stream, "%s: ", state->name); + va_start (ap, fmt); + vfprintf (state->err_stream, fmt, ap); + va_end (ap); + fprintf (state->err_stream, "\n"); + argp_state_help (state, state->err_stream, ARGP_HELP_STD_ERR); + exit (argp_err_exit_status); +} + + +void +argp_help (const struct argp *argp, FILE *stream, unsigned flags, char *name) +{ + _argp_state_help (argp, NULL, stream, flags, name); +} + + +error_t +argp_parse (const struct argp *argp, int argc, + char **argv, unsigned flags, int *arg_index, void *input) +{ + int rc = 0; + struct argp_state state = { argp, argc, argv, 1, flags, 0, 0, input, + NULL, NULL, _argp_pname (argv[0]), + stderr, stdout, NULL }; + /* All non-option arguments are collected at the beginning of + &argv[1] during processing. This is a counter for their number. */ + int non_opt_args = 0; + + rc = argp->parser (ARGP_KEY_INIT, NULL, &state); + if (rc && rc != ARGP_ERR_UNKNOWN) + goto argperror; + + while (state.next < state.argc - non_opt_args) + { + int idx = state.next; + state.next++; + + if (! strcasecmp (state.argv[idx], "--")) + { + state.quoted = idx; + continue; + } + + if (state.quoted || state.argv[idx][0] != '-') + { + char *arg_saved = state.argv[idx]; + non_opt_args++; + memmove (&state.argv[idx], &state.argv[idx + 1], + (state.argc - 1 - idx) * sizeof (char *)); + state.argv[argc - 1] = arg_saved; + state.next--; + } + else if (! strcasecmp (state.argv[idx], "--help") + || !strcmp (state.argv[idx], "-?")) + { + argp_state_help (&state, state.out_stream, ARGP_HELP_STD_HELP); + } + else if (! strcasecmp (state.argv[idx], "--usage")) + { + argp_state_help (&state, state.out_stream, + ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); + } + else if (! strcasecmp (state.argv[idx], "--version") + || !strcmp (state.argv[idx], "-V")) + { + fprintf (state.out_stream, "%s\n", argp_program_version); + exit (0); + } + else + { + /* Search for option and call parser with its KEY. */ + int key = ARGP_KEY_ARG; /* Just some dummy value. */ + const struct argp_option *opt = argp->options; + char *arg = NULL; + int found = 0; + + /* Check for --opt=value syntax. */ + arg = strchr (state.argv[idx], '='); + if (arg) + { + *arg = '\0'; + arg++; + } + + if (state.argv[idx][1] != '-') + key = state.argv[idx][1]; + + while (! found && opt->key) + { + if (key == opt->key + || (key == ARGP_KEY_ARG + && ! strcasecmp (&state.argv[idx][2], opt->name))) + { + if (arg && !opt->arg) + argp_error (&state, "Option %s does not take an argument", + state.argv[idx]); + if (opt->arg && state.next < state.argc + && state.argv[idx + 1][0] != '-') + { + arg = state.argv[idx + 1]; + state.next++; + } + if (opt->arg && !(opt->flags & OPTION_ARG_OPTIONAL)) + argp_error (&state, "Option %s requires an argument", + state.argv[idx]); + + rc = argp->parser (opt->key, arg, &state); + if (rc == ARGP_ERR_UNKNOWN) + break; + else if (rc) + goto argperror; + found = 1; + } + opt++; + } + if (! found) + argp_error (&state, "Unknown option %s", state.argv[idx]); + } + } + + while (state.next < state.argc) + { + /* Call parser for all non-option args. */ + int idx = state.next; + state.next++; + rc = argp->parser (ARGP_KEY_ARG, state.argv[idx], &state); + if (rc && rc != ARGP_ERR_UNKNOWN) + goto argperror; + if (rc == ARGP_ERR_UNKNOWN) + { + int old_next = state.next; + rc = argp->parser (ARGP_KEY_ARGS, NULL, &state); + if (rc == ARGP_ERR_UNKNOWN) + { + argp_error (&state, "Too many arguments", state.argv[idx]); + goto argperror; + } + if (! rc && state.next == old_next) + { + state.arg_num += state.argc - state.next; + state.next = state.argc; + } + } + else + state.arg_num++; + } + + if (state.arg_num == 0) + { + rc = argp->parser (ARGP_KEY_NO_ARGS, NULL, &state); + if (rc && rc != ARGP_ERR_UNKNOWN) + goto argperror; + } + if (state.next == state.argc) + { + rc = argp->parser (ARGP_KEY_END, NULL, &state); + if (rc && rc != ARGP_ERR_UNKNOWN) + goto argperror; + } + rc = argp->parser (ARGP_KEY_FINI, NULL, &state); + if (rc && rc != ARGP_ERR_UNKNOWN) + goto argperror; + + rc = 0; + argp->parser (ARGP_KEY_SUCCESS, NULL, &state); + + argperror: + if (rc) + { + argp_error (&state, "unexpected error: %s", strerror (rc)); + argp->parser (ARGP_KEY_ERROR, NULL, &state); + } + + argp->parser (ARGP_KEY_FINI, NULL, &state); + + if (arg_index) + *arg_index = state.next - 1; + + return 0; +} +#endif + + +/* SUPPORT. */ +FILE *log_stream; +char *program_name = "gpgme-tool"; + +void +log_init (void) +{ + log_stream = stderr; +} + + +void +log_error (int status, gpg_error_t errnum, const char *fmt, ...) +{ + va_list ap; + + fprintf (log_stream, "%s: ", program_name); + va_start (ap, fmt); + vfprintf (log_stream, fmt, ap); + va_end (ap); + if (errnum) + fprintf (log_stream, ": %s <%s>", gpg_strerror (errnum), + gpg_strsource (errnum)); + fprintf (log_stream, "\n"); + if (status) + exit (status); +} + + + +typedef enum status + { + STATUS_PROTOCOL, + STATUS_PROGRESS, + STATUS_ENGINE, + STATUS_ARMOR, + STATUS_TEXTMODE, + STATUS_INCLUDE_CERTS, + STATUS_KEYLIST_MODE, + STATUS_ENCRYPT_RESULT + } status_t; + +const char *status_string[] = + { + "PROTOCOL", + "PROGRESS", + "ENGINE", + "ARMOR", + "TEXTMODE", + "INCLUDE_CERTS", + "KEYLIST_MODE", + "ENCRYPT_RESULT" + }; + +struct gpgme_tool +{ + gpgme_ctx_t ctx; +#define MAX_RECIPIENTS 10 + gpgme_key_t recipients[MAX_RECIPIENTS + 1]; + int recipients_nr; + + gpg_error_t (*write_status) (void *hook, const char *status, const char *msg); + void *write_status_hook; +}; +typedef struct gpgme_tool *gpgme_tool_t; + + +/* Forward declaration. */ +void gt_write_status (gpgme_tool_t gt, status_t status, ...); + +void +_gt_progress_cb (void *opaque, const char *what, + int type, int current, int total) +{ + gpgme_tool_t gt = opaque; + char buf[100]; + + snprintf (buf, sizeof (buf), "0x%02x %i %i", type, current, total); + gt_write_status (gt, STATUS_PROGRESS, what, buf); +} + + +gpg_error_t +_gt_gpgme_new (gpgme_tool_t gt, gpgme_ctx_t *ctx) +{ + gpg_error_t err; + + err = gpgme_new (ctx); + if (err) + return err; + gpgme_set_progress_cb (*ctx, _gt_progress_cb, gt); + return 0; +} + + +void +gt_init (gpgme_tool_t gt) +{ + memset (gt, '\0', sizeof (*gt)); + gpg_error_t err; + + err = _gt_gpgme_new (gt, >->ctx); + if (err) + log_error (1, err, "can't create gpgme context"); +} + + +gpg_error_t +gt_signers_add (gpgme_tool_t gt, const char *fpr) +{ + gpg_error_t err; + gpgme_key_t key; + + err = gpgme_get_key (gt->ctx, fpr, &key, 0); + if (err) + return err; + + return gpgme_signers_add (gt->ctx, key); +} + + +gpg_error_t +gt_signers_clear (gpgme_tool_t gt) +{ + gpgme_signers_clear (gt->ctx); + return 0; +} + + +gpg_error_t +gt_recipients_add (gpgme_tool_t gt, const char *fpr) +{ + gpg_error_t err; + gpgme_key_t key; + + if (gt->recipients_nr >= MAX_RECIPIENTS) + return gpg_error_from_errno (ENOMEM); + + err = gpgme_get_key (gt->ctx, fpr, &key, 0); + if (err) + return err; + + gt->recipients[gt->recipients_nr++] = key; + return 0; +} + + +void +gt_recipients_clear (gpgme_tool_t gt) +{ + int idx; + + for (idx = 0; idx < gt->recipients_nr; idx++) + gpgme_key_unref (gt->recipients[idx]); + memset (gt->recipients, '\0', gt->recipients_nr * sizeof (gpgme_key_t)); + gt->recipients_nr = 0; +} + + +gpg_error_t +gt_reset (gpgme_tool_t gt) +{ + gpg_error_t err; + gpgme_ctx_t ctx; + + err = _gt_gpgme_new (gt, &ctx); + if (err) + return err; + + gpgme_release (gt->ctx); + gt->ctx = ctx; + gt_recipients_clear (gt); + return 0; +} + + +void +gt_write_status (gpgme_tool_t gt, status_t status, ...) +{ + va_list ap; + const char *text; + char buf[950]; + char *p; + size_t n; + gpg_error_t err; + + va_start (ap, status); + p = buf; + n = 0; + while ((text = va_arg (ap, const char *))) + { + if (n) + { + *p++ = ' '; + n++; + } + while (*text && n < sizeof (buf) - 2) + { + *p++ = *text++; + n++; + } + } + *p = 0; + va_end (ap); + + err = gt->write_status (gt->write_status_hook, status_string[status], buf); + if (err) + log_error (1, err, "can't write status line"); +} + + +gpg_error_t +gt_get_engine_info (gpgme_tool_t gt, gpgme_protocol_t proto) +{ + gpgme_engine_info_t info; + info = gpgme_ctx_get_engine_info (gt->ctx); + while (info) + { + if (proto == GPGME_PROTOCOL_UNKNOWN || proto == info->protocol) + gt_write_status (gt, STATUS_ENGINE, + gpgme_get_protocol_name (info->protocol), + info->file_name, info->version, + info->req_version, info->home_dir); + info = info->next; + } + return 0; +} + + +gpgme_protocol_t +gt_protocol_from_name (const char *name) +{ + if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_OpenPGP))) + return GPGME_PROTOCOL_OpenPGP; + if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_CMS))) + return GPGME_PROTOCOL_CMS; + if (! strcasecmp (name,gpgme_get_protocol_name (GPGME_PROTOCOL_GPGCONF))) + return GPGME_PROTOCOL_GPGCONF; + if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_ASSUAN))) + return GPGME_PROTOCOL_ASSUAN; + if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_G13))) + return GPGME_PROTOCOL_G13; + return GPGME_PROTOCOL_UNKNOWN; +} + + +gpg_error_t +gt_set_protocol (gpgme_tool_t gt, gpgme_protocol_t proto) +{ + return gpgme_set_protocol (gt->ctx, proto); +} + + +gpg_error_t +gt_get_protocol (gpgme_tool_t gt) +{ + gpgme_protocol_t proto = gpgme_get_protocol (gt->ctx); + + gt_write_status (gt, STATUS_PROTOCOL, gpgme_get_protocol_name (proto), + NULL); + + return 0; +} + + +gpg_error_t +gt_set_armor (gpgme_tool_t gt, int armor) +{ + gpgme_set_armor (gt->ctx, armor); + return 0; +} + + +gpg_error_t +gt_get_armor (gpgme_tool_t gt) +{ + gt_write_status (gt, STATUS_ARMOR, + gpgme_get_armor (gt->ctx) ? "true" : "false", NULL); + + return 0; +} + + +gpg_error_t +gt_set_textmode (gpgme_tool_t gt, int textmode) +{ + gpgme_set_textmode (gt->ctx, textmode); + return 0; +} + + +gpg_error_t +gt_get_textmode (gpgme_tool_t gt) +{ + gt_write_status (gt, STATUS_TEXTMODE, + gpgme_get_textmode (gt->ctx) ? "true" : "false", NULL); + + return 0; +} + + +gpg_error_t +gt_set_keylist_mode (gpgme_tool_t gt, gpgme_keylist_mode_t keylist_mode) +{ + gpgme_set_keylist_mode (gt->ctx, keylist_mode); + return 0; +} + + +gpg_error_t +gt_get_keylist_mode (gpgme_tool_t gt) +{ +#define NR_KEYLIST_MODES 6 + const char *modes[NR_KEYLIST_MODES + 1]; + int idx = 0; + gpgme_keylist_mode_t mode = gpgme_get_keylist_mode (gt->ctx); + + if (mode & GPGME_KEYLIST_MODE_LOCAL) + modes[idx++] = "local"; + if (mode & GPGME_KEYLIST_MODE_EXTERN) + modes[idx++] = "extern"; + if (mode & GPGME_KEYLIST_MODE_SIGS) + modes[idx++] = "sigs"; + if (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS) + modes[idx++] = "sig_notations"; + if (mode & GPGME_KEYLIST_MODE_EPHEMERAL) + modes[idx++] = "ephemeral"; + if (mode & GPGME_KEYLIST_MODE_VALIDATE) + modes[idx++] = "validate"; + modes[idx++] = NULL; + + gt_write_status (gt, STATUS_KEYLIST_MODE, modes[0], modes[1], modes[2], + modes[3], modes[4], modes[5], modes[6]); + + return 0; +} + + +gpg_error_t +gt_set_include_certs (gpgme_tool_t gt, int include_certs) +{ + gpgme_set_include_certs (gt->ctx, include_certs); + return 0; +} + + +gpg_error_t +gt_get_include_certs (gpgme_tool_t gt) +{ + int include_certs = gpgme_get_include_certs (gt->ctx); + char buf[100]; + + if (include_certs == GPGME_INCLUDE_CERTS_DEFAULT) + strcpy (buf, "default"); + else + snprintf (buf, sizeof (buf), "%i", include_certs); + + gt_write_status (gt, STATUS_INCLUDE_CERTS, buf, NULL); + + return 0; +} + + +gpg_error_t +gt_decrypt_verify (gpgme_tool_t gt, gpgme_data_t cipher, gpgme_data_t plain, + int verify) +{ + if (verify) + return gpgme_op_decrypt_verify (gt->ctx, cipher, plain); + else + return gpgme_op_decrypt (gt->ctx, cipher, plain); +} + + +gpg_error_t +gt_sign_encrypt (gpgme_tool_t gt, gpgme_encrypt_flags_t flags, + gpgme_data_t plain, gpgme_data_t cipher, int sign) +{ + gpg_error_t err; + + if (sign) + err = gpgme_op_encrypt (gt->ctx, gt->recipients, flags, plain, cipher); + else + err = gpgme_op_encrypt_sign (gt->ctx, gt->recipients, flags, plain, cipher); + + gt_recipients_clear (gt); + + return err; +} + + +gpg_error_t +gt_sign (gpgme_tool_t gt, gpgme_data_t plain, gpgme_data_t sig, + gpgme_sig_mode_t mode) +{ + return gpgme_op_sign (gt->ctx, plain, sig, mode); +} + + +gpg_error_t +gt_verify (gpgme_tool_t gt, gpgme_data_t sig, gpgme_data_t sig_text, + gpgme_data_t plain) +{ + return gpgme_op_verify (gt->ctx, sig, sig_text, plain); +} + + +gpg_error_t +gt_import (gpgme_tool_t gt, gpgme_data_t data) +{ + return gpgme_op_import (gt->ctx, data); +} + + +gpg_error_t +gt_export (gpgme_tool_t gt, const char *pattern[], gpgme_export_mode_t mode, + gpgme_data_t data) +{ + return gpgme_op_export_ext (gt->ctx, pattern, mode, data); +} + + +gpg_error_t +gt_genkey (gpgme_tool_t gt, const char *parms, gpgme_data_t public, + gpgme_data_t secret) +{ + return gpgme_op_genkey (gt->ctx, parms, public, secret); +} + + +gpg_error_t +gt_import_keys (gpgme_tool_t gt, char *fpr[]) +{ + gpg_error_t err; + int cnt; + int idx; + gpgme_key_t *keys; + + cnt = 0; + while (fpr[cnt]) + cnt++; + + if (! cnt) + return gpg_error (GPG_ERR_INV_VALUE); + + keys = malloc ((cnt + 1) * sizeof (gpgme_key_t)); + if (! keys) + return gpg_error_from_syserror (); + + for (idx = 0; idx < cnt; idx++) + { + err = gpgme_get_key (gt->ctx, fpr[idx], &keys[idx], 0); + if (err) + break; + } + if (! err) + { + keys[cnt] = NULL; + err = gpgme_op_import_keys (gt->ctx, keys); + } + + /* Rollback. */ + while (--idx >= 0) + gpgme_key_unref (keys[idx]); + free (keys); + + return err; +} + + +gpg_error_t +gt_delete (gpgme_tool_t gt, char *fpr, int allow_secret) +{ + gpg_error_t err; + gpgme_key_t key; + + err = gpgme_get_key (gt->ctx, fpr, &key, 0); + if (err) + return err; + + err = gpgme_op_delete (gt->ctx, key, allow_secret); + gpgme_key_unref (key); + return err; +} + + +gpg_error_t +gt_keylist_start (gpgme_tool_t gt, const char *pattern[], int secret_only) +{ + return gpgme_op_keylist_ext_start (gt->ctx, pattern, secret_only, 0); +} + + +gpg_error_t +gt_keylist_next (gpgme_tool_t gt, gpgme_key_t *key) +{ + return gpgme_op_keylist_next (gt->ctx, key); +} + + +gpg_error_t +gt_getauditlog (gpgme_tool_t gt, gpgme_data_t output, unsigned int flags) +{ + return gpgme_op_getauditlog (gt->ctx, output, flags); +} + + +gpg_error_t +gt_vfs_mount (gpgme_tool_t gt, const char *container_file, + const char *mount_dir, int flags) +{ + gpg_error_t err; + gpg_error_t op_err; + err = gpgme_op_vfs_mount (gt->ctx, container_file, mount_dir, flags, &op_err); + return err || op_err; +} + + +// TODO +#define GT_RESULT_ENCRYPT 0x1 +#define GT_RESULT_DECRYPT 0x2 +#define GT_RESULT_SIGN 0x4 +#define GT_RESULT_VERIFY 0x8 +#define GT_RESULT_IMPORT 0x10 +#define GT_RESULT_GENKEY 0x20 +#define GT_RESULT_KEYLIST 0x40 +#define GT_RESULT_VFS_MOUNT 0x80 +#define GT_RESULT_ALL (~0U) + +gpg_error_t +gt_result (gpgme_tool_t gt, unsigned int flags) +{ + if (flags & GT_RESULT_ENCRYPT) + { + gpgme_encrypt_result_t res = gpgme_op_encrypt_result (gt->ctx); + if (res) + { + gpgme_invalid_key_t invrec = res->invalid_recipients; + while (invrec) + { + gt_write_status (gt, STATUS_ENCRYPT_RESULT, "invalid_recipient", + invrec->fpr, invrec->reason); + invrec = invrec->next; + } + } + } + return 0; +} + + +/* GPGME SERVER. */ + +#include + +struct server +{ + gpgme_tool_t gt; + assuan_context_t assuan_ctx; + + gpgme_data_encoding_t input_enc; + gpgme_data_encoding_t output_enc; + assuan_fd_t message_fd; + gpgme_data_encoding_t message_enc; +}; + + +gpg_error_t +server_write_status (void *hook, const char *status, const char *msg) +{ + struct server *server = hook; + return assuan_write_status (server->assuan_ctx, status, msg); +} + + +static gpgme_data_encoding_t +server_data_encoding (const char *line) +{ + if (strstr (line, "--binary")) + return GPGME_DATA_ENCODING_BINARY; + if (strstr (line, "--base64")) + return GPGME_DATA_ENCODING_BASE64; + if (strstr (line, "--armor")) + return GPGME_DATA_ENCODING_ARMOR; + if (strstr (line, "--url")) + return GPGME_DATA_ENCODING_URL; + if (strstr (line, "--urlesc")) + return GPGME_DATA_ENCODING_URLESC; + if (strstr (line, "--url0")) + return GPGME_DATA_ENCODING_URL0; + return GPGME_DATA_ENCODING_NONE; +} + + +static gpgme_error_t +server_data_obj (assuan_fd_t fd, gpgme_data_encoding_t encoding, + gpgme_data_t *data) +{ + gpgme_error_t err; + + err = gpgme_data_new_from_fd (data, fd); + if (err) + return err; + return gpgme_data_set_encoding (*data, encoding); +} + + +void +server_reset_fds (struct server *server) +{ + /* assuan closes the input and output FDs for us when doing a RESET, From cvs at cvs.gnupg.org Fri Oct 30 22:44:43 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 30 Oct 2009 22:44:43 +0100 Subject: [svn] GpgOL - r314 - in trunk: . src Message-ID: Author: wk Date: 2009-10-30 22:44:43 +0100 (Fri, 30 Oct 2009) New Revision: 314 Added: trunk/src/attic.c Removed: trunk/src/ol-ext-callback.cpp trunk/src/ol-ext-callback.h Modified: trunk/ChangeLog trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/display.cpp trunk/src/ext-commands.cpp trunk/src/ext-commands.h trunk/src/inspectors.cpp trunk/src/inspectors.h trunk/src/message-events.cpp trunk/src/message.cpp trunk/src/olflange-def.h trunk/src/olflange-dlgs.cpp trunk/src/olflange.cpp trunk/src/olflange.h trunk/src/oomhelp.cpp trunk/src/user-events.cpp Log: Many more hacks. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/ChangeLog 2009-10-30 21:44:43 UTC (rev 314) @@ -1,3 +1,7 @@ +2009-10-30 Werner Koch + + * forms/Makefile.am (icons): Udpate all icons. + 2009-10-08 Werner Koch * configure.ac (CFLAGS): Add -fno-strict-aliasing. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/ChangeLog 2009-10-30 21:44:43 UTC (rev 314) @@ -1,3 +1,28 @@ +2009-10-30 Werner Koch + + * oomhelp.cpp (get_oom_control_bytag): Fix silly bug. + + * inspectors.cpp (get_inspector_composer_flags): New. + (set_inspector_composer_flags): New. + * oomhelp.cpp (get_eecb_object): New. + * message-events.cpp (get_inspector): New. + (get_crypto_flags): New. + (OnWrite, OnWriteComplete): Use new functions instead of the class + members. Use the new oom property functions. + * ext-commands.cpp (get_inspector, get_crypto_flags): New. + (DoCommand): Use new function. + (set_crypto_flags): New. + (InstallCommands): Use set_crypto_flags. + (add_menu, check_menu, add_toolbar, struct toolbar_info_s): Remove. + (QueryButtonInfo): Remove all code. + (InstallCommands): Make use of get_eecb_object and put_oom_string. + (DoCommand): Use get_eecb_object. + * olflange.h (IExchExt): Remove m_protoSelection, m_gpgSign, + m_gpgEncrypt and all related code. + * olflange.cpp (Install): Use get_oom_string. + * display.cpp (update_display): Ditto. + * ol-ext-callback.h, ol-ext-callback.cpp: Remove. + 2009-10-29 Werner Koch * ext-commands.cpp: Remove m_nCmdDebugN, m_nCmdRevertFolder, Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/Makefile.am 2009-10-30 21:44:43 UTC (rev 314) @@ -68,7 +68,6 @@ attached-file-events.cpp attached-file-events.h \ property-sheets.cpp property-sheets.h \ item-events.h \ - ol-ext-callback.cpp ol-ext-callback.h \ oomhelp.cpp oomhelp.h eventsink.h \ explorers.cpp explorers.h \ inspectors.cpp inspectors.h \ Added: trunk/src/attic.c =================================================================== --- trunk/src/attic.c (rev 0) +++ trunk/src/attic.c 2009-10-30 21:44:43 UTC (rev 314) @@ -0,0 +1,147 @@ +/* Check whether the preview pane is visisble. Returns: + -1 := Don't know. + 0 := No + 1 := Yes. + */ +int +is_preview_pane_visible (LPEXCHEXTCALLBACK eecb) +{ + HRESULT hr; + LPDISPATCH pDisp; + DISPID dispid; + DISPPARAMS dispparams; + VARIANT aVariant, rVariant; + + pDisp = find_outlook_property (eecb, + "Application.ActiveExplorer.IsPaneVisible", + &dispid); + if (!pDisp) + { + log_debug ("%s:%s: ActiveExplorer.IsPaneVisible NOT found\n", + SRCNAME, __func__); + return -1; + } + + dispparams.rgvarg = &aVariant; + dispparams.rgvarg[0].vt = VT_INT; + dispparams.rgvarg[0].intVal = 3; /* olPreview */ + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + rVariant.bstrVal = NULL; + hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, &dispparams, + &rVariant, NULL, NULL); + pDisp->Release(); + pDisp = NULL; + if (hr == S_OK && rVariant.vt != VT_BOOL) + { + log_debug ("%s:%s: invoking IsPaneVisible succeeded but vt is %d", + SRCNAME, __func__, rVariant.vt); + if (rVariant.vt == VT_BSTR && rVariant.bstrVal) + SysFreeString (rVariant.bstrVal); + return -1; + } + if (hr != S_OK) + { + log_debug ("%s:%s: invoking IsPaneVisible failed: %#lx", + SRCNAME, __func__, hr); + return -1; + } + + return !!rVariant.boolVal; + +} + + +/* Set the preview pane to visible if visble is true or to invisible + if visible is false. */ +void +show_preview_pane (LPEXCHEXTCALLBACK eecb, int visible) +{ + HRESULT hr; + LPDISPATCH pDisp; + DISPID dispid; + DISPPARAMS dispparams; + VARIANT aVariant[2]; + + pDisp = find_outlook_property (eecb, + "Application.ActiveExplorer.ShowPane", + &dispid); + if (!pDisp) + { + log_debug ("%s:%s: ActiveExplorer.ShowPane NOT found\n", + SRCNAME, __func__); + return; + } + + dispparams.rgvarg = aVariant; + dispparams.rgvarg[0].vt = VT_BOOL; + dispparams.rgvarg[0].boolVal = !!visible; + dispparams.rgvarg[1].vt = VT_INT; + dispparams.rgvarg[1].intVal = 3; /* olPreview */ + dispparams.cArgs = 2; + dispparams.cNamedArgs = 0; + hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, &dispparams, + NULL, NULL, NULL); + pDisp->Release(); + pDisp = NULL; + if (hr != S_OK) + log_debug ("%s:%s: invoking ShowPane(%d) failed: %#lx", + SRCNAME, __func__, visible, hr); +} + + +/*** +Outlook interop ? stopping user properties appearing on Outlook message print + +Here?s a weird one? we were adding user properties to a message using the IUserProperties interface, but whenever we did this the property would render when the message was printed. This included whenever the message was sent to a recipient within the same Exchange organisation. + +Last time I had to ask Microsoft PSS to help was 1992, and in that case they were nice enough to send me a handcrafted sample application on a 3.5? floppy. This time however they got back to me in a day with this little code snippet: + +void MarkPropNoPrint(Outlook.MailItem message, string propertyName) +{ +// Late Binding in .NET +// http://support.microsoft.com/default.aspx?scid=kb;EN-US;302902 +Type userPropertyType; +long dispidMember = 107; +long ulPropPrintable = 0?4; +string dispMemberName = String.Format(?[DispID={0}]?, dispidMember); +object[] dispParams; +Microsoft.Office.Interop.Outlook.UserProperty userProperty = message.UserProperties[propertyName]; + +if (null == userProperty) return; +userPropertyType = userProperty.GetType(); + +// Call IDispatch::Invoke to get the current flags +object flags = userPropertyType.InvokeMember(dispMemberName, System.Reflection.BindingFlags.GetProperty, null, userProperty, null); +long lFlags = long.Parse(flags.ToString()); + +// Remove the hidden property Printable flag +lFlags &= ~ulPropPrintable; + +// Place the new flags property into an argument array +dispParams = new object[] {lFlags}; + +// Call IDispatch::Invoke to set the current flags +userPropertyType.InvokeMember(dispMemberName, +System.Reflection.BindingFlags.SetProperty, null, userProperty, dispParams); +} + +Srsly? there is no way I would have worked that out for myself? + +*/ + + + +/* HOWTO get the Window handle */ + +/* Use FindWindow. Use the Inspector.Caption property (be aware that on long */ +/* captions the result will be truncated at about 255 characters). The class */ +/* name to use for the Inspector window is "rctrl_renwnd32". */ + +/* I usually set any dialogs as modal to the Inspector window using */ +/* SetWindowLong, then the dialog would end up in front of the mail window, */ +/* which would be in front of the Outlook Explorer window. */ + + Modified: trunk/src/display.cpp =================================================================== --- trunk/src/display.cpp 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/display.cpp 2009-10-30 21:44:43 UTC (rev 314) @@ -29,7 +29,7 @@ #include "myexchext.h" #include "common.h" #include "mapihelp.h" -#include "ol-ext-callback.h" +#include "olflange-def.h" #include "display.h" @@ -222,7 +222,6 @@ struct find_message_window_state findstate; (void)is_sensitive; - memset (&findstate, 0, sizeof findstate); window = find_message_window (hwnd, &findstate); @@ -246,29 +245,33 @@ SetWindowTextA (window, text); return 0; } -// else if (exchange_cb && is_sensitive && !opt.compat.no_oom_write) -// { -// log_debug ("%s:%s: updating display using OOM (note)\n", -// SRCNAME, __func__); -// if (is_html) -// put_outlook_property (exchange_cb, "Body", "" ); -// return put_outlook_property -// (exchange_cb, "Body", -// _("[Encrypted body not shown - please open the message]")); -// } else if (exchange_cb && !opt.compat.no_oom_write) { + LPDISPATCH obj; + int rc; + log_debug ("%s:%s: updating display using OOM\n", SRCNAME, __func__); - /* Bug in OL 2002 and 2003 - as a workaround set the body first - to empty. */ + + obj = get_eecb_object ((LPEXCHEXTCALLBACK)exchange_cb); + if (!obj) + { + log_error ("%s:%s: Object not found via EECB\n", SRCNAME, __func__); + return -1; + } + if (is_html) - put_outlook_property (exchange_cb, "Body", "" ); - return put_outlook_property (exchange_cb, is_html? "HTMLBody":"Body", - text); + { + /* Bug in OL 2002 and 2003 - as a workaround set the body + first to empty. */ + put_oom_string (obj, "Body", ""); + } + rc = put_oom_string (obj, is_html? "HTMLBody":"Body", text); + obj->Release (); + return rc; } else { - log_debug ("%s:%s: window handle not found for parent %p\n", + log_error ("%s:%s: window handle not found for parent %p\n", SRCNAME, __func__, hwnd); return -1; } Modified: trunk/src/ext-commands.cpp =================================================================== --- trunk/src/ext-commands.cpp 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/ext-commands.cpp 2009-10-30 21:44:43 UTC (rev 314) @@ -35,48 +35,23 @@ #include "dialogs.h" /* For IDB_foo. */ #include "olflange-def.h" #include "olflange.h" -#include "ol-ext-callback.h" #include "message.h" #include "engine.h" #include "revert.h" #include "ext-commands.h" #include "explorers.h" +#include "inspectors.h" #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \ SRCNAME, __func__, __LINE__); \ } while (0) -/* An object to store information about active (installed) toolbar - buttons. */ -struct toolbar_info_s -{ - toolbar_info_t next; - UINT button_id;/* The ID of the button as assigned by Outlook. */ - UINT bitmap; /* The bitmap of the button. */ - UINT cmd_id; /* The ID of the command to send on a click. */ - const char *desc;/* The description text. */ - ULONG context; /* Context under which this entry will be used. */ - int did_qbi; /* Has been processed by QueryButtonInfo. */ -}; - - /* Keep copies of some bitmaps. */ static int bitmaps_initialized; static HBITMAP my_check_bitmap, my_uncheck_bitmap; - -static void add_menu (LPEXCHEXTCALLBACK eecb, - UINT FAR *pnCommandIDBase, ...) -#if __GNUC__ >= 4 - __attribute__ ((sentinel)) -#endif - ; - - - - /* Wrapper around UlRelease with error checking. */ static void ul_release (LPVOID punk, const char *func, int lnr) @@ -99,7 +74,6 @@ m_pExchExt = pParentInterface; m_lRef = 0; m_lContext = 0; - m_toolbar_info = NULL; m_hWnd = NULL; if (!bitmaps_initialized) @@ -113,12 +87,7 @@ /* Destructor */ GpgolExtCommands::~GpgolExtCommands (void) { - while (m_toolbar_info) - { - toolbar_info_t tmp = m_toolbar_info->next; - xfree (m_toolbar_info); - m_toolbar_info = tmp; - } + } @@ -136,142 +105,64 @@ } -/* Add a new menu. The variable entries are made up of pairs of - strings and UINT *. A NULL is used to terminate this list. An - empty string is translated to a separator menu item. One level of - submenus are supported. */ -static void -add_menu (LPEXCHEXTCALLBACK eecb, UINT FAR *pnCommandIDBase, ...) +/* Note: Duplicated from message-events.cpp. Eventually we should get + rid of this module. */ +static LPDISPATCH +get_inspector (LPEXCHEXTCALLBACK eecb) { - va_list arg_ptr; - HMENU mainmenu, submenu, menu; - const char *string; - UINT *cmdptr; + LPDISPATCH obj; + LPDISPATCH inspector = NULL; - va_start (arg_ptr, pnCommandIDBase); - /* We put all new entries into the tools menu. To make this work we - need to pass the id of an existing item from that menu. */ - eecb->GetMenuPos (EECMDID_ToolsCustomizeToolbar, &mainmenu, NULL, NULL, 0); - menu = mainmenu; - submenu = NULL; - while ( (string = va_arg (arg_ptr, const char *)) ) + obj = get_eecb_object (eecb); + if (obj) { - cmdptr = va_arg (arg_ptr, UINT*); - - if (!*string) - ; /* Ignore this entry. */ - else if (*string == '@' && !string[1]) - AppendMenu (menu, MF_SEPARATOR, 0, NULL); - else if (*string == '>') - { - submenu = CreatePopupMenu (); - AppendMenu (menu, MF_STRING|MF_POPUP, (UINT_PTR)submenu, string+1); - menu = submenu; - } - else if (*string == '<') - { - menu = mainmenu; - submenu = NULL; - } - else - { - AppendMenu (menu, MF_STRING, *pnCommandIDBase, string); - if (menu == submenu) - SetMenuItemBitmaps (menu, *pnCommandIDBase, MF_BYCOMMAND, - my_uncheck_bitmap, my_check_bitmap); - if (cmdptr) - *cmdptr = *pnCommandIDBase; - (*pnCommandIDBase)++; - } + /* This should be MailItem; use the getInspector method. */ + inspector = get_oom_object (obj, "GetInspector"); + obj->Release (); } - va_end (arg_ptr); + return inspector; } -static void -check_menu (LPEXCHEXTCALLBACK eecb, UINT menu_id, int checked) +/* Note: Duplicated from message-events.cpp. Eventually we should get + rid of this module. */ +static int +get_crypto_flags (LPEXCHEXTCALLBACK eecb, bool *r_sign, bool *r_encrypt) { - HMENU menu; - - eecb->GetMenuPos (EECMDID_ToolsCustomizeToolbar, &menu, NULL, NULL, 0); - if (debug_commands) - log_debug ("check_menu: eecb=%p menu_id=%u checked=%d -> menu=%p\n", - eecb, menu_id, checked, menu); - CheckMenuItem (menu, menu_id, - MF_BYCOMMAND | (checked?MF_CHECKED:MF_UNCHECKED)); -} - - - -void -GpgolExtCommands::add_toolbar (LPTBENTRY tbearr, UINT n_tbearr, ...) -{ - va_list arg_ptr; - const char *desc; - UINT bmapid; - UINT cmdid; - int tbeidx; - toolbar_info_t tb_info; + LPDISPATCH inspector; int rc; - for (tbeidx = n_tbearr-1; tbeidx > -1; tbeidx--) - if (tbearr[tbeidx].tbid == EETBID_STANDARD) - break; - if (!(tbeidx > -1)) + inspector = get_inspector (eecb); + if (!inspector) { - log_error ("standard toolbar not found"); - return; + log_error ("%s:%s: inspector not found", SRCNAME, __func__); + rc = -1; } - - SendMessage (tbearr[tbeidx].hwnd, TB_BUTTONSTRUCTSIZE, - (WPARAM)(int)sizeof (TBBUTTON), 0); - - - va_start (arg_ptr, n_tbearr); - - while ( (desc = va_arg (arg_ptr, const char *)) ) + else { - bmapid = va_arg (arg_ptr, UINT); - cmdid = va_arg (arg_ptr, UINT); + rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt); + inspector->Release (); + } + return rc; +} - if (!*desc) - ; /* Empty description - ignore this item. */ - else if (*desc == '|' && !desc[1]) - { - /* Separator. Ignore BMAPID and CMDID. */ - /* Not yet implemented. */ - } - else - { - TBADDBITMAP tbab; - - tb_info = (toolbar_info_t)xcalloc (1, sizeof *tb_info); - tb_info->button_id = tbearr[tbeidx].itbbBase++; - tbab.hInst = glob_hinst; - tbab.nID = bmapid; - rc = SendMessage (tbearr[tbeidx].hwnd, TB_ADDBITMAP,1,(LPARAM)&tbab); - if (rc == -1) - log_error_w32 (-1, "TB_ADDBITMAP failed for `%s'", desc); - tb_info->bitmap = rc; - tb_info->cmd_id = cmdid; - tb_info->desc = desc; - tb_info->context = m_lContext; +static void +set_crypto_flags (LPEXCHEXTCALLBACK eecb, bool sign, bool encrypt) +{ + LPDISPATCH inspector; - tb_info->next = m_toolbar_info; - m_toolbar_info = tb_info; - if (debug_commands) - log_debug ("%s:%s: ctx=%lx button_id=%d cmd_id=%d '%s'\n", - SRCNAME, __func__, m_lContext, - tb_info->button_id, tb_info->cmd_id, tb_info->desc); - } + inspector = get_inspector (eecb); + if (!inspector) + log_error ("%s:%s: inspector not found", SRCNAME, __func__); + else + { + set_inspector_composer_flags (inspector, sign, encrypt); + inspector->Release (); } - va_end (arg_ptr); - } - /* Called by Exchange to install commands and toolbar buttons. Returns S_FALSE to signal Exchange to continue calling extensions. */ STDMETHODIMP @@ -287,14 +178,7 @@ { HRESULT hr; m_hWnd = hWnd; - LPDISPATCH pDisp; - DISPID dispid; - DISPID dispid_put = DISPID_PROPERTYPUT; - DISPPARAMS dispparams; - VARIANT aVariant; - int force_encrypt = 0; - char *draft_info = NULL; - + LPDISPATCH obj; (void)hMenu; @@ -302,7 +186,6 @@ log_debug ("%s:%s: context=%s flags=0x%lx\n", SRCNAME, __func__, ext_context_name (m_lContext), lFlags); - show_event_object (eecb, __func__); /* Outlook 2003 sometimes displays the plaintext and sometimes the original undecrypted text when doing a reply. This seems to @@ -326,6 +209,8 @@ { LPMDB mdb = NULL; LPMESSAGE message = NULL; + int force_encrypt = 0; + char *draft_info = NULL; /* Note that for read and send the object returned by the outlook extension callback is of class 43 (MailItem) so we @@ -335,72 +220,38 @@ log_debug ("%s:%s: getObject failed: hr=%#lx\n", SRCNAME,__func__,hr); else if (!opt.compat.no_msgcache) { - const char *body; - char *key = NULL; - size_t keylen = 0; - void *refhandle = NULL; - - pDisp = find_outlook_property (eecb, "ConversationIndex", &dispid); - if (pDisp) + obj = get_eecb_object (eecb); + if (obj) { - DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; + const char *body; + char *key, *p; + size_t keylen; + void *refhandle = NULL; - aVariant.bstrVal = NULL; - hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, - DISPATCH_PROPERTYGET, &dispparamsNoArgs, - &aVariant, NULL, NULL); - if (hr != S_OK) - log_debug ("%s:%s: retrieving ConversationIndex failed: %#lx", - SRCNAME, __func__, hr); - else if (aVariant.vt != VT_BSTR) - log_debug ("%s:%s: ConversationIndex is not a string (%d)", - SRCNAME, __func__, aVariant.vt); - else if (aVariant.bstrVal) + key = get_oom_string (obj, "ConversationIndex"); + if (key) { - char *p; - - key = wchar_to_utf8 (aVariant.bstrVal); log_debug ("%s:%s: ConversationIndex is `%s'", - SRCNAME, __func__, key); + SRCNAME, __func__, key); /* The key is a hex string. Convert it to binary. */ for (keylen=0,p=key; hexdigitp(p) && hexdigitp(p+1); p += 2) ((unsigned char*)key)[keylen++] = xtoi_2 (p); - SysFreeString (aVariant.bstrVal); + if (keylen && (body = msgcache_get (key, keylen, &refhandle))) + { + put_oom_string (obj, "Body", body); + /* Because we found the plaintext in the cache + we can assume that the orginal message has + been encrypted and thus we now set a flag to + make sure that by default the reply gets + encrypted too. */ + force_encrypt = 1; + } + msgcache_unref (refhandle); + xfree (key); } - - pDisp->Release(); - pDisp = NULL; + obj->Release (); } - - if (key && keylen - && (body = msgcache_get (key, keylen, &refhandle)) - && (pDisp = find_outlook_property (eecb, "Body", &dispid))) - { - dispparams.cNamedArgs = 1; - dispparams.rgdispidNamedArgs = &dispid_put; - dispparams.cArgs = 1; - dispparams.rgvarg = &aVariant; - dispparams.rgvarg[0].vt = VT_LPWSTR; - dispparams.rgvarg[0].bstrVal = utf8_to_wchar (body); - hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, - DISPATCH_PROPERTYPUT, &dispparams, - NULL, NULL, NULL); - xfree (dispparams.rgvarg[0].bstrVal); - log_debug ("%s:%s: PROPERTYPUT(body) result -> %#lx\n", - SRCNAME, __func__, hr); - - pDisp->Release(); - pDisp = NULL; - - /* Because we found the plaintext in the cache we can assume - that the orginal message has been encrypted and thus we - now set a flag to make sure that by default the reply - gets encrypted too. */ - force_encrypt = 1; - } - msgcache_unref (refhandle); - xfree (key); } /* Because we have the message open, we use it to get the draft @@ -408,43 +259,36 @@ if (message) draft_info = mapi_get_gpgol_draft_info (message); - ul_release (message, __func__, __LINE__); ul_release (mdb, __func__, __LINE__); + + if (!opt.disable_gpgol) + { + bool sign, encrypt; + + if (draft_info && draft_info[0] == 'E') + encrypt = true; + else if (draft_info && draft_info[0] == 'e') + encrypt = false; + else + encrypt = !!opt.encrypt_default; + + if (draft_info && draft_info[0] && draft_info[1] == 'S') + sign = true; + else if (draft_info && draft_info[0] && draft_info[1] == 's') + sign = false; + else + sign = !!opt.sign_default; + + if (force_encrypt) + encrypt = true; + + /* FIXME: ove that to the inspector activation. */ + //set_crypto_flags (eecb, sign, encrypt); + } + xfree (draft_info); } - /* Now install menu and toolbar items. */ - if (m_lContext == EECONTEXT_READNOTEMESSAGE) - { - } - else if (m_lContext == EECONTEXT_SENDNOTEMESSAGE && !opt.disable_gpgol) - { - m_pExchExt->m_protoSelection = opt.default_protocol; - - if (draft_info && draft_info[0] == 'E') - m_pExchExt->m_gpgEncrypt = true; - else if (draft_info && draft_info[0] == 'e') - m_pExchExt->m_gpgEncrypt = false; - else - m_pExchExt->m_gpgEncrypt = opt.encrypt_default; - - if (draft_info && draft_info[0] && draft_info[1] == 'S') - m_pExchExt->m_gpgSign = true; - else if (draft_info && draft_info[0] && draft_info[1] == 's') - m_pExchExt->m_gpgSign = false; - else - m_pExchExt->m_gpgSign = opt.sign_default; - - if (force_encrypt) - m_pExchExt->m_gpgEncrypt = true; - } - else if (m_lContext == EECONTEXT_VIEWER) - { - - } - - xfree (draft_info); - return S_FALSE; } @@ -467,8 +311,6 @@ SRCNAME, __func__, nCommandID, nCommandID, ext_context_name (m_lContext), hwnd); - show_event_object (eecb, __func__); - if (nCommandID == SC_CLOSE && m_lContext == EECONTEXT_READNOTEMESSAGE) { /* This is the system close command. Replace it with our own to @@ -477,14 +319,16 @@ own OOM (in this case Body). */ LPDISPATCH pDisp; DISPID dispid; - DISPPARAMS dispparams; - VARIANT aVariant; if (debug_commands) log_debug ("%s:%s: command Close called\n", SRCNAME, __func__); - pDisp = find_outlook_property (eecb, "Close", &dispid); - if (pDisp) + + pDisp = get_eecb_object (eecb); + dispid = lookup_oom_dispid (pDisp, "Close"); + if (pDisp && dispid != DISPID_UNKNOWN) { + DISPPARAMS dispparams; + VARIANT aVariant; /* Note that there is a report on the Net from 2005 by Amit Joshi where he claims that in Outlook XP olDiscard does not work but is treated like olSave. */ @@ -509,8 +353,12 @@ SRCNAME, __func__, hr); } else - log_debug ("%s:%s: invoking Close failed: no Close method)", - SRCNAME, __func__); + { + if (pDisp) + pDisp->Release (); + log_debug ("%s:%s: invoking Close failed: no Close method)", + SRCNAME, __func__); + } message_wipe_body_cruft (eecb); @@ -542,17 +390,18 @@ && m_lContext == EECONTEXT_SENDNOTEMESSAGE) { char buf[4]; + bool sign, encrypt; log_debug ("%s:%s: command SaveMessage called\n", SRCNAME, __func__); - buf[0] = m_pExchExt->m_gpgEncrypt? 'E':'e'; - buf[1] = m_pExchExt->m_gpgSign? 'S':'s'; - switch (m_pExchExt->m_protoSelection) + + if (get_crypto_flags (eecb, &sign, &encrypt)) + buf[0] = buf[1] = '?'; + else { - case PROTOCOL_UNKNOWN: buf[2] = 'A'; break; - case PROTOCOL_OPENPGP: buf[2] = 'P'; break; - case PROTOCOL_SMIME: buf[2] = 'X'; break; - default: buf[2] = '-'; break; + buf[0] = encrypt? 'E':'e'; + buf[1] = sign? 'S':'s'; } + buf[2] = 'A'; /* Automatic. */ buf[3] = 0; hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); @@ -595,9 +444,8 @@ GpgolExtCommands::Help (LPEXCHEXTCALLBACK eecb, UINT nCommandID) { (void)eecb; + (void)nCommandID; - show_event_object (eecb, __func__); - return S_FALSE; } @@ -634,42 +482,10 @@ LPTSTR description, UINT description_size, ULONG flags) { - toolbar_info_t tb_info; - size_t n; - - (void)description_size; (void)flags; - for (tb_info = m_toolbar_info; tb_info; tb_info = tb_info->next ) - if (tb_info->button_id == buttonid - && tb_info->context == m_lContext) - break; - if (!tb_info) - return S_FALSE; /* Not one of our toolbar buttons. */ - - if (debug_commands) - log_debug ("%s:%s: ctx=%lx tbid=%ld button_id(req)=%d got=%d" - " cmd_id=%d '%s'\n", - SRCNAME, __func__, m_lContext, toolbarid, buttonid, - tb_info->button_id, tb_info->cmd_id, tb_info->desc); - - /* Mark that this button has passed this function. */ - tb_info->did_qbi = 1; - - pTBB->iBitmap = tb_info->bitmap; - pTBB->idCommand = tb_info->cmd_id; - pTBB->fsState = TBSTATE_ENABLED; - pTBB->fsStyle = TBSTYLE_BUTTON; - pTBB->dwData = 0; - pTBB->iString = -1; - - n = strlen (tb_info->desc); - if (n > description_size) - n = description_size; - lstrcpyn (description, tb_info->desc, n); - - return S_OK; + return S_FALSE; /* Not one of our toolbar buttons. */ } Modified: trunk/src/ext-commands.h =================================================================== --- trunk/src/ext-commands.h 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/ext-commands.h 2009-10-30 21:44:43 UTC (rev 314) @@ -40,16 +40,10 @@ ULONG m_lRef; ULONG m_lContext; - /* A list of all active toolbar items. */ - toolbar_info_t m_toolbar_info; - HWND m_hWnd; GpgolExt* m_pExchExt; - void add_toolbar (LPTBENTRY tbearr, UINT n_tbearr, ...); - void update_protocol_menu (LPEXCHEXTCALLBACK eecb); - public: STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj); inline STDMETHODIMP_(ULONG) AddRef (void) Modified: trunk/src/inspectors.cpp =================================================================== --- trunk/src/inspectors.cpp 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/inspectors.cpp 2009-10-30 21:44:43 UTC (rev 314) @@ -64,11 +64,15 @@ /* Event sink for an Inspector object. */ +typedef struct GpgolInspectorEvents GpgolInspectorEvents; +typedef GpgolInspectorEvents *LPGPGOLINSPECTOREVENTS; + BEGIN_EVENT_SINK(GpgolInspectorEvents, IOOMInspectorEvents) STDMETHOD_ (void, Activate) (THIS_); STDMETHOD_ (void, Close) (THIS_); STDMETHOD_ (void, Deactivate) (THIS_); bool m_first_activate_seen; + unsigned long m_serialno; EVENT_SINK_CTOR(GpgolInspectorEvents) { m_first_activate_seen = false; @@ -105,6 +109,7 @@ struct button_list_s { struct button_list_s *next; + unsigned long serialno; /* of the inspector. */ LPDISPATCH sink; LPDISPATCH button; int instid; @@ -124,6 +129,9 @@ /* The inspector object. */ LPOOMINSPECTOR inspector; + /* Our serial number for the inspector. */ + unsigned long serialno; + /* The event sink object. This is used by the event methods to locate the inspector object. */ LPOOMINSPECTOREVENTS eventsink; @@ -139,6 +147,8 @@ static HANDLE all_inspectors_lock; +static void add_inspector_controls (LPOOMINSPECTOR inspector, + unsigned long serialno); static void update_crypto_info (LPDISPATCH button); @@ -187,12 +197,30 @@ } +/* Return a new serial number for an inspector. These serial numbers + are used to make the button tags unique. */ +static unsigned long +create_inspector_serial (void) +{ + static long serial; + long n; + + /* Avoid returning 0 because we use that value as Nil. */ + while (!(n = InterlockedIncrement (&serial))) + ; + return (unsigned long)n; +} + + /* Add SINK and BUTTON to the list at LISTADDR. The list takes ownership of SINK and BUTTON, thus the caller may not use OBJ or - OBJ2 after this call. If TAG is given it is stored as well. */ + OBJ2 after this call. If TAG must be given without the + serialnumber suffix. SERIALNO is the serialno of the correspnding + inspector. */ static void move_to_button_list (button_list_t *listaddr, - LPDISPATCH sink, LPDISPATCH button, const char *tag) + LPDISPATCH sink, LPDISPATCH button, + const char *tag, unsigned long serialno) { button_list_t item; int instid; @@ -202,13 +230,14 @@ instid = button? get_oom_int (button, "InstanceId"): 0; - // log_debug ("%s:%s: sink=%p btn=%p tag=(%s) instid=%d", - // SRCNAME, __func__, sink, button, tag, instid); + log_debug ("%s:%s: sink=%p btn=%p tag=(%s) instid=%d", + SRCNAME, __func__, sink, button, tag, instid); item = (button_list_t)xcalloc (1, sizeof *item + strlen (tag)); item->sink = sink; item->button = button; item->instid = instid; + item->serialno = serialno; strcpy (item->tag, tag); item->next = *listaddr; *listaddr = item; @@ -217,7 +246,7 @@ /* Register the inspector object INSPECTOR along with its event SINK. */ static void -register_inspector (LPOOMINSPECTOR inspector, LPOOMINSPECTOREVENTS sink) +register_inspector (LPOOMINSPECTOR inspector, LPGPGOLINSPECTOREVENTS sink) { inspector_info_t item; @@ -225,6 +254,7 @@ lock_all_inspectors (); inspector->AddRef (); item->inspector = inspector; + item->serialno = sink->m_serialno = create_inspector_serial (); sink->AddRef (); item->eventsink = sink; @@ -303,6 +333,65 @@ } +/* Return the serialno of INSPECTOR or 0 if not found. */ +static unsigned long +get_serialno (LPDISPATCH inspector) +{ + unsigned int result = 0; + inspector_info_t iinfo; + + /* FIXME: This might not bet reliable. We merely compare the + pointer and not something like an Instance Id. We should check + whether this is sufficient or whether to track the inspectors + with different hack. For example we could add an invisible menu + entry and scan for that entry to get the serial number serial + number of it. A better option would be to add a custom property + to the inspector, but that seems not supported - we could of + course add it to a button then. */ + lock_all_inspectors (); + + for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next) + if (iinfo->inspector == inspector) + { + result = iinfo->serialno; + break; + } + + unlock_all_inspectors (); + return result; +} + + +/* Return the button with TAG and assigned to the isnpector with + SERIALNO. Return NULL if not found. */ +static LPDISPATCH +get_button (unsigned long serialno, const char *tag) +{ + LPDISPATCH result = NULL; + inspector_info_t iinfo; + button_list_t ol; + + lock_all_inspectors (); + + for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next) + if (iinfo->serialno == serialno) + { + for (ol = iinfo->buttons; ol; ol = ol->next) + if (ol->tag && !strcmp (ol->tag, tag)) + { + result = ol->button; + if (result) + result->AddRef (); + break; + } + break; + } + + unlock_all_inspectors (); + return result; +} + + /* Search through all objects and find the inspector which has a button with the instanceId INSTID. The find the button with TAG in that inspector and return it. Caller must release the returned @@ -315,7 +404,7 @@ button_list_t ol; // log_debug ("%s:%s: inst=%d tag=(%s)",SRCNAME, __func__, instid, tag); - + lock_all_inspectors (); for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next) @@ -340,6 +429,7 @@ + /* The method called by outlook for each new inspector. Note that Outlook sometimes reuses Inspectro objects thus this event is not an indication for a newly opened Inspector. */ @@ -356,7 +446,7 @@ obj = install_GpgolInspectorEvents_sink ((LPDISPATCH)inspector); if (obj) { - register_inspector (inspector, (LPOOMINSPECTOREVENTS)obj); + register_inspector (inspector, (LPGPGOLINSPECTOREVENTS)obj); obj->Release (); } inspector->Release (); @@ -402,16 +492,16 @@ if (!m_first_activate_seen) { m_first_activate_seen = true; - add_inspector_controls (inspector); + add_inspector_controls (inspector, m_serialno); } /* Update the crypt info. */ - obj = get_oom_object (m_object, "CommandBars"); + obj = get_oom_object (inspector, "CommandBars"); if (!obj) log_error ("%s:%s: CommandBars not found", SRCNAME, __func__); else { - button = get_oom_control_bytag (obj, "GpgOL_Inspector_Crypto_Info"); + button = get_button (m_serialno, "GpgOL_Inspector_Crypto_Info"); obj->Release (); if (button) { @@ -453,41 +543,126 @@ } +/* Get the flags from the inspector; i.e. whether to sign or encrypt a + message. Returns 0 on success. */ +int +get_inspector_composer_flags (LPDISPATCH inspector, + bool *r_sign, bool *r_encrypt) +{ + LPDISPATCH button; + int rc = 0; + unsigned long serialno; + + serialno = get_serialno (inspector); + if (!serialno) + { + log_error ("%s:%s: S/n not found", SRCNAME, __func__); + return -1; + } + + button = get_button (serialno, "GpgOL_Inspector_Sign"); + if (!button) + { + log_error ("%s:%s: Sign button not found", SRCNAME, __func__); + rc = -1; + } + else + { + *r_sign = get_oom_int (button, "State") == msoButtonDown; + button->Release (); + } + + button = get_button (serialno, "GpgOL_Inspector_Encrypt"); + if (!button) + { + log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__); + rc = -1; + } + else + { + *r_encrypt = get_oom_int (button, "State") == msoButtonDown; + button->Release (); + } + + if (!rc) + log_debug ("%s:%s: sign=%d encrypt=%d", + SRCNAME, __func__, *r_sign, *r_encrypt); + return rc; +} + + +/* Set the flags for the inspector; i.e. whether to sign or encrypt a + message. Returns 0 on success. */ +int +set_inspector_composer_flags (LPDISPATCH inspector, bool sign, bool encrypt) +{ + LPDISPATCH button; + int rc = 0; + unsigned long serialno; + + serialno = get_serialno (inspector); + if (!serialno) + { + log_error ("%s:%s: S/n not found", SRCNAME, __func__); + return -1; + } + + button = get_button (serialno, "GpgOL_Inspector_Sign"); + if (!button) + { + log_error ("%s:%s: Sign button not found", SRCNAME, __func__); + rc = -1; + } + else + { + if (put_oom_int (button, "State", sign? msoButtonDown : msoButtonUp)) + rc = -1; + button->Release (); + } + + button = get_button (serialno, "GpgOL_Inspector_Encrypt"); + if (!button) + { + log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__); + rc = -1; + } + else + { + if (put_oom_int (button, "State", encrypt? msoButtonDown : msoButtonUp)) + rc = -1; + button->Release (); + } + + return rc; +} + + +/* Helper to make the tag unique. */ +static const char * +add_tag (LPDISPATCH control, unsigned long serialno, const char *value) +{ + char buf[256]; + + snprintf (buf, sizeof buf, "%s#%lu", value, serialno); + put_oom_string (control, "Tag", buf); + return value; +} + + /* Add all the controls. */ -void -add_inspector_controls (LPOOMINSPECTOR inspector) +static void +add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno) { + static LPDISPATCH obj, controls, button; inspector_info_t inspinfo; button_list_t buttonlist = NULL; const char *tag; int in_composer; + log_debug ("%s:%s: Enter", SRCNAME, __func__); - /* In theory we should take a lock here to avoid a race between the - test for a new control and the creation. However, we are not - called from a second thread. FIXME: We might want to use - inspector_info insteasd to check this. However this requires us - to keep a lock per inspector. */ - - /* Check that our controls do not already exist. */ - obj = get_oom_object (inspector, "CommandBars"); - if (!obj) - { - log_error ("%s:%s: CommandBars not found", SRCNAME, __func__); - return; - } - button= get_oom_control_bytag (obj, "GpgOL_Inspector_Crypto_Info"); - obj->Release (); - if (button) - { - button->Release (); - log_debug ("%s:%s: Leave (Controls are already added)", - SRCNAME, __func__); - return; - } - /* Check whether we are in composer or read mode. */ in_composer = is_inspector_in_composer_mode (inspector); @@ -503,7 +678,7 @@ button = opt.disable_gpgol? NULL : add_oom_button (controls); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt"); put_oom_bool (button, "BeginGroup", true); put_oom_int (button, "Style", msoButtonIconAndCaption ); put_oom_string (button, "Caption", @@ -511,19 +686,19 @@ put_oom_icon (button, IDB_ENCRYPT, 16); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = opt.disable_gpgol? NULL : add_oom_button (controls); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Sign"); put_oom_int (button, "Style", msoButtonIconAndCaption ); put_oom_string (button, "Caption", _("&sign message with GnuPG")); put_oom_icon (button, IDB_SIGN, 16); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } controls->Release (); @@ -541,49 +716,49 @@ button = in_composer? NULL : add_oom_button (controls); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Verify")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Verify"); put_oom_int (button, "Style", msoButtonIconAndCaption ); put_oom_string (button, "Caption", _("GpgOL Decrypt/Verify")); put_oom_icon (button, IDB_DECRYPT_VERIFY, 16); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = opt.enable_debug? add_oom_button (controls) : NULL; if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-0")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-0"); put_oom_int (button, "Style", msoButtonCaption ); put_oom_string (button, "Caption", "GpgOL Debug-0 (display crypto info)"); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = opt.enable_debug? add_oom_button (controls) : NULL; if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-1")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-1"); put_oom_int (button, "Style", msoButtonCaption ); put_oom_string (button, "Caption", "GpgOL Debug-1 (open_inspector)"); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = opt.enable_debug? add_oom_button (controls) : NULL; if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-2")); + tag = add_tag (button, serialno,"GpgOL_Inspector_Debug-2"); put_oom_int (button, "Style", msoButtonCaption ); put_oom_string (button, "Caption", "GpgOL Debug-2 (change message class)"); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } controls->Release (); @@ -602,38 +777,38 @@ ? NULL : add_oom_button (controls)); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt at t")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt at t"); put_oom_int (button, "Style", msoButtonIcon ); put_oom_string (button, "Caption", _("Encrypt message with GnuPG")); put_oom_icon (button, IDB_ENCRYPT, 16); put_oom_int (button, "State", msoButtonMixed ); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = (opt.disable_gpgol || !in_composer ? NULL : add_oom_button (controls)); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign at t")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Sign at t"); put_oom_int (button, "Style", msoButtonIcon); put_oom_string (button, "Caption", _("Sign message with GnuPG")); put_oom_icon (button, IDB_SIGN, 16); put_oom_int (button, "State", msoButtonDown); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } button = in_composer? NULL : add_oom_button (controls); if (button) { - put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Crypto_Info")); + tag = add_tag (button, serialno, "GpgOL_Inspector_Crypto_Info"); put_oom_int (button, "Style", msoButtonIcon); obj = install_GpgolCommandBarButtonEvents_sink (button); - move_to_button_list (&buttonlist, obj, button, tag); + move_to_button_list (&buttonlist, obj, button, tag, serialno); } controls->Release (); @@ -763,14 +938,18 @@ { int state = get_oom_int (button, "State"); char tag2[256]; + char *p; LPDISPATCH button2; - log_debug ("%s:%s: button `%s' state is %d", SRCNAME, tag, __func__, state); + log_debug ("%s:%s: button `%s' state is %d", SRCNAME, __func__, tag, state); state = (state == msoButtonUp)? msoButtonDown : msoButtonUp; put_oom_int (button, "State", state); /* Toggle the other button. */ mem2str (tag2, tag, sizeof tag2 - 2); + p = strchr (tag2, '#'); + if (p) + *p = 0; /* Strip the serialno suffix. */ if (*tag2 && tag2[1] && !strcmp (tag2+strlen(tag2)-2, "@t")) tag2[strlen(tag2)-2] = 0; /* Remove the "@t". */ else Modified: trunk/src/inspectors.h =================================================================== --- trunk/src/inspectors.h 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/inspectors.h 2009-10-30 21:44:43 UTC (rev 314) @@ -37,6 +37,7 @@ typedef struct IOOMInspectorsEvents IOOMInspectorsEvents; typedef IOOMInspectorsEvents *LPOOMINSPECTORSEVENTS; + EXTERN_C const IID IID_IOOMInspector; #undef INTERFACE #define INTERFACE IOOMInspector @@ -122,12 +123,15 @@ LPDISPATCH install_GpgolInspectorEvents_sink (LPDISPATCH object); -void add_inspector_controls (LPOOMINSPECTOR inspector); - void proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid); +int get_inspector_composer_flags (LPDISPATCH inspector, + bool *r_sign, bool *r_encrypt); +int set_inspector_composer_flags (LPDISPATCH inspector, + bool sign, bool encrypt); + #endif /*INSPECTORS_H*/ Modified: trunk/src/message-events.cpp =================================================================== --- trunk/src/message-events.cpp 2009-10-30 10:34:51 UTC (rev 313) +++ trunk/src/message-events.cpp 2009-10-30 21:44:43 UTC (rev 314) @@ -32,13 +32,13 @@ #include "olflange-def.h" #include "olflange.h" -#include "ol-ext-callback.h" #include "mimeparser.h" #include "mimemaker.h" #include "message.h" #include "message-events.h" #include "explorers.h" +#include "inspectors.h" #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \ SRCNAME, __func__, __LINE__); \ @@ -99,6 +99,47 @@ } +/* Return the inspector the the current Mailitem. If the inspector + does not exists, an inspector object is created (but not + immediatley shown). */ +static LPDISPATCH +get_inspector (LPEXCHEXTCALLBACK eecb) +{ + LPDISPATCH obj; + LPDISPATCH inspector = NULL; + + obj = get_eecb_object (eecb); + if (obj) + { + /* This should be MailItem; use the getInspector method. */ + inspector = get_oom_object (obj, "GetInspector"); + obj->Release (); + } + return inspector; +} + + +static int +get_crypto_flags (LPEXCHEXTCALLBACK eecb, bool *r_sign, bool *r_encrypt) +{ + LPDISPATCH inspector; + int rc; + + inspector = get_inspector (eecb); + if (!inspector) + { + log_error ("%s:%s: inspector not found", SRCNAME, __func__); + rc = -1; + } + else + { + rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt); + inspector->Release (); + } + return rc; +} + + /* Called from Exchange on reading a message. Returns: S_FALSE to signal Exchange to continue calling extensions. EECB is a pointer to the IExchExtCallback interface. */ @@ -118,9 +159,6 @@ log_debug ("%s:%s: received (hwnd=%p) %s\n", SRCNAME, __func__, hwnd, m_gotinspector? "got_inspector":""); - show_event_object (eecb, __func__); - //add_oom_command_button (eecb); - /* Fixme: If preview decryption is not enabled and we have an encrypted message, we might want to show a greyed out preview window. There are two ways to clear the preview window: @@ -168,8 +206,6 @@ log_debug ("%s:%s: received; flags=%#lx m_processed=%d \n", SRCNAME, __func__, flags, m_processed); - show_event_object (eecb, __func__); - /* If the message has been processed by us (i.e. in OnRead), we now use our own display code. */ if (!flags && m_processed && !opt.disable_gpgol) @@ -193,61 +229,37 @@ STDMETHODIMP GpgolMessageEvents::OnWrite (LPEXCHEXTCALLBACK eecb) { + LPDISPATCH obj; + HWND hWnd = NULL; + bool sign, encrypt, need_crypto;