diff options
author | Werner Koch <wk@gnupg.org> | 2011-02-08 21:11:19 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2011-02-08 21:11:19 +0100 |
commit | 2c79a2832cd3cbc1c09f4f7a7b2653ba6cbd2845 (patch) | |
tree | 87e424f10a74c0cecce3c3ecc96b43eaca1b892c /dirmngr | |
parent | Fix ECDSA 521 bit signing. (diff) | |
download | gnupg2-2c79a2832cd3cbc1c09f4f7a7b2653ba6cbd2845.tar.xz gnupg2-2c79a2832cd3cbc1c09f4f7a7b2653ba6cbd2845.zip |
Add finger support to dirmngr.
The basic network code from http.c is used for finger. This keeps the
network related code at one place and we are able to use the somewhat
matured code form http.c. Unfortunately I had to enhance the http
code for more robustness and probably introduced new bugs.
Test this code using
gpg --fetch-key finger:wk@g10code.com
(I might be the last user of finger ;-)
Diffstat (limited to 'dirmngr')
-rw-r--r-- | dirmngr/ChangeLog | 6 | ||||
-rw-r--r-- | dirmngr/Makefile.am | 3 | ||||
-rw-r--r-- | dirmngr/ks-action.c | 45 | ||||
-rw-r--r-- | dirmngr/ks-action.h | 1 | ||||
-rw-r--r-- | dirmngr/ks-engine-finger.c | 101 | ||||
-rw-r--r-- | dirmngr/ks-engine.h | 3 | ||||
-rw-r--r-- | dirmngr/server.c | 29 |
7 files changed, 186 insertions, 2 deletions
diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index 3a01b97af..1e575e1e9 100644 --- a/dirmngr/ChangeLog +++ b/dirmngr/ChangeLog @@ -1,3 +1,9 @@ +2011-02-08 Werner Koch <wk@g10code.com> + + * server.c (cmd_ks_fetch): New. + * ks-action.c (ks_action_fetch): New. + * ks-engine-finger.c: New. + 2011-02-03 Werner Koch <wk@g10code.com> * Makefile.am (dirmngr_LDADD): Remove -llber. diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index d5aecc7ab..a030f3861 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -50,7 +50,8 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ ldapserver.h ldapserver.c certcache.c certcache.h \ cdb.h cdblib.c ldap.c misc.c dirmngr-err.h w32-ldap-help.h \ ocsp.c ocsp.h validate.c validate.h ldap-wrapper.h $(ldap_url) \ - ks-action.c ks-action.h ks-engine.h ks-engine-hkp.c + ks-action.c ks-action.h ks-engine.h \ + ks-engine-hkp.c ks-engine-finger.c if USE_LDAPWRAPPER dirmngr_SOURCES += ldap-wrapper.c diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 50f0d5063..dff49979f 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -132,7 +132,7 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) else { err = copy_stream (infp, outfp); - /* Reading from the keyserver should nver fail, thus + /* Reading from the keyserver should never fail, thus return this error. */ es_fclose (infp); infp = NULL; @@ -149,6 +149,49 @@ ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp) } +/* Retrive keys from URL and write the result to the provided output + stream OUTFP. */ +gpg_error_t +ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) +{ + gpg_error_t err = 0; + estream_t infp; + parsed_uri_t parsed_uri; /* The broken down URI. */ + + if (!url) + return gpg_error (GPG_ERR_INV_URI); + + err = http_parse_uri (&parsed_uri, url, 1); + if (err) + return err; + + if (parsed_uri->is_http) + { + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + else if (!parsed_uri->opaque) + { + err = gpg_error (GPG_ERR_INV_URI); + } + else if (!strcmp (parsed_uri->scheme, "finger")) + { + err = ks_finger_get (ctrl, parsed_uri, &infp); + if (!err) + { + err = copy_stream (infp, outfp); + /* Reading from the finger serrver should not fail, thus + return this error. */ + es_fclose (infp); + } + } + else + err = gpg_error (GPG_ERR_INV_URI); + + http_release_parsed_uri (parsed_uri); + return err; +} + + /* Send an OpenPGP key to all keyservers. The key in {DATA,DATALEN} is expected in OpenPGP binary transport format. */ diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h index b3bd3fc46..bba53bc04 100644 --- a/dirmngr/ks-action.h +++ b/dirmngr/ks-action.h @@ -22,6 +22,7 @@ gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp); gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp); +gpg_error_t ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp); gpg_error_t ks_action_put (ctrl_t ctrl, const void *data, size_t datalen); diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c new file mode 100644 index 000000000..c54e34351 --- /dev/null +++ b/dirmngr/ks-engine-finger.c @@ -0,0 +1,101 @@ +/* ks-engine-finger.c - HKP keyserver engine + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "dirmngr.h" +#include "misc.h" +#include "userids.h" +#include "ks-engine.h" + + +/* Get the key from URI which is expected to specify a finger scheme. + On success R_FP has an open stream to read the data. */ +gpg_error_t +ks_finger_get (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp) +{ + gpg_error_t err; + estream_t fp; + char *server; + char *name; + http_t http; + + (void)ctrl; + *r_fp = NULL; + + if (strcmp (uri->scheme, "finger") || !uri->opaque || !uri->path) + return gpg_error (GPG_ERR_INV_ARG); + + name = xtrystrdup (uri->path); + if (!name) + return gpg_error_from_syserror (); + + server = strchr (name, '@'); + if (!server) + { + err = gpg_error (GPG_ERR_INV_URI); + xfree (name); + return err; + } + *server++ = 0; + + err = http_raw_connect (&http, server, 79, 0, NULL); + if (err) + { + xfree (name); + return err; + } + + fp = http_get_write_ptr (http); + if (!fp) + { + err = gpg_error (GPG_ERR_INTERNAL); + http_close (http, 0); + xfree (name); + return err; + } + + if (es_fputs (name, fp) || es_fputs ("\r\n", fp) || es_fflush (fp)) + { + err = gpg_error_from_syserror (); + http_close (http, 0); + xfree (name); + return err; + } + xfree (name); + es_fclose (fp); + + fp = http_get_read_ptr (http); + if (!fp) + { + err = gpg_error (GPG_ERR_INTERNAL); + http_close (http, 0); + return err; + } + + http_close (http, 1 /* Keep read ptr. */); + + *r_fp = fp; + return 0; +} diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h index 304fc4d1a..50f42be4b 100644 --- a/dirmngr/ks-engine.h +++ b/dirmngr/ks-engine.h @@ -31,6 +31,9 @@ gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, gpg_error_t ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen); +/*-- ks-engine-finger.c --*/ +gpg_error_t ks_finger_get (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp); + #endif /*DIRMNGR_KS_ENGINE_H*/ diff --git a/dirmngr/server.c b/dirmngr/server.c index 86b21b67b..403a13692 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1541,6 +1541,34 @@ cmd_ks_get (assuan_context_t ctx, char *line) } +static const char hlp_ks_fetch[] = + "KS_FETCH <URL>\n" + "\n" + "Get the key(s) from URL."; +static gpg_error_t +cmd_ks_fetch (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + estream_t outfp; + + /* No options for now. */ + line = skip_options (line); + + /* Setup an output stream and perform the get. */ + outfp = es_fopencookie (ctx, "w", data_line_cookie_functions); + if (!outfp) + err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); + else + { + err = ks_action_fetch (ctrl, line, outfp); + es_fclose (outfp); + } + + return leave_cmd (ctx, err); +} + + static const char hlp_ks_put[] = "KS_PUT\n" @@ -1742,6 +1770,7 @@ register_commands (assuan_context_t ctx) { "KEYSERVER", cmd_keyserver, hlp_keyserver }, { "KS_SEARCH", cmd_ks_search, hlp_ks_search }, { "KS_GET", cmd_ks_get, hlp_ks_get }, + { "KS_FETCH", cmd_ks_fetch, hlp_ks_fetch }, { "KS_PUT", cmd_ks_put, hlp_ks_put }, { "GETINFO", cmd_getinfo, hlp_getinfo }, { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr }, |