mirror of
git://git.gnupg.org/gnupg.git
synced 2025-03-25 22:19:59 +01:00
Generic keyserver API code
This commit is contained in:
parent
4b01e2a943
commit
b7a4656965
@ -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) \
|
||||
|
72
g10/g10.c
72
g10/g10.c
@ -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
|
||||
}
|
||||
|
@ -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
471
g10/hkp.c
@ -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">dshaw@jabberwocky.com</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;
|
||||
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;
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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 );
|
||||
|
@ -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 ) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user