aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog11
-rw-r--r--g10/g10.c4
-rw-r--r--g10/keyedit.c190
-rw-r--r--g10/keyserver-internal.h3
-rw-r--r--g10/keyserver.c14
5 files changed, 134 insertions, 88 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 918798d79..4e217e867 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,14 @@
+2004-05-08 David Shaw <[email protected]>
+
+ * keyedit.c (keyedit_menu, menu_set_keyserver_url): Allow passing
+ preferred keyserver on "keyserver" command line. Sanity check
+ keyserver URL before accepting it.
+
+ * keyserver-internal.h, g10.c (main), keyserver.c
+ (parse_keyserver_uri): Add an option to require the scheme:// and
+ change all callers.
+ (free_keyserver_spec): Make public.
+
2004-05-07 Werner Koch <[email protected]>
* sign.c (write_plaintext_packet): Fixed the detection of too
diff --git a/g10/g10.c b/g10/g10.c
index 438242e52..6ced4f262 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -2084,10 +2084,10 @@ main( int argc, char **argv )
#endif /* __riscos__ */
break;
case oKeyServer:
- opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,
+ opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
configname,configlineno);
if(!opt.keyserver)
- log_error(_("could not parse keyserver URI\n"));
+ log_error(_("could not parse keyserver URL\n"));
break;
case oKeyServerOptions:
if(!parse_keyserver_options(pargs.r.ret_str))
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 0381dc731..8ab2276be 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -41,6 +41,7 @@
#include "ttyio.h"
#include "status.h"
#include "i18n.h"
+#include "keyserver-internal.h"
static void show_prefs( PKT_user_id *uid, int verbose );
static void show_key_with_all_names( KBNODE keyblock, int only_marked,
@@ -55,7 +56,8 @@ static int menu_addrevoker( KBNODE pub_keyblock,
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
-static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
+static int menu_set_keyserver_url (const char *url,
+ KBNODE pub_keyblock, KBNODE sec_keyblock );
static int menu_select_uid( KBNODE keyblock, int idx );
static int menu_select_key( KBNODE keyblock, int idx );
static int count_uids( KBNODE keyblock );
@@ -1607,11 +1609,13 @@ keyedit_menu( const char *username, STRLIST locusr,
break;
case cmdPREFKS:
- if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
+ if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
+ keyblock, sec_keyblock ) )
+ {
merge_keys_and_selfsig( keyblock );
modified = 1;
redisplay = 1;
- }
+ }
break;
case cmdNOP:
@@ -3173,96 +3177,120 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
static int
-menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
+menu_set_keyserver_url (const char *url,
+ KBNODE pub_keyblock, KBNODE sec_keyblock )
{
- PKT_secret_key *sk; /* copy of the main sk */
- PKT_public_key *main_pk;
- PKT_user_id *uid;
- KBNODE node;
- u32 keyid[2];
- int selected, select_all;
- int modified = 0;
- char *answer;
+ PKT_secret_key *sk; /* copy of the main sk */
+ PKT_public_key *main_pk;
+ PKT_user_id *uid;
+ KBNODE node;
+ u32 keyid[2];
+ int selected, select_all;
+ int modified = 0;
+ char *answer;
+ struct keyserver_spec *keyserver;
- no_primary_warning(pub_keyblock);
+ no_primary_warning(pub_keyblock);
- answer=cpr_get_utf8("keyedit.add_keyserver",
- _("Enter your preferred keyserver URL: "));
- if(answer[0]=='\0' || answer[0]=='\004')
- {
- m_free(answer);
- return 0;
- }
+ if(url)
+ answer=m_strdup(url);
+ else
+ {
+ answer=cpr_get_utf8("keyedit.add_keyserver",
+ _("Enter your preferred keyserver URL: "));
+ if(answer[0]=='\0' || answer[0]=='\004')
+ {
+ m_free(answer);
+ return 0;
+ }
+ }
- select_all = !count_selected_uids (pub_keyblock);
+ /* Sanity check the format */
+ keyserver=parse_keyserver_uri(answer,1,NULL,0);
+ m_free(answer);
+ if(!keyserver)
+ {
+ log_info(_("could not parse keyserver URL\n"));
+ return 0;
+ }
- node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
- sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
+ select_all = !count_selected_uids (pub_keyblock);
- /* Now we can actually change the self signature(s) */
- main_pk = NULL;
- uid = NULL;
- selected = 0;
- for ( node=pub_keyblock; node; node = node->next ) {
- if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
- break; /* ready */
+ node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
+ sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
- if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
- main_pk = node->pkt->pkt.public_key;
- keyid_from_pk( main_pk, keyid );
- }
- else if ( node->pkt->pkttype == PKT_USER_ID ) {
- uid = node->pkt->pkt.user_id;
- selected = select_all || (node->flag & NODFLG_SELUID);
- }
- else if ( main_pk && uid && selected
- && node->pkt->pkttype == PKT_SIGNATURE ) {
- PKT_signature *sig = node->pkt->pkt.signature;
- if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
- && (uid && (sig->sig_class&~3) == 0x10) ) {
- if( sig->version < 4 ) {
- char *user=utf8_to_native(uid->name,strlen(uid->name),0);
+ /* Now we can actually change the self signature(s) */
+ main_pk = NULL;
+ uid = NULL;
+ selected = 0;
+ for ( node=pub_keyblock; node; node = node->next )
+ {
+ if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+ break; /* ready */
- log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
- user);
- m_free(user);
- }
- else {
- /* This is a selfsignature which is to be replaced
- * We have to ignore v3 signatures because they are
- * not able to carry the preferences */
- PKT_signature *newsig;
- PACKET *newpkt;
- int rc;
+ if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
+ {
+ main_pk = node->pkt->pkt.public_key;
+ keyid_from_pk( main_pk, keyid );
+ }
+ else if ( node->pkt->pkttype == PKT_USER_ID )
+ {
+ uid = node->pkt->pkt.user_id;
+ selected = select_all || (node->flag & NODFLG_SELUID);
+ }
+ else if ( main_pk && uid && selected
+ && node->pkt->pkttype == PKT_SIGNATURE )
+ {
+ PKT_signature *sig = node->pkt->pkt.signature;
+ if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+ && (uid && (sig->sig_class&~3) == 0x10) )
+ {
+ if( sig->version < 4 )
+ {
+ char *user=utf8_to_native(uid->name,strlen(uid->name),0);
- rc = update_keysig_packet (&newsig, sig,
- main_pk, uid, NULL,
- sk,
- keygen_add_keyserver_url,
- answer );
- if( rc ) {
- log_error ("update_keysig_packet failed: %s\n",
- g10_errstr(rc));
- m_free(answer);
- free_secret_key( sk );
- return 0;
- }
- /* replace the packet */
- newpkt = m_alloc_clear( sizeof *newpkt );
- newpkt->pkttype = PKT_SIGNATURE;
- newpkt->pkt.signature = newsig;
- free_packet( node->pkt );
- m_free( node->pkt );
- node->pkt = newpkt;
- modified = 1;
- }
- }
+ log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
+ user);
+ m_free(user);
+ }
+ else
+ {
+ /* This is a selfsignature which is to be replaced
+ * We have to ignore v3 signatures because they are
+ * not able to carry the preferences */
+ PKT_signature *newsig;
+ PACKET *newpkt;
+ int rc;
+
+ rc = update_keysig_packet (&newsig, sig,
+ main_pk, uid, NULL,
+ sk,
+ keygen_add_keyserver_url,
+ keyserver->uri );
+ if( rc )
+ {
+ log_error ("update_keysig_packet failed: %s\n",
+ g10_errstr(rc));
+ free_keyserver_spec(keyserver);
+ free_secret_key( sk );
+ return 0;
+ }
+ /* replace the packet */
+ newpkt = m_alloc_clear( sizeof *newpkt );
+ newpkt->pkttype = PKT_SIGNATURE;
+ newpkt->pkt.signature = newsig;
+ free_packet( node->pkt );
+ m_free( node->pkt );
+ node->pkt = newpkt;
+ modified = 1;
+ }
+ }
}
}
- m_free(answer);
- free_secret_key( sk );
- return modified;
+ free_keyserver_spec(keyserver);
+ free_secret_key( sk );
+ return modified;
}
diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h
index 42b78048d..9450bbb1d 100644
--- a/g10/keyserver-internal.h
+++ b/g10/keyserver-internal.h
@@ -9,7 +9,8 @@
#include "types.h"
int parse_keyserver_options(char *options);
-struct keyserver_spec *parse_keyserver_uri(char *uri,
+void free_keyserver_spec(struct keyserver_spec *keyserver);
+struct keyserver_spec *parse_keyserver_uri(char *uri,int require_scheme,
const char *configname,
unsigned int configlineno);
int keyserver_export(STRLIST users);
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 8b71a6340..7cf7824e8 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -135,7 +135,7 @@ parse_keyserver_options(char *options)
return ret;
}
-static void
+void
free_keyserver_spec(struct keyserver_spec *keyserver)
{
m_free(keyserver->uri);
@@ -146,7 +146,8 @@ free_keyserver_spec(struct keyserver_spec *keyserver)
}
struct keyserver_spec *
-parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
+parse_keyserver_uri(char *uri,int require_scheme,
+ const char *configname,unsigned int configlineno)
{
int assume_hkp=0;
struct keyserver_spec *keyserver;
@@ -163,6 +164,9 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
scheme=strsep(&uri,":");
if(uri==NULL)
{
+ if(require_scheme)
+ return NULL;
+
/* Assume HKP if there is no scheme */
assume_hkp=1;
uri=scheme;
@@ -1361,9 +1365,11 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
dupe[plen]='\0';
/* Make up a keyserver structure and do an
- import for this key. */
+ import for this key. Note that a preferred
+ keyserver without a scheme:// will be
+ interpreted as hkp:// */
- keyserver=parse_keyserver_uri(dupe,NULL,0);
+ keyserver=parse_keyserver_uri(dupe,0,NULL,0);
m_free(dupe);
if(keyserver)