From c8def6ecfa7fab89b09edb55fc4cef0859e241d9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 18 May 2000 09:30:29 +0000 Subject: [PATCH] See ChangeLog: Thu May 18 11:38:54 CEST 2000 Werner Koch --- NEWS | 5 ++++ cipher/ChangeLog | 6 ++++ cipher/dsa.c | 18 +++++++++++- cipher/elgamal.c | 17 ++++++++++- cipher/primegen.c | 15 +++++++++- doc/DETAILS | 12 ++++++++ doc/HACKING | 66 +++++++++++++++++++++++++++++++++++++++++ doc/gpg.sgml | 10 +++++++ g10/ChangeLog | 14 +++++++++ g10/g10.c | 4 +++ g10/keyedit.c | 2 +- g10/options.h | 1 + g10/status.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++ g10/status.h | 5 ++++ include/cipher.h | 4 +++ 15 files changed, 250 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 05ebc1c2e..9b799923a 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,11 @@ Noteworthy changes in the current test release as default to the one in the homedirectory. Prior versions ignored all --keyring options. + * New option --command-fd to take user input from a file descriptor; + to be used with --status-fd by software which uses GnuPG as a backend. + + * There is a new status PROGRESS which is used to show progress during + key generation. Noteworthy changes in version 1.0.1 (1999-12-16) ----------------------------------- diff --git a/cipher/ChangeLog b/cipher/ChangeLog index fd8888d10..7507454de 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,9 @@ +Thu May 18 11:38:54 CEST 2000 Werner Koch + + * primegen.c (register_primegen_progress): New. + * dsa.c (register_pk_dsa_progress): New. + * elgamal.c (register_pk_elg_progress): New. + Fri Apr 14 19:37:08 CEST 2000 Werner Koch * twofish.c (twofish_get_info): Fixed warning about cast. diff --git a/cipher/dsa.c b/cipher/dsa.c index 5828b9508..d7c4f6892 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -52,13 +52,29 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ); static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey); static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey); + +static void (*progress_cb) ( void *, int ); +static void *progress_cb_data; + +void +register_pk_dsa_progress ( void (*cb)( void *, int), void *cb_data ) +{ + progress_cb = cb; + progress_cb_data = cb_data; +} + + static void progress( int c ) { - fputc( c, stderr ); + if ( progress_cb ) + progress_cb ( progress_cb_data, c ); + else + fputc( c, stderr ); } + /**************** * Generate a random secret exponent k less than q */ diff --git a/cipher/elgamal.c b/cipher/elgamal.c index f968a29d4..74e159684 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -56,12 +56,27 @@ static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey); static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey); +static void (*progress_cb) ( void *, int ); +static void *progress_cb_data; + +void +register_pk_elg_progress ( void (*cb)( void *, int), void *cb_data ) +{ + progress_cb = cb; + progress_cb_data = cb_data; +} + + static void progress( int c ) { - fputc( c, stderr ); + if ( progress_cb ) + progress_cb ( progress_cb_data, c ); + else + fputc( c, stderr ); } + /**************** * Michael Wiener's table about subgroup sizes to match field sizes * (floating around somewhere - Fixme: need a reference) diff --git a/cipher/primegen.c b/cipher/primegen.c index 57160b2a3..b6c569de7 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -38,11 +38,24 @@ static int check_prime( MPI prime, MPI val_2 ); static int is_prime( MPI n, int steps, int *count ); static void m_out_of_n( char *array, int m, int n ); +static void (*progress_cb) ( void *, int ); +static void *progress_cb_data; + +void +register_primegen_progress ( void (*cb)( void *, int), void *cb_data ) +{ + progress_cb = cb; + progress_cb_data = cb_data; +} + static void progress( int c ) { - fputc( c, stderr ); + if ( progress_cb ) + progress_cb ( progress_cb_data, c ); + else + fputc( c, stderr ); } diff --git a/doc/DETAILS b/doc/DETAILS index 46c7e9dfe..ecb3d009a 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -134,6 +134,11 @@ more arguments in future versions. SHM_GET_BOOL SHM_GET_HIDDEN + GET_BOOL + GET_LINE + GET_HIDDEN + GOT_IT + NEED_PASSPHRASE Issued whenever a passphrase is needed. keytype is the numerical value of the public key algorithm @@ -204,6 +209,13 @@ more arguments in future versions. 1 - No such key 2 - Must delete secret key first + PROGRESS what char cur total + Used by the primegen and Public key functions to indicate progress. + "char" is the character displayed with no --status-fd enabled, with + the linefeed replaced by an 'X'. "cur" is the current amount + done and "total" is amount to be done; a "total" of 0 indicates that + the toatal amount is not known. 100/100 may be used to detect the + end of operation. Key generation diff --git a/doc/HACKING b/doc/HACKING index 2f4de27d3..70bfe65dd 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -112,6 +112,72 @@ Directory Layout ./gcrypt Stuff needed to build libgcrypt (under construction) +Detailed Roadmap +---------------- +g10/g10.c Main module with option parsing and all the stuff you have + to do on startup. Also has the exout handler and some + helper functions. +g10/sign.c + +g10/parse-packet.c +g10/build-packet.c +g10/free-packet.c + Parsing and creating of OpenPGP message packets. + +g10/getkey.c +g10/pkclist.c +g10/skclist.c +g10/ringedit.c +g10/keydb.h + +g10/keyid.c Helper functions to get the keyid, fingerprint etc. + + +g10/trustdb.c +g10/trustdb.h +g10/tdbdump.c + +g10/compress.c +g10/filter.h +g10/delkey.c +g10/kbnode.c +g10/main.h +g10/mainproc.c +g10/armor.c +g10/mdfilter.c +g10/textfilter.c +g10/cipher.c +g10/misc.c +g10/options.h +g10/openfile.c +g10/tdbio.c +g10/tdbio.h +g10/hkp.h +g10/hkp.c +g10/packet.h +g10/passphrase.c +g10/pubkey-enc.c +g10/seckey-cert.c +g10/seskey.c +g10/import.c +g10/export.c +g10/comment.c +g10/status.c +g10/status.h +g10/sign.c +g10/plaintext.c +g10/encr-data.c +g10/encode.c +g10/revoke.c +g10/keylist.c +g10/sig-check.c +g10/signal.c +g10/helptext.c +g10/verify.c +g10/decrypt.c +g10/keyedit.c +g10/dearmor.c +g10/keygen.c diff --git a/doc/gpg.sgml b/doc/gpg.sgml index 0871b77c6..3ff12a4c7 100644 --- a/doc/gpg.sgml +++ b/doc/gpg.sgml @@ -1108,6 +1108,16 @@ can only be used if only one passphrase is supplied. Don't use this option if you can avoid it. + +--command-fd &ParmN; + +This is a replacement for the depreciated shared-memory IPC mode. +If this option is enabled, user input on questions is not expected +from the TTY but from the given file descriptor. It should be used +together with --status-fd. See the file doc/DETAILS in the source +distribution for details on how to use it. + + --rfc1991 diff --git a/g10/ChangeLog b/g10/ChangeLog index 5a0647f6c..6d19d7e0e 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,17 @@ +Thu May 18 11:38:54 CEST 2000 Werner Koch + + * keyedit.c (keyedit_menu): Add a keyword arg to the prompt. + + * status.c, status.h: Added 3 new status tokens. + * status.c (do_get_from_fd): New. + (cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt, + cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work + with the new function. + * g10.c: Add new option --command-fd. + + * status.c (progress_cb): New. + (set_status_fd): Register progress functions + Fri May 12 14:01:20 CEST 2000 Werner Koch * delkey.c (delete_key): Add 2 new status messages diff --git a/g10/g10.c b/g10/g10.c index 33b6c33c5..e545b9e8c 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -133,6 +133,7 @@ enum cmd_and_opt_values { aNull = 0, oDigestAlgo, oCompressAlgo, oPasswdFD, + oCommandFD, oQuickRandom, oNoVerbose, oTrustDBName, @@ -316,6 +317,7 @@ static ARGPARSE_OPTS opts[] = { { aListTrustPath, "list-trust-path",0, "@"}, { oKOption, NULL, 0, "@"}, { oPasswdFD, "passphrase-fd",1, "@" }, + { oCommandFD, "command-fd",1, "@" }, { oQuickRandom, "quick-random", 0, "@"}, { oNoVerbose, "no-verbose", 0, "@"}, { oTrustDBName, "trustdb-name", 2, "@" }, @@ -596,6 +598,7 @@ main( int argc, char **argv ) init_signals(); create_dotlock(NULL); /* register locking cleanup */ i18n_init(); + opt.command_fd = -1; /* no command fd */ opt.compress = -1; /* defaults to standard compress level */ /* note: if you change these lines, look at oOpenPGP */ opt.def_cipher_algo = 0; @@ -873,6 +876,7 @@ main( int argc, char **argv ) break; case oCompress: opt.compress = pargs.r.ret_int; break; case oPasswdFD: pwfd = pargs.r.ret_int; break; + case oCommandFD: opt.command_fd = pargs.r.ret_int; break; case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break; case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break; case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; diff --git a/g10/keyedit.c b/g10/keyedit.c index 2a1b26af8..cd297db60 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -694,7 +694,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, have_commands = 0; } if( !have_commands ) { - answer = cpr_get("", _("Command> ")); + answer = cpr_get("keyedit.prompt", _("Command> ")); cpr_kill_prompt(); } trim_spaces(answer); diff --git a/g10/options.h b/g10/options.h index c0394f608..b3bdc8a34 100644 --- a/g10/options.h +++ b/g10/options.h @@ -88,6 +88,7 @@ struct { int honor_http_proxy; int fast_list_mode; int ignore_time_conflict; + int command_fd; } opt; diff --git a/g10/status.c b/g10/status.c index 23bb7deca..38f2c145f 100644 --- a/g10/status.c +++ b/g10/status.c @@ -44,6 +44,7 @@ #include "options.h" #include "main.h" #include "i18n.h" +#include "cipher.h" /* for progress functions */ static int fd = -1; #ifdef USE_SHM_COPROCESSING @@ -53,10 +54,29 @@ static int fd = -1; static int shm_is_locked; #endif /*USE_SHM_COPROCESSING*/ + +static void +progress_cb ( void *ctx, int c ) +{ + char buf[50]; + + if ( c == '\n' ) + sprintf ( buf, "%.20s X 100 100", (char*)ctx ); + else + sprintf ( buf, "%.20s %c 0 0", (char*)ctx, c ); + write_status_text ( STATUS_PROGRESS, buf ); +} + + void set_status_fd ( int newfd ) { fd = newfd; + if ( fd != -1 ) { + register_primegen_progress ( progress_cb, "primegen" ); + register_pk_dsa_progress ( progress_cb, "pk_dsa" ); + register_pk_elg_progress ( progress_cb, "pk_elg" ); + } } int @@ -95,6 +115,10 @@ write_status_text ( int no, const char *text) case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL\n"; break; case STATUS_TRUST_FULLY : s = "TRUST_FULLY\n"; break; case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE\n"; break; + case STATUS_GET_BOOL : s = "GET_BOOL\n"; break; + case STATUS_GET_LINE : s = "GET_LINE\n"; break; + case STATUS_GET_HIDDEN : s = "GET_HIDDEN\n"; break; + case STATUS_GOT_IT : s = "GOT_IT\n"; break; case STATUS_SHM_INFO : s = "SHM_INFO\n"; break; case STATUS_SHM_GET : s = "SHM_GET\n"; break; case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL\n"; break; @@ -125,6 +149,7 @@ write_status_text ( int no, const char *text) case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION\n"; break; case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION\n"; break; case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM\n"; break; + case STATUS_PROGRESS : s = "PROGRESS\n"; break; default: s = "?\n"; break; } @@ -276,10 +301,50 @@ do_shm_get( const char *keyword, int hidden, int bool ) #endif /* USE_SHM_COPROCESSING */ +/**************** + * Request a string from the client over the command-fd + * If bool, returns static string on true (do not free) or NULL for false + */ +static char * +do_get_from_fd( const char *keyword, int hidden, int bool ) +{ + int i, len; + char *string; + + write_status_text( bool? STATUS_GET_BOOL : + hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword ); + + for( string = NULL, i = len = 200; ; i++ ) { + if( i >= len-1 ) { + char *save = string; + len += 100; + string = hidden? m_alloc_secure ( len ) : m_alloc ( len ); + if( save ) + memcpy(string, save, i ); + else + i=0; + } + /* Hmmm: why not use our read_line function here */ + if( read( fd, string+i, 1) != 1 || string[i] == '\n' ) + break; + } + string[i] = 0; + + write_status( STATUS_GOT_IT ); + + if( bool ) /* Fixme: is this correct??? */ + return string[0] == 'Y' ? "" : NULL; + + return string; +} + + int cpr_enabled() { + if( opt.command_fd != -1 ) + return 1; #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return 1; @@ -292,6 +357,8 @@ cpr_get( const char *keyword, const char *prompt ) { char *p; + if( opt.command_fd != -1 ) + return do_get_from_fd ( keyword, 0, 0 ); #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return do_shm_get( keyword, 0, 0 ); @@ -325,6 +392,8 @@ cpr_get_hidden( const char *keyword, const char *prompt ) { char *p; + if( opt.command_fd != -1 ) + return do_get_from_fd ( keyword, 1, 0 ); #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return do_shm_get( keyword, 1, 0 ); @@ -343,6 +412,8 @@ cpr_get_hidden( const char *keyword, const char *prompt ) void cpr_kill_prompt(void) { + if( opt.command_fd != -1 ) + return; #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return; @@ -357,6 +428,8 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt ) int yes; char *p; + if( opt.command_fd != -1 ) + return !!do_get_from_fd ( keyword, 0, 1 ); #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return !!do_shm_get( keyword, 0, 1 ); @@ -383,6 +456,8 @@ cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt ) int yes; char *p; + if( opt.command_fd != -1 ) + return !!do_get_from_fd ( keyword, 0, 1 ); #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return !!do_shm_get( keyword, 0, 1 ); diff --git a/g10/status.h b/g10/status.h index 3581fd767..667565560 100644 --- a/g10/status.h +++ b/g10/status.h @@ -75,6 +75,11 @@ #define STATUS_END_ENCRYPTION 44 #define STATUS_DELETE_PROBLEM 45 +#define STATUS_GET_BOOL 46 +#define STATUS_GET_LINE 47 +#define STATUS_GET_HIDDEN 48 +#define STATUS_GOT_IT 49 +#define STATUS_PROGRESS 50 /*-- status.c --*/ void set_status_fd ( int fd ); diff --git a/include/cipher.h b/include/cipher.h index a3f0eeba2..bf2010fe0 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -168,10 +168,14 @@ int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, extern ushort small_prime_numbers[]; /*-- primegen.c --*/ +void register_primegen_progress ( void (*cb)( void *, int), void *cb_data ); MPI generate_secret_prime( unsigned nbits ); MPI generate_public_prime( unsigned nbits ); MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, MPI g, MPI **factors ); +/*-- elsewhere --*/ +void register_pk_dsa_progress ( void (*cb)( void *, int), void *cb_data ); +void register_pk_elg_progress ( void (*cb)( void *, int), void *cb_data ); #endif /*G10_CIPHER_H*/