diff --git a/dirmngr/ChangeLog b/dirmngr/ChangeLog index 757eb78ac..ac71bdd6c 100644 --- a/dirmngr/ChangeLog +++ b/dirmngr/ChangeLog @@ -1,5 +1,15 @@ 2011-02-09 Werner Koch + * ks-engine-kdns.c: New. Based on the former gpgkeys_kdns. + + * server.c (cmd_keyserver): Add option --help. + (dirmngr_status_help): New. + * ks-action.c (ks_print_help): New. + (ks_action_help): New. + * ks-engine-finger.c (ks_finger_help): New. + * ks-engine-http.c (ks_http_help): New. + * ks-engine-hkp.c (ks_hkp_help): New. + * ks-action.c (ks_action_fetch): Support http URLs. * ks-engine-http.c: New. diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 6b27c7abc..6bdb5985e 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -51,7 +51,7 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ 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-engine-http.c ks-engine-finger.c + ks-engine-hkp.c ks-engine-http.c ks-engine-finger.c ks-engine-kdns.c if USE_LDAPWRAPPER dirmngr_SOURCES += ldap-wrapper.c diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index de243ee25..4f5cbd1d7 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -192,6 +192,7 @@ ksba_cert_t get_cert_local_ski (ctrl_t ctrl, gpg_error_t get_istrusted_from_client (ctrl_t ctrl, const char *hexfpr); void start_command_handler (gnupg_fd_t fd); gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...); +gpg_error_t dirmngr_status_help (ctrl_t ctrl, const char *text); gpg_error_t dirmngr_tick (ctrl_t ctrl); diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index ec691fe2a..1f876d07b 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -49,6 +49,50 @@ copy_stream (estream_t in, estream_t out) } +/* Called by the engine's help functions to print the actual help. */ +gpg_error_t +ks_print_help (ctrl_t ctrl, const char *text) +{ + return dirmngr_status_help (ctrl, text); +} + + +/* Run the help command for the engine responsible for URI. */ +gpg_error_t +ks_action_help (ctrl_t ctrl, const char *url) +{ + gpg_error_t err; + parsed_uri_t parsed_uri; /* The broken down URI. */ + + if (!url || !*url) + { + ks_print_help (ctrl, "Known schemata:\n"); + parsed_uri = NULL; + } + else + { + err = http_parse_uri (&parsed_uri, url, 1); + if (err) + return err; + } + + /* Call all engines to geive them a chance to print a help sting. */ + err = ks_hkp_help (ctrl, parsed_uri); + if (!err) + err = ks_http_help (ctrl, parsed_uri); + if (!err) + err = ks_finger_help (ctrl, parsed_uri); + if (!err) + err = ks_kdns_help (ctrl, parsed_uri); + + if (!parsed_uri) + ks_print_help (ctrl, + "(Use the schema followed by a colon for specific help.)"); + else + http_release_parsed_uri (parsed_uri); + return err; +} + /* Search all configured keyservers for keys matching PATTERNS and write the result to the provided output stream. */ @@ -187,6 +231,15 @@ ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp) es_fclose (infp); } } + else if (!strcmp (parsed_uri->scheme, "kdns")) + { + err = ks_kdns_fetch (ctrl, parsed_uri, &infp); + if (!err) + { + err = copy_stream (infp, outfp); + es_fclose (infp); + } + } else err = gpg_error (GPG_ERR_INV_URI); diff --git a/dirmngr/ks-action.h b/dirmngr/ks-action.h index bba53bc04..3dca90f16 100644 --- a/dirmngr/ks-action.h +++ b/dirmngr/ks-action.h @@ -20,6 +20,7 @@ #ifndef DIRMNGR_KS_ACTION_H #define DIRMNGR_KS_ACTION_H 1 +gpg_error_t ks_action_help (ctrl_t ctrl, const char *url); 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); diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c index c9e897f84..57dd340e8 100644 --- a/dirmngr/ks-engine-finger.c +++ b/dirmngr/ks-engine-finger.c @@ -29,6 +29,28 @@ #include "userids.h" #include "ks-engine.h" +/* Print a help output for the schemata supported by this module. */ +gpg_error_t +ks_finger_help (ctrl_t ctrl, parsed_uri_t uri) +{ + char const data[] = + "Handler for FINGER:\n" + " finger:@\n" + "Supported methods: fetch\n" + "Example:\n" + " finger:joe@example.org\n"; + gpg_error_t err; + + if (!uri) + err = ks_print_help (ctrl, " finger"); + else if (!strcmp (uri->scheme, "finger")) + err = ks_print_help (ctrl, data); + else + err = 0; + + return err; +} + /* 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. */ diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 3467a6df3..5ad61fd4d 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -36,6 +36,26 @@ /* How many redirections do we allow. */ #define MAX_REDIRECTS 2 +/* Print a help output for the schemata supported by this module. */ +gpg_error_t +ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri) +{ + const char const data[] = + "Handler for HKP URLs:\n" + " hkp://\n" + "Supported methods: search, get, put\n"; + gpg_error_t err; + + if (!uri) + err = ks_print_help (ctrl, " hkp"); + else if (uri->is_http) + err = ks_print_help (ctrl, data); + else + err = 0; + + return err; +} + /* Send an HTTP request. On success returns an estream object at R_FP. HOSTPORTSTR is only used for diagnostics. If POST_CB is not diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 304e793f7..2ce1b19a1 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -31,6 +31,26 @@ /* How many redirections do we allow. */ #define MAX_REDIRECTS 2 +/* Print a help output for the schemata supported by this module. */ +gpg_error_t +ks_http_help (ctrl_t ctrl, parsed_uri_t uri) +{ + const char const data[] = + "Handler for HTTP URLs:\n" + " http://\n" + "Supported methods: fetch\n"; + gpg_error_t err; + + if (!uri) + err = ks_print_help (ctrl, " http"); + else if (uri->is_http) + err = ks_print_help (ctrl, data); + else + err = 0; + + return err; +} + /* Get the key from URL which is expected to specify a http style scheme. On success R_FP has an open stream to read the data. */ diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h index 9d2afdf85..8b5514473 100644 --- a/dirmngr/ks-engine.h +++ b/dirmngr/ks-engine.h @@ -23,7 +23,11 @@ #include "../common/estream.h" #include "../common/http.h" +/*-- ks-action.c --*/ +gpg_error_t ks_print_help (ctrl_t ctrl, const char *text); + /*-- ks-engine-hkp.c --*/ +gpg_error_t ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri); gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, estream_t *r_fp); gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, @@ -32,12 +36,18 @@ gpg_error_t ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen); /*-- ks-engine-http.c --*/ +gpg_error_t ks_http_help (ctrl_t ctrl, parsed_uri_t uri); gpg_error_t ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp); /*-- ks-engine-finger.c --*/ +gpg_error_t ks_finger_help (ctrl_t ctrl, parsed_uri_t uri); gpg_error_t ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp); +/*-- ks-engine-kdns.c --*/ +gpg_error_t ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri); +gpg_error_t ks_kdns_fetch (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 403a13692..1a244c896 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1359,7 +1359,7 @@ cmd_validate (assuan_context_t ctx, char *line) static const char hlp_keyserver[] = - "KEYSERVER [--clear] []\n" + "KEYSERVER [--clear|--help] []\n" "\n" "If called without arguments list all configured keyserver URLs.\n" "If called with option \"--clear\" remove all configured keyservers\n" @@ -1374,14 +1374,21 @@ cmd_keyserver (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; - int clear_flag, add_flag; + int clear_flag, add_flag, help_flag; uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it is always initialized. */ clear_flag = has_option (line, "--clear"); + help_flag = has_option (line, "--help"); line = skip_options (line); add_flag = !!*line; + if (help_flag) + { + err = ks_action_help (ctrl, line); + goto leave; + } + if (add_flag) { item = xtrymalloc (sizeof *item + strlen (line)); @@ -1409,7 +1416,7 @@ cmd_keyserver (assuan_context_t ctx, char *line) ctrl->keyservers = item; } - if (!add_flag && !clear_flag) /* List configured keyservers. */ + if (!add_flag && !clear_flag && !help_flag) /* List configured keyservers. */ { uri_item_t u; @@ -1947,7 +1954,7 @@ start_command_handler (assuan_fd_t fd) /* Send a status line back to the client. KEYWORD is the status - keyword, the optioal string argumenst are blank separated added to + keyword, the optional string arguments are blank separated added to the line, the last argument must be a NULL. */ gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...) @@ -1985,6 +1992,36 @@ dirmngr_status (ctrl_t ctrl, const char *keyword, ...) } +/* Print a help status line. TEXTLEN gives the length of the text + from TEXT to be printed. The function splits text at LFs. */ +gpg_error_t +dirmngr_status_help (ctrl_t ctrl, const char *text) +{ + gpg_error_t err = 0; + + if (ctrl->server_local) + { + assuan_context_t ctx = ctrl->server_local->assuan_ctx; + char buf[950], *p; + size_t n; + + do + { + p = buf; + n = 0; + for ( ; *text && *text != '\n' && n < DIM (buf)-2; n++) + *p++ = *text++; + if (*text == '\n') + text++; + *p = 0; + err = assuan_write_status (ctx, "#", buf); + } + while (!err && *text); + } + + return err; +} + /* Send a tick progress indicator back. Fixme: This is only does for the currently active channel. */ gpg_error_t