diff --git a/g10/ChangeLog b/g10/ChangeLog index 339906acb..3f91ee5df 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,16 @@ +2003-02-26 David Shaw + + * keyserver.c (keyserver_spawn): Include various pieces of + information about the key in the data sent to the keyserver + helper. This allows the helper to use it in instructing a remote + server which may not have any actual OpenPGP smarts in parsing + keys. + + * main.h, export.c (export_pubkeys_stream, do_export_stream): Add + ability to return only the first match in an exported keyblock for + keyserver usage. This should be replaced at some point with a + more flexible solution where each key can be armored seperately. + 2003-02-22 David Shaw * sign.c (sign_file): Do not push textmode filter onto an unopened diff --git a/g10/export.c b/g10/export.c index c56888265..b1bec1f1c 100644 --- a/g10/export.c +++ b/g10/export.c @@ -35,8 +35,9 @@ #include "i18n.h" static int do_export( STRLIST users, int secret, unsigned int options ); -static int do_export_stream( IOBUF out, STRLIST users, - int secret, unsigned int options, int *any ); +static int do_export_stream( IOBUF out, STRLIST users, int secret, + KBNODE *keyblock_out, unsigned int options, + int *any ); int parse_export_options(char *str,unsigned int *options) @@ -103,11 +104,12 @@ export_pubkeys( STRLIST users, unsigned int options ) * been exported */ int -export_pubkeys_stream( IOBUF out, STRLIST users, unsigned int options ) +export_pubkeys_stream( IOBUF out, STRLIST users, + KBNODE *keyblock_out, unsigned int options ) { int any, rc; - rc = do_export_stream( out, users, 0, options, &any ); + rc = do_export_stream( out, users, 0, keyblock_out, options, &any ); if( !rc && !any ) rc = -1; return rc; @@ -146,7 +148,7 @@ do_export( STRLIST users, int secret, unsigned int options ) } if( opt.compress_keys && opt.compress ) iobuf_push_filter( out, compress_filter, &zfx ); - rc = do_export_stream( out, users, secret, options, &any ); + rc = do_export_stream( out, users, secret, NULL, options, &any ); if( rc || !any ) iobuf_cancel(out); @@ -156,9 +158,12 @@ do_export( STRLIST users, int secret, unsigned int options ) } +/* If keyblock_out is non-NULL, AND the exit code is zero, then it + contains a pointer to the first keyblock found and exported. No + other keyblocks are exported. The caller must free it. */ static int do_export_stream( IOBUF out, STRLIST users, int secret, - unsigned int options, int *any ) + KBNODE *keyblock_out, unsigned int options, int *any ) { int rc = 0; PACKET pkt; @@ -408,6 +413,11 @@ do_export_stream( IOBUF out, STRLIST users, int secret, } } ++*any; + if(keyblock_out) + { + *keyblock_out=keyblock; + break; + } } if( rc == -1 ) rc = 0; @@ -415,7 +425,8 @@ do_export_stream( IOBUF out, STRLIST users, int secret, leave: m_free(desc); keydb_release (kdbhd); - release_kbnode( keyblock ); + if(rc || keyblock_out==NULL) + release_kbnode( keyblock ); if( !*any ) log_info(_("WARNING: nothing exported\n")); return rc; diff --git a/g10/keyserver.c b/g10/keyserver.c index ed7883d47..b153bc49a 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -801,6 +801,7 @@ keyserver_spawn(int action,STRLIST list, { armor_filter_context_t afx; IOBUF buffer=iobuf_temp(); + KBNODE block; temp=NULL; add_to_strlist(&temp,key->d); @@ -809,19 +810,84 @@ keyserver_spawn(int action,STRLIST list, afx.what=1; iobuf_push_filter(buffer,armor_filter,&afx); - if(export_pubkeys_stream(buffer,temp, + /* TODO: Don't use the keyblock hack here - instead, + output each key as a different ascii armored blob with + its own INFO section. */ + + if(export_pubkeys_stream(buffer,temp,&block, opt.keyserver_options.export_options)==-1) iobuf_close(buffer); else { + KBNODE node; + iobuf_flush_temp(buffer); + merge_keys_and_selfsig(block); + + fprintf(spawn->tochild,"INFO %s BEGIN\n",key->d); + + for(node=block;node;node=node->next) + { + switch(node->pkt->pkttype) + { + default: + continue; + + case PKT_PUBLIC_KEY: + case PKT_PUBLIC_SUBKEY: + { + PKT_public_key *pk=node->pkt->pkt.public_key; + + keyid_from_pk(pk,NULL); + + fprintf(spawn->tochild,"%sb:%08lX%08lX:%u:%u:%u:%u:", + node->pkt->pkttype==PKT_PUBLIC_KEY?"pu":"su", + (ulong)pk->keyid[0],(ulong)pk->keyid[1], + pk->pubkey_algo, + nbits_from_pk(pk), + pk->timestamp, + pk->expiredate); + + if(pk->is_revoked) + fprintf(spawn->tochild,"r"); + if(pk->has_expired) + fprintf(spawn->tochild,"e"); + + fprintf(spawn->tochild,"\n"); + + break; + } + + case PKT_USER_ID: + { + PKT_user_id *uid=node->pkt->pkt.user_id; + + if(uid->attrib_data) + continue; + + fprintf(spawn->tochild,"uid:%s:%u:%u:", + uid->name,uid->created,uid->expiredate); + + if(uid->is_revoked) + fprintf(spawn->tochild,"r"); + if(uid->is_expired) + fprintf(spawn->tochild,"e"); + + fprintf(spawn->tochild,"\n"); + } + } + } + + fprintf(spawn->tochild,"INFO %s END\n",key->d); + fprintf(spawn->tochild,"KEY %s BEGIN\n",key->d); fwrite(iobuf_get_temp_buffer(buffer), iobuf_get_temp_length(buffer),1,spawn->tochild); fprintf(spawn->tochild,"KEY %s END\n",key->d); iobuf_close(buffer); + release_kbnode(block); } free_strlist(temp); diff --git a/g10/main.h b/g10/main.h index c41d783ff..fa7adf06a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -184,7 +184,8 @@ int collapse_uids( KBNODE *keyblock ); int parse_export_options(char *str,unsigned int *options); int export_pubkeys( STRLIST users, unsigned int options ); -int export_pubkeys_stream( IOBUF out, STRLIST users, unsigned int options ); +int export_pubkeys_stream( IOBUF out, STRLIST users, + KBNODE *keyblock_out, unsigned int options ); int export_seckeys( STRLIST users ); int export_secsubkeys( STRLIST users );