From ec8c9d9494494656b2618ecfc43ec485dc931ec4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 31 Jul 2001 15:21:58 +0000 Subject: [PATCH] A couple of minor changes and a short README for Gpgcom --- TODO | 9 +++++- complus/Makefile.am | 2 +- complus/README | 72 ++++++++++++++++++++++++++++++++++++++++++++ configure.in | 2 +- gpgme/ChangeLog | 27 +++++++++++++++++ gpgme/data.c | 24 +++++++++++---- gpgme/encrypt.c | 8 ++++- gpgme/gpgme.c | 34 +++++++++++++++++++++ gpgme/gpgme.h | 4 ++- gpgme/mkstatus | 5 ++++ gpgme/rungpg.c | 15 ++++++++++ gpgme/rungpg.h | 1 + gpgme/util.c | 14 --------- gpgme/version.c | 2 +- gpgme/w32-io.c | 10 +++++-- jnlib/ChangeLog | 5 ++++ jnlib/stringhelp.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ jnlib/stringhelp.h | 9 ++++++ 18 files changed, 288 insertions(+), 28 deletions(-) create mode 100644 complus/README diff --git a/TODO b/TODO index 7fb09837..7724065b 100644 --- a/TODO +++ b/TODO @@ -5,4 +5,11 @@ * Allow to use GTK's main loop instead of the select stuff in wait.c -* add locking to the key cache? \ No newline at end of file +* add locking to the key cache? + +* Should --delete silently delete secret keys or is there a need for + another flag or a callback? + +* There is no status response if we have no usable recipients - must + add one to gpg so that gpgme_encrypt does return with an error. + diff --git a/complus/Makefile.am b/complus/Makefile.am index 45c3dc42..1965b9ff 100644 --- a/complus/Makefile.am +++ b/complus/Makefile.am @@ -24,7 +24,7 @@ # system with an install MIDL and run the command # midl /nocpp gpgcom.idl # Sorry, there is no other way yet. -EXTRA_DIST = gpgcom.idl gpgcom.tlb gpgcom.rc vbtest.html vbtest.vbs +EXTRA_DIST = gpgcom.idl gpgcom.tlb gpgcom.rc vbtest.html vbtest.vbs README # No need to install this because we are cross-compiling anyway. noinst_PROGRAMS = gpgcom tgpgcom diff --git a/complus/README b/complus/README new file mode 100644 index 00000000..30fc30d9 --- /dev/null +++ b/complus/README @@ -0,0 +1,72 @@ + How to install and use the Gpgcom Windows Component + =================================================== + 2001-07-31 + + +Installation should be pretty easy: +----------------------------------- + + * Get and install the latest GnuPG binary for windows + (ftp://ftp.gnupg.org/gcrypt/binary/gnupg-w32-1.0.6.zip) + + * Check that you have an untampered version of this package by + comparing an MD5SUM against the one on the webpage or by checking + the signature of the package using "gpg --verify". See the + webpacge for details. + + * Because you are reading this file, you probably have already + unpacked it distribution using a unzip utility :-). You should + find these files: + + README - This file + gpgcom.exe - The Gpgcom server + vbtest.html - A Test webpage + vbtest.vbs - A VB script to be used with the cscript utility + + * If you are updating Gpgcom, run the old Gpgcom like this: + + c:\gnupg\gpgcom -UnregServer + + (Replace c:\gnupg with the actually used path) + + * Copy the file gpgcom.exe to a some location. C:\gnupg seems to be + a good choice. + + * Register the component using this command: + + c:\gnupg\gpgcom -RegServer + + * Ready + +Testing the installation: +------------------------- + + * Make sure that you have a working GnuPG (gpg.exe) and that at least + one key is installed. + + * Edit the vbtest.vbs script and replace "alice" in the line + + gpg.AddRecipient "alice" + + with a keyID or user name you have in your key ring. + + * Run the test script: + + cscript vbtest.vbs + + and you should see a valid MIME message with the encrypted text. + + +Using Gpgcom +------------ + +Gpgcom currently support only encryption but will be extended to the +full range of operations GnuPG provides. The 2 examples should goive +yopu a hint on how to use it. We suggest that you always set armor to +true, so that the returned text is a string. IF you don't use armor, +the "ciphertext" property will return an array with the binary +message. + + + + diff --git a/configure.in b/configure.in index 0bf7855b..e2714f0d 100644 --- a/configure.in +++ b/configure.in @@ -32,6 +32,7 @@ AM_MAINTAINER_MODE # 3. Interfaces removed (BAD, breaks upward compatibility): Increment # CURRENT, set AGE and REVISION to 0. AM_INIT_AUTOMAKE(gpgme,0.2.2a) +# --> New functions introduced <---- LIBGPGME_LT_CURRENT=3 LIBGPGME_LT_AGE=3 LIBGPGME_LT_REVISION=1 @@ -178,7 +179,6 @@ echo " GPG version: min. $NEED_GPG_VERSION GPG path: $GPG - Component: $component_system " diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 1c5261bb..8ca3caa0 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,30 @@ +2001-07-31 Werner Koch + + * encrypt.c (gpgme_op_encrypt): Hack to detect no valid recipients. + +2001-07-30 Werner Koch + + * gpgme.c (gpgme_get_armor,gpgme_get_texmode): New. + + * rungpg.c (build_argv): Disable armor comments + * w32-io.c (build_commandline): Need to add quotes here + +2001-07-24 Werner Koch + + * data.c (gpgme_data_read): Add a a way to return the available bytes. + +2001-07-23 Werner Koch + + * util.c: Removed stpcpy() because we use the version from jnlib. + +2001-07-19 Werner Koch + + * mkstatus: Define the collating sequence for sort. + +2001-06-26 Werner Koch + + * rungpg.h: Add STATUS_UNEXPECTED as suggested by Timo. + 2001-06-15 Werner Koch * keylist.c (set_userid_flags): Fixed the assigned values. Kudos diff --git a/gpgme/data.c b/gpgme/data.c index f234c50f..b4cde8e5 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -439,6 +439,11 @@ gpgme_data_rewind ( GpgmeData dh ) * are copied and the actual number of bytes are returned in @nread. * If there are no more bytes available %GPGME_EOF is returned and @nread * is set to 0. + * + * With a @buffer of NULL, the function does only return the number of + * bytes available and does not move the read pointer. This does only + * work for certain data types, all other will respnd with an + * %GPGME_Invalid_Type. * * Return value: An errorcode or 0 on success, EOF is indcated by the * error code GPGME_EOF. @@ -456,13 +461,22 @@ gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread ) *nread = 0; return mk_error(EOF); } - if (nbytes > length) - nbytes = length; - memcpy ( buffer, dh->data + dh->readpos, nbytes ); - *nread = nbytes; - dh->readpos += nbytes; + if (!buffer) { + *nread = nbytes; + } + else { + if (nbytes > length) + nbytes = length; + memcpy ( buffer, dh->data + dh->readpos, nbytes ); + *nread = nbytes; + dh->readpos += nbytes; + } } else if (dh->type == GPGME_DATA_TYPE_CB) { + if (!buffer) { + *nread = 0; + return mk_error (Invalid_Type); + } nbytes = dh->len - dh->readpos; if ( nbytes ) { /* we have unread data - return this */ diff --git a/gpgme/encrypt.c b/gpgme/encrypt.c index 3fe60a62..bff4153d 100644 --- a/gpgme/encrypt.c +++ b/gpgme/encrypt.c @@ -70,7 +70,7 @@ gpgme_op_encrypt_start ( GpgmeCtx c, GpgmeRecipients recp, for ( i=0; i < c->verbosity; i++ ) _gpgme_gpg_add_arg ( c->gpg, "--verbose" ); /* If we know that all recipients are valid (full or ultimate trust) - * we can pass suppress further checks */ + * we can suppress further checks */ if ( _gpgme_recipients_all_valid (recp) ) _gpgme_gpg_add_arg ( c->gpg, "--always-trust" ); @@ -127,6 +127,12 @@ gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp, if ( !rc ) { gpgme_wait (c, 1); c->pending = 0; + /* FIXME: gpg does not return status info for invalid + * recipients, so we simply check whether we got any output at + * all and if not assume that we don't have valid recipients + * */ + if (gpgme_data_get_type (out) == GPGME_DATA_TYPE_NONE) + rc = mk_error (No_Recipients); } return rc; } diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 1c6ffae5..b473feb6 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -152,6 +152,23 @@ gpgme_set_armor ( GpgmeCtx c, int yes ) c->use_armor = yes; } + +/** + * gpgme_get_armor: + * @c: the context + * + * Return the state of the armor flag which can be changed using + * gpgme_set_armor(). + * + * Return value: Boolean whether armor mode is to be used. + **/ +int +gpgme_get_armor (GpgmeCtx c) +{ + return c && c->use_armor; +} + + /** * gpgme_set_textmode: * @c: the context @@ -168,6 +185,23 @@ gpgme_set_textmode ( GpgmeCtx c, int yes ) c->use_textmode = yes; } +/** + * gpgme_get_textmode: + * @c: the context + * + * Return the state of the textmode flag which can be changed using + * gpgme_set_textmode(). + * + * Return value: Boolean whether textmode is to be used. + **/ +int +gpgme_get_textmode (GpgmeCtx c) +{ + return c && c->use_textmode; +} + + + /** * gpgme_set_keylist_mode: * @c: the context diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 0f04b4b3..d4082d2f 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -44,7 +44,7 @@ extern "C" { * let autoconf (using the AM_PATH_GPGME macro) check that this * header matches the installed library. * Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "0.2.2" +#define GPGME_VERSION "0.2.2a" @@ -168,7 +168,9 @@ GpgmeCtx gpgme_wait (GpgmeCtx c, int hang); char *gpgme_get_notation (GpgmeCtx c); void gpgme_set_armor (GpgmeCtx c, int yes); +int gpgme_get_armor (GpgmeCtx c); void gpgme_set_textmode (GpgmeCtx c, int yes); +int gpgme_get_textmode (GpgmeCtx c); void gpgme_set_keylist_mode ( GpgmeCtx c, int mode ); void gpgme_set_passphrase_cb (GpgmeCtx c, GpgmePassphraseCb cb, void *cb_value); diff --git a/gpgme/mkstatus b/gpgme/mkstatus index 150313d1..08bed641 100755 --- a/gpgme/mkstatus +++ b/gpgme/mkstatus @@ -20,6 +20,11 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# resetting collate is important, so that the bsearch works properly +LC_ALL=C +LC_COLLATE=C +export LC_ALL LC_COLLATE + cat <cmd.used) argc++; + argc += 2; /* --comment */ argv = xtrycalloc ( argc+1, sizeof *argv ); if (!argv) @@ -651,6 +652,20 @@ build_argv ( GpgObject gpg ) } argc++; } + argv[argc] = xtrystrdup ( "--comment" ); + if (!argv[argc]) { + xfree (fd_data_map); + free_argv (argv); + return mk_error (Out_Of_Core); + } + argc++; + argv[argc] = xtrystrdup ( "" ); + if (!argv[argc]) { + xfree (fd_data_map); + free_argv (argv); + return mk_error (Out_Of_Core); + } + argc++; for ( a=gpg->arglist; a; a = a->next ) { if ( a->data ) { switch ( _gpgme_data_get_mode (a->data) ) { diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h index 2895a83a..6323d591 100644 --- a/gpgme/rungpg.h +++ b/gpgme/rungpg.h @@ -49,6 +49,7 @@ typedef enum { STATUS_SHM_GET_HIDDEN , STATUS_NEED_PASSPHRASE , STATUS_USERID_HINT , + STATUS_UNEXPECTED , STATUS_VALIDSIG , STATUS_SIG_ID , STATUS_ENC_TO , diff --git a/gpgme/util.c b/gpgme/util.c index 1d777a5d..0c267fe7 100644 --- a/gpgme/util.c +++ b/gpgme/util.c @@ -62,19 +62,5 @@ _gpgme_free ( void *a ) -/********************************************* - ********** missing string functions ********* - *********************************************/ -#ifndef HAVE_STPCPY -char * -stpcpy (char *a, const char *b) -{ - while( *b ) - *a++ = *b++; - *a = 0; - - return a; -} -#endif diff --git a/gpgme/version.c b/gpgme/version.c index 74b6576d..5c486f20 100644 --- a/gpgme/version.c +++ b/gpgme/version.c @@ -124,7 +124,7 @@ compare_versions ( const char *my_version, const char *req_version ) * and return the version string; return NULL if the condition is not * met. If a NULL is passed to this function, no check is done and * the version string is simply returned. It is a pretty good idea to - * run this function as soon as poossible, becuase it also intializes + * run this function as soon as possible, because it also intializes * some subsystems. In a multithreaded environment if should be called * before the first thread is created. * diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 89e0dd3a..de7e6704 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -770,15 +770,19 @@ build_commandline ( char **argv ) /* FIXME: we have to quote some things because under Windows the * program parses the commandline and does some unquoting */ for (i=0; argv[i]; i++) - n += strlen (argv[i]) + 1; + n += strlen (argv[i]) + 2 + 1; /* 2 extra bytes for possible quoting */ buf = p = xtrymalloc (n); if ( !buf ) return NULL; *buf = 0; if ( argv[0] ) p = stpcpy (p, argv[0]); - for (i = 1; argv[i]; i++) - p = stpcpy (stpcpy (p, " "), argv[i]); + for (i = 1; argv[i]; i++) { + if (!*argv[i]) + p = stpcpy (p, " \"\""); + else + p = stpcpy (stpcpy (p, " "), argv[i]); + } return buf; } diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index b9a1c2bb..93253685 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,8 @@ +2001-07-19 Werner Koch + + * stringhelp.c (ascii_memistr,ascii_isupper,ascii_islower, + ascii_toupper,ascii_tolower, ascii_strcasecmp, ascii_memcasecmp): New. + 2000-07-26 10:02:51 Werner Koch (wk@habibti.openit.de) * stringhelp.c.: Add stdarg.h diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index f222a627..0d3035e8 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -264,6 +264,79 @@ compare_filenames( const char *a, const char *b ) } +/**************************************************** + ******** locale insensitive ctype functions ******** + ****************************************************/ +/* FIXME: replace them by a table lookup and macros */ +int +ascii_isupper (int c) +{ + return c >= 'A' && c <= 'Z'; +} + +int +ascii_islower (int c) +{ + return c >= 'a' && c <= 'z'; +} + +int +ascii_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + c &= ~0x20; + return c; +} + +int +ascii_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + c |= 0x20; + return c; +} + + +int +ascii_strcasecmp( const char *a, const char *b ) +{ + if (a == b) + return 0; + + for (; *a && *b; a++, b++) { + if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b)) + break; + } + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); +} + +int +ascii_memcasecmp( const char *a, const char *b, size_t n ) +{ + if (a == b) + return 0; + for ( ; n; n--, a++, b++ ) { + if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); + } + return 0; +} + +int +ascii_strcmp( const char *a, const char *b ) +{ + if (a == b) + return 0; + + for (; *a && *b; a++, b++) { + if (*a != *b ) + break; + } + return *a == *b? 0 : (*(signed char *)a - *(signed char *)b); +} + + + /********************************************* ********** missing string functions ********* *********************************************/ diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 5d124e40..17a6ad09 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -37,6 +37,15 @@ char *make_dirname(const char *filepath); char *make_filename( const char *first_part, ... ); int compare_filenames( const char *a, const char *b ); +const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); +int ascii_isupper (int c); +int ascii_islower (int c); +int ascii_toupper (int c); +int ascii_tolower (int c); +int ascii_strcasecmp( const char *a, const char *b ); +int ascii_memcasecmp( const char *a, const char *b, size_t n ); + + #ifndef HAVE_MEMICMP int memicmp( const char *a, const char *b, size_t n ); #endif