diff options
-rw-r--r-- | g10/Makefile.am | 4 | ||||
-rw-r--r-- | g10/g10.c | 72 | ||||
-rw-r--r-- | g10/gpgv.c | 3 | ||||
-rw-r--r-- | g10/hkp.c | 479 | ||||
-rw-r--r-- | g10/hkp.h | 4 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/mainproc.c | 6 | ||||
-rw-r--r-- | g10/options.h | 16 | ||||
-rw-r--r-- | g10/options.skel | 74 |
9 files changed, 462 insertions, 197 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am index 9828da796..7251cf645 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -86,7 +86,9 @@ gpg_SOURCES = g10.c \ delkey.c \ keygen.c \ pipemode.c \ - helptext.c + helptext.c \ + keyserver.c \ + keyserver-internal.h gpgv_SOURCES = gpgv.c \ $(common_source) \ @@ -48,7 +48,7 @@ #include "i18n.h" #include "status.h" #include "g10defs.h" -#include "hkp.h" +#include "keyserver-internal.h" enum cmd_and_opt_values { aNull = 0, oArmor = 'a', @@ -92,6 +92,7 @@ enum cmd_and_opt_values { aNull = 0, aListSecretKeys, aSendKeys, aRecvKeys, + aSearchKeys, aExport, aExportAll, aExportSecret, @@ -193,6 +194,8 @@ enum cmd_and_opt_values { aNull = 0, oLockMultiple, oLockNever, oKeyServer, + oKeyServerOptions, + oTempDir, oEncryptTo, oNoEncryptTo, oLoggerFD, @@ -218,6 +221,7 @@ enum cmd_and_opt_values { aNull = 0, oShowSessionKey, oOverrideSessionKey, oNoRandomSeedFile, + oAutoKeyRetrieve, oNoAutoKeyRetrieve, oUseAgent, oMergeOnly, @@ -265,6 +269,8 @@ static ARGPARSE_OPTS opts[] = { { aExport, "export" , 256, N_("export keys") }, { aSendKeys, "send-keys" , 256, N_("export keys to a key server") }, { aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") }, + { aSearchKeys, "search-keys" , 256, + N_("search for keys on a key server") }, { aRefreshKeys, "refresh-keys", 256, N_("update all keys from a keyserver")}, { aExportAll, "export-all" , 256, "@" }, @@ -301,6 +307,7 @@ static ARGPARSE_OPTS opts[] = { { oDefRecipientSelf, "default-recipient-self" ,0, N_("use the default key as default recipient")}, { oNoDefRecipient, "no-default-recipient", 0, "@" }, + { oTempDir, "temp-directory", 2, "@" }, { oEncryptTo, "encrypt-to", 2, "@" }, { oNoEncryptTo, "no-encrypt-to", 0, "@" }, { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, @@ -326,6 +333,7 @@ static ARGPARSE_OPTS opts[] = { { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")}, + { oKeyServerOptions, "keyserver-options",2,"@"}, { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") }, { oOptions, "options" , 2, N_("read options from file")}, @@ -437,6 +445,7 @@ static ARGPARSE_OPTS opts[] = { { oShowSessionKey, "show-session-key", 0, "@" }, { oOverrideSessionKey, "override-session-key", 2, "@" }, { oNoRandomSeedFile, "no-random-seed-file", 0, "@" }, + { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" }, { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" }, { oNoSigCache, "no-sig-cache", 0, "@" }, { oNoSigCreateCheck, "no-sig-create-check", 0, "@" }, @@ -707,7 +716,6 @@ main( int argc, char **argv ) opt.marginals_needed = 3; opt.max_cert_depth = 5; opt.pgp2_workarounds = 1; - opt.auto_key_retrieve = 1; #ifdef __MINGW32__ opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" ); #else @@ -811,6 +819,7 @@ main( int argc, char **argv ) case aFastImport: set_cmd( &cmd, aFastImport); break; case aSendKeys: set_cmd( &cmd, aSendKeys); break; case aRecvKeys: set_cmd( &cmd, aRecvKeys); break; + case aSearchKeys: set_cmd( &cmd, aSearchKeys); break; case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break; case aExport: set_cmd( &cmd, aExport); break; case aExportAll: set_cmd( &cmd, aExportAll); break; @@ -1061,8 +1070,14 @@ main( int argc, char **argv ) not_implemented("lock-multiple"); #endif /* __riscos__ */ break; - - case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break; + case oKeyServer: + if(parse_keyserver_uri(pargs.r.ret_str)) + log_error(_("Could not parse keyserver URI\n")); + break; + case oKeyServerOptions: + parse_keyserver_options(pargs.r.ret_str); + break; + case oTempDir: opt.temp_dir=pargs.r.ret_str; break; case oNotation: add_notation_data( pargs.r.ret_str ); break; case oUtf8Strings: utf8_strings = 1; break; case oNoUtf8Strings: utf8_strings = 0; break; @@ -1078,7 +1093,11 @@ main( int argc, char **argv ) case oAllowFreeformUID: opt.allow_freeform_uid = 1; break; case oNoLiteral: opt.no_literal = 1; break; case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break; - case oHonorHttpProxy: opt.honor_http_proxy = 1; break; + case oHonorHttpProxy: + opt.honor_http_proxy = 1; + log_info("WARNING: --honor-http-proxy is deprecated.\n"); + log_info("Please use \"--keyserver-options honor-http-proxy\" instead\n"); + break; case oFastListMode: opt.fast_list_mode = 1; break; case oFixedListMode: opt.fixed_list_mode = 1; break; case oListOnly: opt.list_only=1; break; @@ -1086,6 +1105,7 @@ main( int argc, char **argv ) case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; case oIgnoreCrcError: opt.ignore_crc_error = 1; break; case oNoRandomSeedFile: use_random_seed = 0; break; + case oAutoKeyRetrieve: opt.auto_key_retrieve = 1; break; case oNoAutoKeyRetrieve: opt.auto_key_retrieve = 0; break; case oShowSessionKey: opt.show_session_key = 1; break; case oOverrideSessionKey: @@ -1519,19 +1539,30 @@ main( int argc, char **argv ) for( ; argc; argc--, argv++ ) add_to_strlist2( &sl, *argv, utf8_strings ); if( cmd == aSendKeys ) - hkp_export( sl ); + keyserver_export( sl ); else if( cmd == aRecvKeys ) - hkp_import( sl ); + keyserver_import( sl ); else export_pubkeys( sl, (cmd == aExport) ); free_strlist(sl); break; + case aSearchKeys: + sl = NULL; + for( ; argc; argc--, argv++ ) + append_to_strlist2( &sl, *argv, utf8_strings ); + + keyserver_search( sl ); + free_strlist(sl); + break; + case aRefreshKeys: - if (argc) - wrong_args("--refresh-keys"); - hkp_refresh_keys (); - break; + sl = NULL; + for( ; argc; argc--, argv++ ) + add_to_strlist2( &sl, *argv, utf8_strings ); + keyserver_refresh(sl); + free_strlist(sl); + break; case aExportSecret: sl = NULL; @@ -1995,3 +2026,22 @@ check_policy_url( const char *s ) return 0; } +const char *get_temp_dir(void) +{ + char *tmp; + + if(opt.temp_dir) + return opt.temp_dir; + + if((tmp=getenv("TMPDIR"))) + return tmp; + + if((tmp=getenv("TMP"))) + return tmp; + +#ifdef __riscos__ + return "<Wimp$ScrapDir>"; +#else + return "/tmp"; +#endif +} diff --git a/g10/gpgv.c b/g10/gpgv.c index d80cbd51f..b3076e706 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -48,7 +48,6 @@ #include "i18n.h" #include "status.h" #include "g10defs.h" -#include "hkp.h" enum cmd_and_opt_values { aNull = 0, @@ -247,7 +246,7 @@ get_ownertrust_info (PKT_public_key *pk) * get them from a keyserver */ int -hkp_ask_import( u32 *keyid, void *dummy ) +keyserver_import_keyid( u32 *keyid, void *dummy ) { return -1; } @@ -34,6 +34,7 @@ #include "filter.h" #include "http.h" #include "main.h" +#include "keyserver-internal.h" static int urlencode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); @@ -54,30 +55,28 @@ hkp_ask_import( u32 *keyid, void *stats_handle) int rc; unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0; - if( !opt.keyserver_name ) - return -1; - log_info(_("requesting key %08lX from %s ...\n"), (ulong)keyid[1], - opt.keyserver_name ); - request = m_alloc( strlen( opt.keyserver_name ) + 100 ); + log_info(_("requesting key %08lX from HKP keyserver %s\n"), + (ulong)keyid[1],opt.keyserver_host ); + request = m_alloc( strlen( opt.keyserver_host ) + 100 ); /* hkp does not accept the long keyid - we should really write a * nicer one :-) * FIXME: request binary mode - need to pass no_armor mode * down to the import function. Marc told that there is such a * binary mode ... how? */ - if ( !strncmp (opt.keyserver_name, "x-broken-hkp://", 15) ) { - sprintf( request, "x-hkp://%s/pks/lookup?op=get&search=0x%08lX", - opt.keyserver_name+15, (ulong)keyid[1] ); - hflags |= HTTP_FLAG_NO_SHUTDOWN; - } - else if ( !strncmp (opt.keyserver_name, "x-hkp://", 8) ) { - sprintf( request, "%s/pks/lookup?op=get&search=0x%08lX", - opt.keyserver_name, (ulong)keyid[1] ); - } - else { - sprintf( request, "x-hkp://%s/pks/lookup?op=get&search=0x%08lX", - opt.keyserver_name, (ulong)keyid[1] ); - } + + if(strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0) + hflags |= HTTP_FLAG_NO_SHUTDOWN; + + sprintf(request,"x-hkp://%s%s%s/pks/lookup?op=get&search=0x%08lX", + opt.keyserver_host, + atoi(opt.keyserver_port)>0?":":"", + atoi(opt.keyserver_port)>0?opt.keyserver_port:"", + (ulong)keyid[1] ); + + if(opt.keyserver_options.verbose>2) + log_info("Request is \"%s\"\n",request); + rc = http_open_document( &hd, request, hflags ); if( rc ) { log_info(_("can't get key from keyserver: %s\n"), @@ -85,7 +84,8 @@ hkp_ask_import( u32 *keyid, void *stats_handle) : g10_errstr(rc) ); } else { - rc = import_keys_stream( hd.fp_read , 0, stats_handle ); + rc = import_keys_stream( hd.fp_read, + opt.keyserver_options.fast_import,stats_handle); http_close( &hd ); } @@ -93,41 +93,6 @@ hkp_ask_import( u32 *keyid, void *stats_handle) return rc; } - - -int -hkp_import( STRLIST users ) -{ - void *stats_handle; - - if( !opt.keyserver_name ) { - log_error(_("no keyserver known (use option --keyserver)\n")); - return -1; - } - - stats_handle = import_new_stats_handle (); - for( ; users; users = users->next ) { - KEYDB_SEARCH_DESC desc; - - classify_user_id (users->d, &desc); - if( desc.mode != KEYDB_SEARCH_MODE_SHORT_KID - && desc.mode != KEYDB_SEARCH_MODE_LONG_KID ) { - log_error (_("%s: not a valid key ID\n"), users->d ); - continue; - } - /* because the function may use log_info in some situations, the - * errorcounter ist not increaed and the program will return - * with success - which is not good when this function is used. - */ - if( hkp_ask_import( desc.u.kid, stats_handle ) ) - log_inc_errorcount(); - } - import_print_stats (stats_handle); - import_release_stats_handle (stats_handle); - return 0; -} - - int hkp_export( STRLIST users ) { @@ -139,11 +104,6 @@ hkp_export( STRLIST users ) unsigned int status; unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0; - if( !opt.keyserver_name ) { - log_error(_("no keyserver known (use option --keyserver)\n")); - return -1; - } - iobuf_push_filter( temp, urlencode_filter, NULL ); memset( &afx, 0, sizeof afx); @@ -158,21 +118,23 @@ hkp_export( STRLIST users ) iobuf_flush_temp( temp ); - request = m_alloc( strlen( opt.keyserver_name ) + 100 ); - if ( !strncmp (opt.keyserver_name, "x-broken-hkp://", 15) ) { - sprintf( request, "x-hkp://%s/pks/add", opt.keyserver_name+15 ); - hflags |= HTTP_FLAG_NO_SHUTDOWN; - } - else if ( !strncmp (opt.keyserver_name, "x-hkp://", 8) ) { - sprintf( request, "%s/pks/add", opt.keyserver_name ); - } - else { - sprintf( request, "x-hkp://%s/pks/add", opt.keyserver_name ); - } + request = m_alloc( strlen( opt.keyserver_host ) + 100 ); + + if(strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0) + hflags |= HTTP_FLAG_NO_SHUTDOWN; + + sprintf( request, "x-hkp://%s%s%s/pks/add", + opt.keyserver_host, + atoi(opt.keyserver_port)>0?":":"", + atoi(opt.keyserver_port)>0?opt.keyserver_port:""); + + if(opt.keyserver_options.verbose>2) + log_info("Request is \"%s\"\n",request); + rc = http_open( &hd, HTTP_REQ_POST, request , hflags ); if( rc ) { log_error(_("can't connect to `%s': %s\n"), - opt.keyserver_name, + opt.keyserver_host, rc == G10ERR_NETWORK? strerror(errno) : g10_errstr(rc) ); iobuf_close(temp); @@ -196,7 +158,7 @@ hkp_export( STRLIST users ) rc = http_wait_response( &hd, &status ); if( rc ) { log_error(_("error sending to `%s': %s\n"), - opt.keyserver_name, g10_errstr(rc) ); + opt.keyserver_host, g10_errstr(rc) ); } else { #if 1 @@ -208,10 +170,10 @@ hkp_export( STRLIST users ) #endif if( (status/100) == 2 ) log_info(_("success sending to `%s' (status=%u)\n"), - opt.keyserver_name, status ); + opt.keyserver_host, status ); else log_error(_("failed sending to `%s': status=%u\n"), - opt.keyserver_name, status ); + opt.keyserver_host, status ); } http_close( &hd ); return rc; @@ -243,93 +205,294 @@ urlencode_filter( void *opaque, int control, return rc; } +/* pub 2048/<a href="/pks/lookup?op=get&search=0x3CB3B415">3CB3B415</a> 1998/04/03 David M. Shaw <<a href="/pks/lookup?op=get&search=0x3CB3B415">[email protected]</a>> */ -int -hkp_refresh_keys (void) +/* Luckily enough, both the HKP server and NAI HKP interface to their + LDAP server are close enough in output so the same function can + parse them both. */ + +static int parse_hkp_index(IOBUF buffer,char *line) { - KEYDB_HANDLE hd; - KBNODE node, keyblock = NULL; - PKT_public_key *pk; - u32 keyid[2]; - u32 *keys = NULL; - size_t n, nkeys=0, maxkeys=0; - void *stats_handle; - int rc = 0; - - /* fist take a snapshot of all keys */ - hd = keydb_new(0); - rc = keydb_search_first(hd); - if (rc) { - if (rc != -1) - log_error ("keydb_search_first failed: %s\n", g10_errstr(rc)); - goto leave; + static int open=0,revoked=0; + static char *key,*uid; + static u32 bits,createtime; + int ret=0; + + /* printf("Open %d, LINE: %s\n",open,line); */ + + /* For multiple UIDs */ + if(open && uid!=NULL) + { + ret=0; + + if(!(revoked && !opt.keyserver_options.include_revoked)) + { + char intstr[11]; + + iobuf_writestr(buffer,key); + iobuf_writestr(buffer,":"); + iobuf_writestr(buffer,uid); + iobuf_writestr(buffer,":"); + iobuf_writestr(buffer,revoked?"1:":":"); + sprintf(intstr,"%u",createtime); + iobuf_writestr(buffer,intstr); + iobuf_writestr(buffer,"::::"); + sprintf(intstr,"%u",bits); + iobuf_writestr(buffer,intstr); + iobuf_writestr(buffer,"\n"); + + ret=1; + } + + if(strncmp(line," ",5)!=0) + { + m_free(key); + m_free(uid); + uid=NULL; + open=0; + } } - - do { - if (!keys) { - maxkeys = 10000; - keys = m_alloc (maxkeys * sizeof *keys); - nkeys = 0; - } - else if ( nkeys == maxkeys ) { - maxkeys += 10000; - keys = m_realloc (keys, maxkeys * sizeof *keys); - } - - rc = keydb_get_keyblock (hd, &keyblock); - if (rc) { - log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc)); - goto leave; - } - - node = keyblock; - if ( node->pkt->pkttype != PKT_PUBLIC_KEY) { - log_debug ("invalid pkttype %d encountered\n", - node->pkt->pkttype); - dump_kbnode (node); - release_kbnode(keyblock); - continue; - } - pk = node->pkt->pkt.public_key; - keyid_from_pk(pk, keyid); - release_kbnode(keyblock); - keyblock = NULL; - /* fixme: replace the linear search */ - for (n=0; n < nkeys; n++) { - if (keys[n] == keyid[1]) { - log_info (_("duplicate (short) key ID %08lX\n"), - (ulong)keyid[1]); - break; - } - } - if (n == nkeys) /* not a duplicate */ - keys[nkeys++] = keyid[1]; - } while ( !(rc = keydb_search_next(hd)) ); - if (rc == -1) - rc = 0; - if (rc) - log_error ("keydb_search_next failed: %s\n", g10_errstr(rc)); - keydb_release(hd); - hd = NULL; - - /* and now refresh them */ - stats_handle = import_new_stats_handle (); - log_info (_("%lu key(s) to refresh\n"), (ulong)nkeys); - for (n=0; n < nkeys; n++) { - /* Note: We do only use the short keyID */ - keyid[0] = 0; - keyid[1] = keys[n]; - if ( hkp_ask_import(keyid, stats_handle) ) - log_inc_errorcount(); + + if(strncasecmp(line,"pub ",5)==0) + { + char *tok,*temp; + + open=1; + + line+=4; + + tok=strsep(&line,"/"); + if(tok==NULL) + return ret; + + bits=atoi(tok); + + tok=strsep(&line,">"); + if(tok==NULL) + return ret; + + tok=strsep(&line,"<"); + if(tok==NULL) + return ret; + + key=m_strdup(tok); + + tok=strsep(&line," "); + if(tok==NULL) + return ret; + + tok=strsep(&line," "); + if(tok==NULL) + return ret; + + /* The date parser wants '-' instead of '/', so... */ + temp=tok; + while(*temp!='\0') + { + if(*temp=='/') + *temp='-'; + + temp++; + } + + createtime=scan_isodatestr(tok); } - import_print_stats (stats_handle); - import_release_stats_handle (stats_handle); - - leave: - m_free (keys); - if (keyblock) - release_kbnode(keyblock); - keydb_release(hd); - return rc; + + if(open) + { + int uidindex=0; + + /* All that's left is the user name. Strip off anything + <between brackets> and de-urlencode it. */ + + while(*line==' ' && *line!='\0') + line++; + + if(strncmp(line,"*** KEY REVOKED ***",19)==0) + { + revoked=1; + return ret; + } + + uid=m_alloc(strlen(line)+1); + + while(*line!='\0') + { + switch(*line) + { + case '<': + while(*line!='>' && *line!='\0') + line++; + + if(*line!='\0') + line++; + break; + + case '&': + if((*(line+1)!='\0' && tolower(*(line+1))=='l') && + (*(line+2)!='\0' && tolower(*(line+2))=='t') && + (*(line+3)!='\0' && *(line+3)==';')) + { + uid[uidindex++]='<'; + line+=4; + break; + } + + if((*(line+1)!='\0' && tolower(*(line+1))=='g') && + (*(line+2)!='\0' && tolower(*(line+2))=='t') && + (*(line+3)!='\0' && *(line+3)==';')) + { + uid[uidindex++]='>'; + line+=4; + break; + } + + default: + uid[uidindex++]=*line; + line++; + break; + } + } + + uid[uidindex]='\0'; + + /* Chop off the trailing \r, \n, or both. This is fussy as the + true HKP servers have \r\n, and the NAI HKP servers have just + \n. */ + + if(isspace(uid[uidindex-1])) + uid[uidindex-1]='\0'; + + if(isspace(uid[uidindex-2])) + uid[uidindex-2]='\0'; + } + + return ret; } +int hkp_search(STRLIST tokens) +{ + int rc=0,len=0,first=1; + unsigned int maxlen=1024,buflen=0; + char *searchstr=NULL,*searchurl=NULL,*request; + struct http_context hd; + unsigned int hflags=opt.honor_http_proxy?HTTP_FLAG_TRY_PROXY:0; + byte *line=NULL; + + /* Glue the tokens together to make a search string */ + + for(;tokens;tokens=tokens->next) + { + len+=strlen(tokens->d)+1; + + searchstr=m_realloc(searchstr,len+1); + if(first) + { + searchstr[0]='\0'; + first=0; + } + + strcat(searchstr,tokens->d); + strcat(searchstr," "); + } + + if(len<=1) + { + m_free(searchstr); + return 0; + } + + searchstr[len-1]='\0'; + + log_info(_("searching for \"%s\" from HKP server %s\n"), + searchstr,opt.keyserver_host); + + /* Now make it url-ish */ + + len=0; + request=searchstr; + while(*request!='\0') + { + if(isalnum(*request) || *request=='-') + { + searchurl=m_realloc(searchurl,len+1); + searchurl[len++]=*request; + } + else if(*request==' ') + { + searchurl=m_realloc(searchurl,len+1); + searchurl[len++]='+'; + } + else + { + searchurl=m_realloc(searchurl,len+3); + sprintf(&searchurl[len],"%%%02X",*request); + len+=3; + } + + request++; + } + + searchurl=m_realloc(searchurl,len+1); + searchurl[len]='\0'; + + request=m_alloc(strlen(opt.keyserver_host) + 100 + strlen(searchurl)); + + if(strcasecmp(opt.keyserver_scheme,"x-broken-hkp")==0) + hflags |= HTTP_FLAG_NO_SHUTDOWN; + + sprintf(request,"x-hkp://%s%s%s/pks/lookup?op=index&search=%s", + opt.keyserver_host, + atoi(opt.keyserver_port)>0?":":"", + atoi(opt.keyserver_port)>0?opt.keyserver_port:"", + searchurl); + + if(opt.keyserver_options.verbose>2) + log_info("Request is \"%s\"\n",request); + + rc=http_open_document(&hd,request,hflags); + if(rc) + { + log_error(_("can't search keyserver: %s\n"), + rc==G10ERR_NETWORK?strerror(errno):g10_errstr(rc)); + } + else + { + IOBUF buffer; + int count=1; + + buffer=iobuf_temp(); + + rc=1; + while(rc!=0) + { + /* This is a judgement call. Is it better to slurp up all + the results before prompting the user? On the one hand, + it probably makes the keyserver happier to not be blocked + on sending for a long time while the user picks a key. + On the other hand, it might be nice for the server to be + able to stop sending before a large search result page is + complete. */ + + rc=iobuf_read_line(hd.fp_read,&line,&buflen,&maxlen); + + if(rc!=0) + count+=parse_hkp_index(buffer,line); + } + + http_close(&hd); + + count--; + + keyserver_search_prompt(buffer,count,searchstr); + + iobuf_close(buffer); + m_free(line); + } + + m_free(request); + m_free(searchurl); + m_free(searchstr); + + return rc; +} @@ -21,11 +21,9 @@ #ifndef G10_HKP_H #define G10_HKP_H 1 - int hkp_ask_import( u32 *keyid, void *stats_handle); int hkp_import( STRLIST users ); int hkp_export( STRLIST users ); -int hkp_refresh_keys (void); - +int hkp_search(STRLIST tokens); #endif /*G10_HKP_H*/ diff --git a/g10/main.h b/g10/main.h index 4ffe3b5da..92050146a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -48,6 +48,7 @@ extern int g10_errors_seen; void print_pubkey_algo_note( int algo ); void print_cipher_algo_note( int algo ); void print_digest_algo_note( int algo ); +const char *get_temp_dir(void); /*-- armor.c --*/ char *make_radix64_string( const byte *data, size_t len ); diff --git a/g10/mainproc.c b/g10/mainproc.c index f2d29b2bd..57cf22139 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -37,7 +37,7 @@ #include "status.h" #include "i18n.h" #include "trustdb.h" -#include "hkp.h" +#include "keyserver-internal.h" struct kidlist_item { @@ -1254,8 +1254,8 @@ check_sig_and_print( CTX c, KBNODE node ) (int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] ); rc = do_check_sig(c, node, NULL ); - if( rc == G10ERR_NO_PUBKEY && opt.keyserver_name && opt.auto_key_retrieve) { - if( !hkp_ask_import( sig->keyid, NULL ) ) + if( rc == G10ERR_NO_PUBKEY && opt.keyserver_scheme && opt.auto_key_retrieve) { + if( keyserver_import_keyid ( sig->keyid )==0 ) rc = do_check_sig(c, node, NULL ); } if( !rc || rc == G10ERR_BAD_SIGN ) { diff --git a/g10/options.h b/g10/options.h index 24012ff10..09a8f173f 100644 --- a/g10/options.h +++ b/g10/options.h @@ -1,3 +1,4 @@ + /* options.h * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * @@ -88,7 +89,20 @@ struct { int not_dash_escaped; int escape_from; int lock_once; - const char *keyserver_name; + char *keyserver_scheme; + char *keyserver_host; + char *keyserver_port; + struct + { + int verbose; + int fast_import:1; + int include_revoked:1; + int include_disabled:1; + int use_temp_files:1; + int keep_temp_files:1; + STRLIST other; + } keyserver_options; + char *temp_dir; int no_encrypt_to; int interactive; STRLIST notation_data; diff --git a/g10/options.skel b/g10/options.skel index f32a9fa08..6f262ac12 100644 --- a/g10/options.skel +++ b/g10/options.skel @@ -91,29 +91,67 @@ lock-once #load-extension rndunix #load-extension rndegd - -# GnuPG can import a key from a HKP keyerver if one is missing -# for certain operations. Is you set this option to a keyserver -# you will be asked in such a case whether GnuPG should try to -# import the key from that server (server do syncronize with each -# other and DNS Round-Robin may give you a random server each time). -# Use "host -l pgp.net | grep www" to figure out a keyserver. +# GnuPG can send and receive keys to and from a keyserver. These +# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP +# support). +# +# Example HKP keyserver: +# x-hkp://wwwkeys.nl.pgp.net +# +# Example email keyserver: +# mailto:[email protected] +# +# Example LDAP keyserver: +# ldap://keyserver.pgp.com +# +# Regular URL syntax applies, and you can set an alternate port +# through the usual method: +# x-hkp://keyserver.example.net:22742 # -# If you do not want to use the default port 11371, you can give the -# name of the keyserver like this: -# x-hkp://keyserver.example.net:22742 -# If you have problems connecting through a buggy proxy, you can use this: -# x-broken-hkp://keyserver.example.net:11371 +# If you have problems connecting to a HKP server through a buggy +# http proxy, you can use this: +# x-broken-hkp://keyserver.example.net # But first you should make sure that you have read the man page regarding -# proxies (--honor-http-proxy) -# Most users just set the name of the preferred keyserver. -#keyserver wwwkeys.nl.pgp.net +# proxies (honor-http-proxy) +# +# Most users just set the name and type of their preferred keyserver. +# Most servers do syncronize with each other and DNS round-robin may +# give you a quasi-random server each time. -# The environment variable http_proxy is only used when the -# this option is set. +#keyserver mailto:[email protected] +#keyserver ldap://keyserver.pgp.com +#keyserver x-hkp://wwwkeys.nl.pgp.net -honor-http-proxy +# Options for keyserver functions +# +# include-disabled = when searching, include keys marked as "disabled" +# on the keyserver (not all keyservers support this). +# +# include-revoked = when searching, include keys marked as "revoked" +# on the keyserver. +# +# verbose = show more information as the keys are fetched. +# Can be included more than once to increase the amount +# of information shown. +# +# use-temp-files = use temporary files instead of a pipe to talk to the +# keyserver. Some platforms (Win32 for one) always +# have this on. +# +# keep-temp-files = don't delete the temporary files after using them +# (really only useful for debugging) +# +# honor-http-proxy = if the keyserver uses http, honor the http_proxy +# environment variable + +#keyserver-options include-disabled include-revoked +# Uncomment this line to automatically fetch a key from a keyserver +# (which must be set - see above) when verifying signatures. +#auto-key-retrieve +# The environment variable http_proxy is only used when the +# this option is set. +#honor-http-proxy |