1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-07-01 02:42:44 +02:00

Generic keyserver API code

This commit is contained in:
David Shaw 2001-12-06 21:43:04 +00:00
parent 4b01e2a943
commit b7a4656965
9 changed files with 460 additions and 195 deletions

View File

@ -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) \

View File

@ -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
}

View File

@ -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;
}

471
g10/hkp.c
View File

@ -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 &lt;<a href="/pks/lookup?op=get&search=0x3CB3B415">dshaw@jabberwocky.com</a>&gt; */
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;
static int open=0,revoked=0;
static char *key,*uid;
static u32 bits,createtime;
int ret=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;
/* 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;
}
if(strncasecmp(line,"pub ",5)==0)
{
char *tok,*temp;
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();
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;
}

View File

@ -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*/

View File

@ -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 );

View File

@ -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 ) {

View File

@ -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;

View File

@ -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).
#
# 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
# Example HKP keyserver:
# x-hkp://wwwkeys.nl.pgp.net
#
# Example email keyserver:
# mailto:pgp-public-keys@keys.nl.pgp.net
#
# 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 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.
#keyserver mailto:pgp-public-keys@keys.nl.pgp.net
#keyserver ldap://keyserver.pgp.com
#keyserver x-hkp://wwwkeys.nl.pgp.net
# 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
#honor-http-proxy