diff --git a/common/Makefile.am b/common/Makefile.am index a6a680f34..0a8051bd4 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -60,7 +60,6 @@ common_sources = \ shareddefs.h \ openpgpdefs.h \ gc-opt-flags.h \ - keyserver.h \ sexp-parse.h \ tlv.c tlv.h \ init.c init.h \ diff --git a/common/keyserver.h b/common/keyserver.h deleted file mode 100644 index 850798ed0..000000000 --- a/common/keyserver.h +++ /dev/null @@ -1,73 +0,0 @@ -/* keyserver.h - Public definitions for gpg keyserver helpers. - * Copyright (C) 2001, 2002, 2011 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of either - * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef GNUPG_COMMON_KEYSERVER_H -#define GNUPG_COMMON_KEYSERVER_H - -#define KEYSERVER_PROTO_VERSION 1 - -/* These are usable for return codes for the gpgkeys_ process, and - also KEY FAILED codes. */ -#define KEYSERVER_OK 0 /* not an error */ -#define KEYSERVER_INTERNAL_ERROR 1 /* gpgkeys_ internal error */ -#define KEYSERVER_NOT_SUPPORTED 2 /* operation not supported */ -#define KEYSERVER_VERSION_ERROR 3 /* VERSION mismatch */ -#define KEYSERVER_GENERAL_ERROR 4 /* keyserver internal error */ -#define KEYSERVER_NO_MEMORY 5 /* out of memory */ -#define KEYSERVER_KEY_NOT_FOUND 6 /* key not found */ -#define KEYSERVER_KEY_EXISTS 7 /* key already exists */ -#define KEYSERVER_KEY_INCOMPLETE 8 /* key incomplete (EOF) */ -#define KEYSERVER_UNREACHABLE 9 /* unable to contact keyserver */ - -/* Must be 127 due to shell internal magic. */ -#define KEYSERVER_SCHEME_NOT_FOUND 127 - -/* Object to hold information pertaining to a keyserver; it also - allows building a list of keyservers. Note that g10/options.h has - a typedef for this. FIXME: We should make use of the - parse_uri_t. */ -struct keyserver_spec -{ - struct keyserver_spec *next; - char *uri; - char *scheme; - char *auth; - char *host; - char *port; - char *path; - char *opaque; - strlist_t options; - struct - { - unsigned int direct_uri:1; - } flags; -}; - - -#endif /*GNUPG_COMMON_KEYSERVER_H*/ diff --git a/doc/gpg.texi b/doc/gpg.texi index 7842e6200..327ebbfc6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1929,10 +1929,7 @@ keys on. The format of the @var{name} is a URI: "hkp"/"hkps" for the HTTP (or compatible) keyservers or "ldap"/"ldaps" for the LDAP keyservers. Note that your particular installation of GnuPG may have other keyserver types available as well. Keyserver -schemes are case-insensitive. After the keyserver name, optional -keyserver configuration options may be provided. These are the same as -the global @option{--keyserver-options} from below, but apply only to -this particular keyserver. +schemes are case-insensitive. Most keyservers synchronize with each other, so there is generally no need to send keys to more than one server. The keyserver diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 6b44bdeb8..f5022c0bc 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -36,7 +36,6 @@ #include "options.h" #include "../common/i18n.h" #include "../common/asshelp.h" -#include "../common/keyserver.h" #include "../common/status.h" #include "keyserver-internal.h" #include "call-dirmngr.h" diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index b6671d72b..45cb9360a 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -21,7 +21,6 @@ #define _KEYSERVER_INTERNAL_H_ #include -#include "../common/keyserver.h" #include "../common/iobuf.h" #include "../common/types.h" diff --git a/g10/keyserver.c b/g10/keyserver.c index 808e4c3fd..751022a36 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -186,37 +186,17 @@ void free_keyserver_spec(struct keyserver_spec *keyserver) { xfree(keyserver->uri); - xfree(keyserver->scheme); - xfree(keyserver->auth); - xfree(keyserver->host); - xfree(keyserver->port); - xfree(keyserver->path); - xfree(keyserver->opaque); - free_strlist(keyserver->options); xfree(keyserver); } /* Return 0 for match */ static int -cmp_keyserver_spec(struct keyserver_spec *one,struct keyserver_spec *two) +cmp_keyserver_spec(struct keyserver_spec *one, struct keyserver_spec *two) { - if(ascii_strcasecmp(one->scheme,two->scheme)==0) - { - if(one->host && two->host && ascii_strcasecmp(one->host,two->host)==0) - { - if((one->port && two->port - && ascii_strcasecmp(one->port,two->port)==0) - || (!one->port && !two->port)) - return 0; - } - else if(one->opaque && two->opaque - && ascii_strcasecmp(one->opaque,two->opaque)==0) - return 0; - } - - return 1; + return !!ascii_strcasecmp(one->uri, two->uri); } + /* Try and match one of our keyservers. If we can, return that. If we can't, return our input. */ struct keyserver_spec * @@ -231,40 +211,24 @@ keyserver_match(struct keyserver_spec *spec) return spec; } -/* TODO: once we cut over to an all-curl world, we don't need this - parser any longer so it can be removed, or at least moved to - keyserver/ksutil.c for limited use in gpgkeys_ldap or the like. */ +/* Create a new keyserver object from STRING. Unless REQUIRE_SCHEME + * is set a missing scheme is replaced by "hkp://". The data structure + * could be much easier but in the past we parsed the URI here for the + * old 2.0 keyserver helpers - which is not anymore needed. */ keyserver_spec_t -parse_keyserver_uri (const char *string,int require_scheme) +parse_keyserver_uri (const char *string, int require_scheme) { - int assume_hkp=0; struct keyserver_spec *keyserver; const char *idx; int count; - char *uri, *duped_uri, *options; log_assert (string); - keyserver=xmalloc_clear(sizeof(struct keyserver_spec)); - - duped_uri = uri = xstrdup (string); - - options=strchr(uri,' '); - if(options) - { - char *tok; - - *options='\0'; - options++; - - while((tok=optsep(&options))) - warn_kshelper_option (tok, 0); - } + keyserver = xcalloc (1, sizeof *keyserver); /* Get the scheme */ - - for(idx=uri,count=0;*idx && *idx!=':';idx++) + for(idx=string, count=0; *idx && *idx!=':';idx++) { count++; @@ -290,162 +254,21 @@ parse_keyserver_uri (const char *string,int require_scheme) return NULL; /* Assume HKP if there is no scheme */ - assume_hkp=1; - keyserver->scheme=xstrdup("hkp"); - - keyserver->uri=xmalloc(strlen(keyserver->scheme)+3+strlen(uri)+1); - strcpy(keyserver->uri,keyserver->scheme); - strcat(keyserver->uri,"://"); - strcat(keyserver->uri,uri); + keyserver->uri = xstrconcat ("hkp://", string, NULL); } else { - int i; - - keyserver->uri=xstrdup(uri); - - keyserver->scheme=xmalloc(count+1); - - /* Force to lowercase */ - for(i=0;ischeme[i]=ascii_tolower(uri[i]); - - keyserver->scheme[i]='\0'; - - /* Skip past the scheme and colon */ - uri+=count+1; + keyserver->uri = xstrdup (string); } - if(ascii_strcasecmp(keyserver->scheme,"x-broken-hkp")==0) - { - log_info ("keyserver option '%s' is obsolete\n", - "x-broken-hkp"); - } - else if(ascii_strcasecmp(keyserver->scheme,"x-hkp")==0) - { - /* Canonicalize this to "hkp" so it works with both the internal - and external keyserver interface. */ - xfree(keyserver->scheme); - keyserver->scheme=xstrdup("hkp"); - } - - if (uri[0]=='/' && uri[1]=='/' && uri[2] == '/') - { - /* Three slashes means network path with a default host name. - This is a hack because it does not crok all possible - combinations. We should better replace all code by the parser - from http.c. */ - keyserver->path = xstrdup (uri+2); - } - else if(assume_hkp || (uri[0]=='/' && uri[1]=='/')) - { - /* Two slashes means network path. */ - - /* Skip over the "//", if any */ - if(!assume_hkp) - uri+=2; - - /* Do we have userinfo auth data present? */ - for(idx=uri,count=0;*idx && *idx!='@' && *idx!='/';idx++) - count++; - - /* We found a @ before the slash, so that means everything - before the @ is auth data. */ - if(*idx=='@') - { - if(count==0) - goto fail; - - keyserver->auth=xmalloc(count+1); - strncpy(keyserver->auth,uri,count); - keyserver->auth[count]='\0'; - uri+=count+1; - } - - /* Is it an RFC-2732 ipv6 [literal address] ? */ - if(*uri=='[') - { - for(idx=uri+1,count=1;*idx - && ((isascii (*idx) && isxdigit(*idx)) - || *idx==':' || *idx=='.');idx++) - count++; - - /* Is the ipv6 literal address terminated? */ - if(*idx==']') - count++; - else - goto fail; - } - else - for(idx=uri,count=0;*idx && *idx!=':' && *idx!='/';idx++) - count++; - - if(count==0) - goto fail; - - keyserver->host=xmalloc(count+1); - strncpy(keyserver->host,uri,count); - keyserver->host[count]='\0'; - - /* Skip past the host */ - uri+=count; - - if(*uri==':') - { - /* It would seem to be reasonable to limit the range of the - ports to values between 1-65535, but RFC 1738 and 1808 - imply there is no limit. Of course, the real world has - limits. */ - - for(idx=uri+1,count=0;*idx && *idx!='/';idx++) - { - count++; - - /* Ports are digits only */ - if(!digitp(idx)) - goto fail; - } - - keyserver->port=xmalloc(count+1); - strncpy(keyserver->port,uri+1,count); - keyserver->port[count]='\0'; - - /* Skip past the colon and port number */ - uri+=1+count; - } - - /* Everything else is the path */ - if(*uri) - keyserver->path=xstrdup(uri); - else - keyserver->path=xstrdup("/"); - - if(keyserver->path[1]) - keyserver->flags.direct_uri=1; - } - else if(uri[0]!='/') - { - /* No slash means opaque. Just record the opaque blob and get - out. */ - keyserver->opaque=xstrdup(uri); - } - else - { - /* One slash means absolute path. We don't need to support that - yet. */ - goto fail; - } - - xfree (duped_uri); return keyserver; fail: free_keyserver_spec(keyserver); - - xfree (duped_uri); return NULL; } + struct keyserver_spec * parse_preferred_keyserver(PKT_signature *sig) { @@ -1225,7 +1048,7 @@ keyserver_import_keyid (ctrl_t ctrl, /* code mostly stolen from do_export_stream */ static int keyidlist (ctrl_t ctrl, strlist_t users, KEYDB_SEARCH_DESC **klist, - int *count, int fakev3) + int *count) { int rc = 0; int num = 100; @@ -1290,28 +1113,6 @@ keyidlist (ctrl_t ctrl, strlist_t users, KEYDB_SEARCH_DESC **klist, if((node=find_kbnode(keyblock,PKT_PUBLIC_KEY))) { - /* This is to work around a bug in some keyservers (pksd and - OKS) that calculate v4 RSA keyids as if they were v3 RSA. - The answer is to refresh both the correct v4 keyid - (e.g. 99242560) and the fake v3 keyid (e.g. 68FDDBC7). - This only happens for key refresh using the HKP scheme - and if the refresh-add-fake-v3-keyids keyserver option is - set. */ - if(fakev3 && is_RSA(node->pkt->pkt.public_key->pubkey_algo) && - node->pkt->pkt.public_key->version>=4) - { - (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - v3_keyid (node->pkt->pkt.public_key->pkey[0], - (*klist)[*count].u.kid); - (*count)++; - - if(*count==num) - { - num+=100; - *klist=xrealloc(*klist,sizeof(KEYDB_SEARCH_DESC)*num); - } - } - /* v4 keys get full fingerprints. v3 keys get long keyids. This is because it's easy to calculate any sort of keyid from a v4 fingerprint, but not a v3 fingerprint. */ @@ -1402,7 +1203,6 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) { gpg_error_t err; int count, numdesc; - int fakev3 = 0; KEYDB_SEARCH_DESC *desc; unsigned int options=opt.keyserver_options.import_options; @@ -1416,19 +1216,8 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users) the end here. */ opt.keyserver_options.import_options|=IMPORT_FAST; - /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO - scheme, then enable fake v3 keyid generation. Note that this - works only with a keyserver configured. gpg.conf - (i.e. opt.keyserver); however that method of configuring a - keyserver is deprecated and in any case it is questionable - whether we should keep on supporting these ancient and broken - keyservers. */ - if((opt.keyserver_options.options&KEYSERVER_ADD_FAKE_V3) && opt.keyserver - && (ascii_strcasecmp(opt.keyserver->scheme,"hkp")==0 || - ascii_strcasecmp(opt.keyserver->scheme,"mailto")==0)) - fakev3=1; - err = keyidlist (ctrl, users, &desc, &numdesc, fakev3); + err = keyidlist (ctrl, users, &desc, &numdesc); if (err) return err; @@ -1515,16 +1304,6 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens) if (!tokens) return 0; /* Return success if no patterns are given. */ - /* Write global options */ - - /* for(temp=opt.keyserver_options.other;temp;temp=temp->next) */ - /* es_fprintf(spawn->tochild,"OPTION %s\n",temp->d); */ - - /* Write per-keyserver options */ - - /* for(temp=keyserver->options;temp;temp=temp->next) */ - /* es_fprintf(spawn->tochild,"OPTION %s\n",temp->d); */ - { membuf_t mb; strlist_t item; @@ -1544,8 +1323,6 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens) goto leave; } } - /* FIXME: Enable the next line */ - /* log_info (_("searching for \"%s\" from %s\n"), searchstr, keyserver->uri); */ parm.ctrl = ctrl; if (searchstr) @@ -1567,31 +1344,6 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens) else if (err) log_error ("error searching keyserver: %s\n", gpg_strerror (err)); - /* switch(ret) */ - /* { */ - /* case KEYSERVER_SCHEME_NOT_FOUND: */ - /* log_error(_("no handler for keyserver scheme '%s'\n"), */ - /* opt.keyserver->scheme); */ - /* break; */ - - /* case KEYSERVER_NOT_SUPPORTED: */ - /* log_error(_("action '%s' not supported with keyserver " */ - /* "scheme '%s'\n"), "search", opt.keyserver->scheme); */ - /* break; */ - - /* case KEYSERVER_TIMEOUT: */ - /* log_error(_("keyserver timed out\n")); */ - /* break; */ - - /* case KEYSERVER_INTERNAL_ERROR: */ - /* default: */ - /* log_error(_("keyserver internal error\n")); */ - /* break; */ - /* } */ - - /* return gpg_error (GPG_ERR_KEYSERVER); */ - - leave: xfree (parm.desc); xfree (parm.searchstr_disp); @@ -1749,13 +1501,8 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, if (!quiet && override_keyserver) { - if (override_keyserver->host) - log_info (_("requesting key %s from %s server %s\n"), - keystr_from_desc (&desc[idx]), - override_keyserver->scheme, override_keyserver->host); - else - log_info (_("requesting key %s from %s\n"), - keystr_from_desc (&desc[idx]), override_keyserver->uri); + log_info (_("requesting key %s from %s\n"), + keystr_from_desc (&desc[idx]), override_keyserver->uri); } } diff --git a/g10/options.h b/g10/options.h index 0a5c4c1f0..237e5ba74 100644 --- a/g10/options.h +++ b/g10/options.h @@ -31,9 +31,14 @@ #include "../common/compliance.h" -/* Declaration of a keyserver spec type. The definition is found in - ../common/keyserver.h. */ -struct keyserver_spec; +/* Object to hold information pertaining to a keyserver; it also + allows building a list of keyservers. For historic reasons this is + not a strlist_t. */ +struct keyserver_spec +{ + struct keyserver_spec *next; + char *uri; +}; typedef struct keyserver_spec *keyserver_spec_t; diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index e024ee7f8..1a411f28a 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -198,7 +198,7 @@ warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx, static void prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) { - struct keyserver_spec *server; + strlist_t server; if (!err) err = warn_version_mismatch (ctrl, ctx, DIRMNGR_NAME, 0); @@ -219,12 +219,13 @@ prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) while (server) { char line[ASSUAN_LINELENGTH]; - char *user = server->user ? server->user : ""; - char *pass = server->pass ? server->pass : ""; - char *base = server->base ? server->base : ""; - snprintf (line, DIM (line), "LDAPSERVER %s:%i:%s:%s:%s", - server->host, server->port, user, pass, base); + /* If the host is "ldap" we prefix the entire line with "ldap:" + * to avoid an ambiguity on the server due to the introduction + * of this optional prefix. */ + snprintf (line, DIM (line), "LDAPSERVER %s%s", + !strncmp (server->d, "ldap:", 5)? "ldap:":"", + server->d); assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); /* The code below is not required because we don't return an error. */ diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 0baf8de38..d91379da2 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -796,99 +796,6 @@ parse_validation_model (const char *model) } -/* Release the list of SERVERS. As usual it is okay to call this - function with SERVERS passed as NULL. */ -void -keyserver_list_free (struct keyserver_spec *servers) -{ - while (servers) - { - struct keyserver_spec *tmp = servers->next; - xfree (servers->host); - xfree (servers->user); - if (servers->pass) - memset (servers->pass, 0, strlen (servers->pass)); - xfree (servers->pass); - xfree (servers->base); - xfree (servers); - servers = tmp; - } -} - -/* See also dirmngr ldapserver_parse_one(). */ -struct keyserver_spec * -parse_keyserver_line (char *line, - const char *filename, unsigned int lineno) -{ - char *p; - char *endp; - struct keyserver_spec *server; - int fieldno; - int fail = 0; - - /* Parse the colon separated fields. */ - server = xcalloc (1, sizeof *server); - for (fieldno = 1, p = line; p; p = endp, fieldno++ ) - { - endp = strchr (p, ':'); - if (endp) - *endp++ = '\0'; - trim_spaces (p); - switch (fieldno) - { - case 1: - if (*p) - server->host = xstrdup (p); - else - { - log_error (_("%s:%u: no hostname given\n"), - filename, lineno); - fail = 1; - } - break; - - case 2: - if (*p) - server->port = atoi (p); - break; - - case 3: - if (*p) - server->user = xstrdup (p); - break; - - case 4: - if (*p && !server->user) - { - log_error (_("%s:%u: password given without user\n"), - filename, lineno); - fail = 1; - } - else if (*p) - server->pass = xstrdup (p); - break; - - case 5: - if (*p) - server->base = xstrdup (p); - break; - - default: - /* (We silently ignore extra fields.) */ - break; - } - } - - if (fail) - { - log_info (_("%s:%u: skipping this line\n"), filename, lineno); - keyserver_list_free (server); - server = NULL; - } - - return server; -} - int main ( int argc, char **argv) @@ -1446,21 +1353,7 @@ main ( int argc, char **argv) case oValidationModel: parse_validation_model (pargs.r.ret_str); break; case oKeyServer: - { - struct keyserver_spec *keyserver; - keyserver = parse_keyserver_line (pargs.r.ret_str, - configname, pargs.lineno); - if (! keyserver) - log_error (_("could not parse keyserver\n")); - else - { - /* FIXME: Keep last next pointer. */ - struct keyserver_spec **next_p = &opt.keyserver; - while (*next_p) - next_p = &(*next_p)->next; - *next_p = keyserver; - } - } + append_to_strlist (&opt.keyserver, pargs.r.ret_str); break; case oIgnoreCertExtension: @@ -2142,7 +2035,7 @@ main ( int argc, char **argv) } /* cleanup */ - keyserver_list_free (opt.keyserver); + free_strlist (opt.keyserver); opt.keyserver = NULL; gpgsm_release_certlist (recplist); gpgsm_release_certlist (signerlist); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index d1283440d..9d9a303f8 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -39,17 +39,6 @@ #define MAX_DIGEST_LEN 64 -struct keyserver_spec -{ - struct keyserver_spec *next; - - char *host; - int port; - char *user; - char *pass; - char *base; -}; - /* A large struct named "opt" to keep global flags. */ EXTERN_UNLESS_MAIN_MODULE @@ -141,7 +130,7 @@ struct the integrity of the software at runtime. */ - struct keyserver_spec *keyserver; + strlist_t keyserver; /* A list of certificate extension OIDs which are ignored so that one can claim that a critical extension has been handled. One