aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/import.c61
-rw-r--r--g10/keyserver.c86
-rw-r--r--g10/main.h8
3 files changed, 116 insertions, 39 deletions
diff --git a/g10/import.c b/g10/import.c
index 441dcca9d..e40141e94 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -59,14 +59,17 @@ struct stats_s {
static int import( IOBUF inp, const char* fname,struct stats_s *stats,
- unsigned char **fpr,size_t *fpr_len,unsigned int options );
+ unsigned char **fpr,size_t *fpr_len,unsigned int options,
+ import_filter filter, void *filter_arg );
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
static void revocation_present(KBNODE keyblock);
static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
unsigned char **fpr,size_t *fpr_len,
- unsigned int options,int from_sk);
+ unsigned int options,int from_sk,
+ import_filter filter, void *filter_arg);
static int import_secret_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options);
+ struct stats_s *stats, unsigned int options,
+ import_filter filter, void *filter_arg);
static int import_revoke_cert( const char *fname, KBNODE node,
struct stats_s *stats);
static int chk_self_sigs( const char *fname, KBNODE keyblock,
@@ -163,7 +166,8 @@ import_release_stats_handle (void *p)
static int
import_keys_internal( IOBUF inp, char **fnames, int nnames,
void *stats_handle, unsigned char **fpr, size_t *fpr_len,
- unsigned int options )
+ unsigned int options,
+ import_filter filter, void *filter_arg)
{
int i, rc = 0;
struct stats_s *stats = stats_handle;
@@ -172,7 +176,8 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
stats = import_new_stats_handle ();
if (inp) {
- rc = import( inp, "[stream]", stats, fpr, fpr_len, options);
+ rc = import (inp, "[stream]", stats, fpr, fpr_len, options,
+ filter, filter_arg);
}
else {
int once = (!fnames && !nnames);
@@ -192,7 +197,8 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
else
{
- rc = import( inp2, fname, stats, fpr, fpr_len, options );
+ rc = import (inp2, fname, stats, fpr, fpr_len, options,
+ NULL, NULL);
iobuf_close(inp2);
/* Must invalidate that ugly cache to actually close it. */
iobuf_ioctl (NULL, 2, 0, (char*)fname);
@@ -223,19 +229,23 @@ void
import_keys( char **fnames, int nnames,
void *stats_handle, unsigned int options )
{
- import_keys_internal(NULL,fnames,nnames,stats_handle,NULL,NULL,options);
+ import_keys_internal (NULL, fnames, nnames, stats_handle, NULL, NULL,
+ options, NULL, NULL);
}
int
import_keys_stream( IOBUF inp, void *stats_handle,
- unsigned char **fpr, size_t *fpr_len,unsigned int options )
+ unsigned char **fpr, size_t *fpr_len,unsigned int options,
+ import_filter filter, void *filter_arg )
{
- return import_keys_internal(inp,NULL,0,stats_handle,fpr,fpr_len,options);
+ return import_keys_internal (inp, NULL, 0, stats_handle, fpr, fpr_len,
+ options, filter, filter_arg);
}
static int
import( IOBUF inp, const char* fname,struct stats_s *stats,
- unsigned char **fpr,size_t *fpr_len,unsigned int options )
+ unsigned char **fpr,size_t *fpr_len,unsigned int options,
+ import_filter filter, void *filter_arg)
{
PACKET *pending_pkt = NULL;
KBNODE keyblock = NULL;
@@ -252,9 +262,11 @@ import( IOBUF inp, const char* fname,struct stats_s *stats,
while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
- rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0);
- else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
- rc = import_secret_one( fname, keyblock, stats, options );
+ rc = import_one (fname, keyblock, stats, fpr, fpr_len, options, 0,
+ filter, filter_arg);
+ else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
+ rc = import_secret_one (fname, keyblock, stats, options,
+ filter, filter_arg);
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
rc = import_revoke_cert( fname, keyblock, stats );
@@ -738,7 +750,7 @@ check_prefs(KBNODE keyblock)
static int
import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
unsigned char **fpr,size_t *fpr_len,unsigned int options,
- int from_sk )
+ int from_sk, import_filter filter, void *filter_arg)
{
PKT_public_key *pk;
PKT_public_key *pk_orig;
@@ -778,6 +790,13 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
return 0;
}
+ if (filter && filter (pk, NULL, filter_arg))
+ {
+ log_error (_("key %s: %s\n"), keystr_from_pk(pk),
+ _("rejected by import filter"));
+ return 0;
+ }
+
if (opt.interactive) {
if(is_status_enabled())
print_import_check (pk, uidnode->pkt->pkt.user_id);
@@ -1146,7 +1165,8 @@ sec_to_pub_keyblock(KBNODE sec_keyblock)
*/
static int
import_secret_one( const char *fname, KBNODE keyblock,
- struct stats_s *stats, unsigned int options)
+ struct stats_s *stats, unsigned int options,
+ import_filter filter, void *filter_arg)
{
PKT_secret_key *sk;
KBNODE node, uidnode;
@@ -1162,6 +1182,12 @@ import_secret_one( const char *fname, KBNODE keyblock,
keyid_from_sk( sk, keyid );
uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
+ if (filter && filter (NULL, sk, filter_arg)) {
+ log_error (_("secret key %s: %s\n"), keystr_from_sk(sk),
+ _("rejected by import filter"));
+ return 0;
+ }
+
if( opt.verbose )
{
log_info( "sec %4u%c/%s %s ",
@@ -1240,8 +1266,9 @@ import_secret_one( const char *fname, KBNODE keyblock,
KBNODE pub_keyblock=sec_to_pub_keyblock(keyblock);
if(pub_keyblock)
{
- import_one(fname,pub_keyblock,stats,
- NULL,NULL,opt.import_options,1);
+ import_one (fname, pub_keyblock, stats,
+ NULL, NULL, opt.import_options, 1,
+ NULL, NULL);
release_kbnode(pub_keyblock);
}
}
diff --git a/g10/keyserver.c b/g10/keyserver.c
index 7bf983064..dca5e18bf 100644
--- a/g10/keyserver.c
+++ b/g10/keyserver.c
@@ -656,7 +656,7 @@ parse_keyrec(char *keystring)
case 'R':
work->flags|=1;
break;
-
+
case 'd':
case 'D':
work->flags|=2;
@@ -910,7 +910,7 @@ keyserver_search_prompt(IOBUF buffer,const char *searchstr)
/* Leave this commented out or now, and perhaps for a very long
time. All HKPish servers return HTML error messages for
no-key-found. */
- /*
+ /*
if(!started)
log_info(_("keyserver does not support searching\n"));
else
@@ -959,7 +959,52 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
#define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
#define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
-static int
+
+/* Check whether a key matches the search description. The filter
+ returns 0 if the key shall be imported. Note that this kind of
+ filter is not related to the iobuf filters. */
+static int
+keyserver_retrieval_filter (PKT_public_key *pk, PKT_secret_key *sk, void *arg)
+{
+ KEYDB_SEARCH_DESC *desc = arg;
+ u32 keyid[2];
+ byte fpr[MAX_FINGERPRINT_LEN];
+ size_t fpr_len = 0;
+
+ /* Secret keys are not expected from a keyserver. Do not import. */
+ if (sk)
+ return G10ERR_GENERAL;
+
+ fingerprint_from_pk (pk, fpr, &fpr_len);
+ keyid_from_pk (pk, keyid);
+
+ /* Compare requested and returned fingerprints if available. */
+ if (desc->mode == KEYDB_SEARCH_MODE_FPR20)
+ {
+ if (fpr_len != 20 || memcmp (fpr, desc->u.fpr, 20))
+ return G10ERR_GENERAL;
+ }
+ else if (desc->mode == KEYDB_SEARCH_MODE_FPR16)
+ {
+ if (fpr_len != 16 || memcmp (fpr, desc->u.fpr, 16))
+ return G10ERR_GENERAL;
+ }
+ else if (desc->mode == KEYDB_SEARCH_MODE_LONG_KID)
+ {
+ if (keyid[0] != desc->u.kid[0] || keyid[1] != desc->u.kid[1])
+ return G10ERR_GENERAL;
+ }
+ else if (desc->mode == KEYDB_SEARCH_MODE_SHORT_KID)
+ {
+ if (keyid[1] != desc->u.kid[1])
+ return G10ERR_GENERAL;
+ }
+
+ return 0;
+}
+
+
+static int
keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
int count,int *prog,unsigned char **fpr,size_t *fpr_len,
struct keyserver_spec *keyserver)
@@ -999,7 +1044,7 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
the program of this process lives. Fortunately Windows provides
a way to retrieve this and our get_libexecdir function has been
modified to return just this. Setting the exec-path is not
- anymore required.
+ anymore required.
set_exec_path(libexecdir);
*/
#else
@@ -1031,7 +1076,7 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
fetcher that can speak that protocol (this is a problem for
LDAP). */
- strcat(command,GPGKEYS_PREFIX);
+ strcat(command,GPGKEYS_PREFIX);
strcat(command,scheme);
/* This "_uri" thing is in case we need to call a direct handler
@@ -1061,7 +1106,7 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
{
command=xrealloc(command,strlen(command)+
strlen(KEYSERVER_ARGS_NOKEEP)+1);
- strcat(command,KEYSERVER_ARGS_NOKEEP);
+ strcat(command,KEYSERVER_ARGS_NOKEEP);
}
ret=exec_write(&spawn,NULL,command,NULL,0,0);
@@ -1509,8 +1554,9 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
but we better protect against rogue keyservers. */
import_keys_stream (spawn->fromchild, stats_handle, fpr, fpr_len,
- (opt.keyserver_options.import_options
- | IMPORT_NO_SECKEY));
+ (opt.keyserver_options.import_options
+ | IMPORT_NO_SECKEY),
+ keyserver_retrieval_filter, desc);
import_print_stats(stats_handle);
import_release_stats_handle(stats_handle);
@@ -1541,7 +1587,7 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
return ret;
}
-static int
+static int
keyserver_work(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
int count,unsigned char **fpr,size_t *fpr_len,
struct keyserver_spec *keyserver)
@@ -1611,7 +1657,7 @@ keyserver_work(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc,
#endif /* ! DISABLE_KEYSERVER_HELPERS*/
}
-int
+int
keyserver_export(STRLIST users)
{
STRLIST sl=NULL;
@@ -1643,7 +1689,7 @@ keyserver_export(STRLIST users)
return rc;
}
-int
+int
keyserver_import(STRLIST users)
{
KEYDB_SEARCH_DESC *desc;
@@ -1703,7 +1749,7 @@ keyserver_import_fprint(const byte *fprint,size_t fprint_len,
return keyserver_work(KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
}
-int
+int
keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
{
KEYDB_SEARCH_DESC desc;
@@ -1718,7 +1764,7 @@ keyserver_import_keyid(u32 *keyid,struct keyserver_spec *keyserver)
}
/* code mostly stolen from do_export_stream */
-static int
+static int
keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
{
int rc=0,ndesc,num=100;
@@ -1741,10 +1787,10 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
}
else
{
- for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
+ for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
;
desc = xmalloc ( ndesc * sizeof *desc);
-
+
for (ndesc=0, sl=users; sl; sl = sl->next)
{
if(classify_user_id (sl->d, desc+ndesc))
@@ -1757,7 +1803,7 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
while (!(rc = keydb_search (kdbhd, desc, ndesc)))
{
- if (!users)
+ if (!users)
desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
/* read the keyblock */
@@ -1860,7 +1906,7 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
if(rc==-1)
rc=0;
-
+
leave:
if(rc)
xfree(*klist);
@@ -2043,7 +2089,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len)
rc=import_keys_stream (key, NULL, fpr, fpr_len,
(opt.keyserver_options.import_options
- | IMPORT_NO_SECKEY));
+ | IMPORT_NO_SECKEY), NULL, NULL);
opt.no_armor=armor_status;
@@ -2182,7 +2228,7 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
snprintf(port,7,":%u",srvlist[i].port);
strcat(keyserver->host,port);
}
-
+
strcat(keyserver->host," ");
}
@@ -2198,7 +2244,7 @@ keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len)
strcat(keyserver->host,domain);
append_to_strlist(&list,name);
-
+
rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver);
free_strlist(list);
diff --git a/g10/main.h b/g10/main.h
index 784ade06d..e4c4385bf 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -207,11 +207,15 @@ MPI encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
MD_HANDLE md, int hash_algo );
/*-- import.c --*/
+
+typedef int (*import_filter)(PKT_public_key *pk, PKT_secret_key *sk, void *arg);
+
int parse_import_options(char *str,unsigned int *options,int noisy);
void import_keys( char **fnames, int nnames,
void *stats_hd, unsigned int options );
-int import_keys_stream( IOBUF inp,void *stats_hd,unsigned char **fpr,
- size_t *fpr_len,unsigned int options );
+int import_keys_stream (IOBUF inp,void *stats_hd,unsigned char **fpr,
+ size_t *fpr_len,unsigned int options,
+ import_filter filter, void *filter_arg);
void *import_new_stats_handle (void);
void import_release_stats_handle (void *p);
void import_print_stats (void *hd);