diff options
Diffstat (limited to '')
-rw-r--r-- | g10/cpr.c | 13 | ||||
-rw-r--r-- | g10/export.c | 11 | ||||
-rw-r--r-- | g10/gpg.c | 4 | ||||
-rw-r--r-- | g10/keyedit.c | 13 | ||||
-rw-r--r-- | g10/keyedit.h | 3 | ||||
-rw-r--r-- | g10/keygen.c | 19 | ||||
-rw-r--r-- | g10/keyserver-internal.h | 4 | ||||
-rw-r--r-- | g10/keyserver.c | 58 | ||||
-rw-r--r-- | g10/main.h | 2 | ||||
-rw-r--r-- | g10/options.h | 5 |
10 files changed, 112 insertions, 20 deletions
@@ -280,6 +280,19 @@ write_status_printf (int no, const char *format, ...) g10_exit (0); } +/* Write a WARNING status line using a full gpg-error error value. */ +void +write_status_warning (const char *where, gpg_error_t err) +{ + if (!statusfp || !status_currently_allowed (STATUS_WARNING)) + return; /* Not enabled or allowed. */ + + es_fprintf (statusfp, "[GNUPG:] %s %s %u\n", + get_status_string (STATUS_WARNING), where, err); + if (es_fflush (statusfp) && opt.exit_on_status_write_error) + g10_exit (0); +} + /* Write an ERROR status line using a full gpg-error error value. */ void diff --git a/g10/export.c b/g10/export.c index ffc37297c..5dcb9c665 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1403,7 +1403,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) /* Print an "EXPORTED" status line. PK is the primary public key. */ -static void +void print_status_exported (PKT_public_key *pk) { char *hexfpr; @@ -2018,7 +2018,8 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY) { stats->exported++; - print_status_exported (node->pkt->pkt.public_key); + if (!(options & EXPORT_NO_STATUS)) + print_status_exported (node->pkt->pkt.public_key); } } else if (!err) @@ -2054,7 +2055,8 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, if (node->pkt->pkttype == PKT_PUBLIC_KEY) { stats->exported++; - print_status_exported (node->pkt->pkt.public_key); + if (!(options & EXPORT_NO_STATUS)) + print_status_exported (node->pkt->pkt.public_key); } } } @@ -2088,7 +2090,8 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY) { stats->exported++; - print_status_exported (node->pkt->pkt.public_key); + if (!(options & EXPORT_NO_STATUS)) + print_status_exported (node->pkt->pkt.public_key); } } @@ -379,6 +379,7 @@ enum cmd_and_opt_values oNoAutoKeyRetrieve, oAutoKeyImport, oNoAutoKeyImport, + oAutoKeyUpload, oUseAgent, oNoUseAgent, oGpgAgentInfo, @@ -808,6 +809,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoAutoKeyImport, "no-auto-key-import", "@"), ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"), ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"), + ARGPARSE_s_n (oAutoKeyUpload, "auto-key-upload", "@"), ARGPARSE_s_n (oIncludeKeyBlock, "include-key-block", N_("include the public key in signatures")), ARGPARSE_s_n (oNoIncludeKeyBlock, "no-include-key-block", "@"), @@ -3606,6 +3608,8 @@ main (int argc, char **argv) opt.keyserver_options.options &= ~KEYSERVER_AUTO_KEY_RETRIEVE; break; + case oAutoKeyUpload: opt.flags.auto_key_upload = 1; break; + case oShowOnlySessionKey: opt.show_only_session_key = 1; /* fallthru */ diff --git a/g10/keyedit.c b/g10/keyedit.c index 0a5064a25..12e127452 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -5053,11 +5053,13 @@ fail: /* Core function to add an ADSK to the KEYBLOCK. Returns 0 on success - * or an error code. CACHE_NONCE can be used to avoid a second - * Pinetry pop-up for appending the ADSK. */ + * or an error code. If SIGTIMESTAMP is not 0 it is used for the key + * binding signature creation time; if not given the current time is + * used. CACHE_NONCE can be used to avoid a second Pinetry pop-up for + * appending the ADSK. */ gpg_error_t append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *adsk, - const char *cache_nonce) + u32 sigtimestamp, const char *cache_nonce) { gpg_error_t err; PKT_public_key *main_pk; /* The primary key. */ @@ -5102,7 +5104,7 @@ append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *adsk, /* Make the signature. */ err = make_keysig_packet (ctrl, &sig, main_pk, NULL, adsk, main_pk, 0x18, - adsk->timestamp, 0, + sigtimestamp, 0, keygen_add_key_flags_and_expire, adsk, cache_nonce); adsk = NULL; /* (owned by adsknode - avoid double free.) */ if (err) @@ -5150,6 +5152,7 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr) byte fpr[MAX_FINGERPRINT_LEN]; size_t fprlen; kbnode_t node; + u32 sigtimestamp = make_timestamp (); log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); @@ -5251,7 +5254,7 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr) log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY || node->pkt->pkttype == PKT_PUBLIC_SUBKEY); err = append_adsk_to_key (ctrl, pub_keyblock, node->pkt->pkt.public_key, - NULL); + sigtimestamp, NULL); leave: diff --git a/g10/keyedit.h b/g10/keyedit.h index 5d8be078e..d37bcb23b 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -61,7 +61,8 @@ void keyedit_quick_update_pref (ctrl_t ctrl, const char *username); void keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, const char *value); gpg_error_t append_adsk_to_key (ctrl_t ctrl, kbnode_t keyblock, - PKT_public_key *adsk, const char *cache_nonce); + PKT_public_key *adsk, + u32 sigtimestamp, const char *cache_nonce); void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock, int print_sec); int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, int rc, kbnode_t keyblock, diff --git a/g10/keygen.c b/g10/keygen.c index 349149b8a..1f4388f39 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1263,6 +1263,7 @@ append_all_default_adsks (ctrl_t ctrl, kbnode_t keyblock) struct para_data_s *para; byte adskfpr[MAX_FINGERPRINT_LEN]; size_t adskfprlen; + u32 sigtimestamp = make_timestamp (); keygen_prepare_new_key_adsks (); for (sl = opt.def_new_key_adsks; sl && !err; sl = sl->next) @@ -1275,7 +1276,10 @@ append_all_default_adsks (ctrl_t ctrl, kbnode_t keyblock) fingerprint_from_pk (para->u.adsk, adskfpr, &adskfprlen); if (!has_key_with_fingerprint (keyblock, adskfpr, adskfprlen)) { - err = append_adsk_to_key (ctrl, keyblock, para->u.adsk, NULL); + /* Fixme: We should use a cache nonce so that only one + * pinentry pops up. */ + err = append_adsk_to_key (ctrl, keyblock, para->u.adsk, + sigtimestamp, NULL); if (!err) any_done = 1; } @@ -6629,7 +6633,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, for (idx=0; (adsk = get_parameter_adsk (para, idx)); idx++) { - err = append_adsk_to_key (ctrl, pub_root, adsk, cache_nonce); + err = append_adsk_to_key (ctrl, pub_root, adsk, + signtimestamp, cache_nonce); if (err) break; any_adsk++; @@ -6740,6 +6745,16 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, es_fflush (es_stdout); if (any_adsk) log_info (_("Note: The key has been created with one or more ADSK!\n")); + + if (opt.flags.auto_key_upload) + { + unsigned int saved_options = opt.keyserver_options.options; + + opt.keyserver_options.options |= KEYSERVER_LDAP_ONLY; + opt.keyserver_options.options |= KEYSERVER_WARN_ONLY; + keyserver_export_pubkey (ctrl, pk, 1/*Assume new key*/); + opt.keyserver_options.options = saved_options; + } } release_kbnode (pub_root); diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index 9506fd015..83d36b6bb 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -38,7 +38,11 @@ struct keyserver_spec *parse_keyserver_uri (const char *string, int require_scheme); struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig); int keyserver_any_configured (ctrl_t ctrl); + gpg_error_t keyserver_export (ctrl_t ctrl, strlist_t users, int assume_new_key); +gpg_error_t keyserver_export_pubkey (ctrl_t ctrl, PKT_public_key *pk, + int assume_new_key); + gpg_error_t keyserver_import (ctrl_t ctrl, strlist_t users, unsigned int flags); int keyserver_import_fpr (ctrl_t ctrl, const byte *fprint,size_t fprint_len, struct keyserver_spec *keyserver, diff --git a/g10/keyserver.c b/g10/keyserver.c index bdfbde5c3..99a5e350a 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -829,6 +829,27 @@ keyserver_export (ctrl_t ctrl, strlist_t users, int assume_new_key) } +/* Send the public key specified by PK to the configured keyserver. + * If ASSUME_NEW_KEY is true the KEYSERVER_UPDATE_BEFORE_SEND option + * will be ignored. */ +gpg_error_t +keyserver_export_pubkey (ctrl_t ctrl, PKT_public_key *pk, int assume_new_key) +{ + gpg_error_t err; + strlist_t keyspec = NULL; + char fpr[2*MAX_FINGERPRINT_LEN+1]; + + hexfingerprint (pk, fpr, sizeof fpr); + add_to_strlist (&keyspec, fpr); + err = keyserver_put (ctrl, keyspec, assume_new_key); + free_strlist (keyspec); + + return err; +} + + + + /* Structure to convey the arg to keyserver_retrieval_screener. */ struct ks_retrieval_screener_arg_s { @@ -1608,13 +1629,15 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, /* Send all keys specified by KEYSPECS to the configured keyserver. * If ASSUME_NEW_KEY is true the KEYSERVER_UPDATE_BEFORE_SEND option - * will be ignored. */ + * will be ignored. */ static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs, int assume_new_key) { gpg_error_t err; strlist_t kspec; char *ksurl; + int warn_only = !!(opt.keyserver_options.options & KEYSERVER_WARN_ONLY); + int loglvl = warn_only? GPGRT_LOGLVL_INFO : GPGRT_LOGLVL_ERROR; if (!keyspecs) return 0; /* Return success if the list is empty. */ @@ -1622,10 +1645,21 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs, int assume_new_key) /* Get the name of the used keyservers. */ if (gpg_dirmngr_ks_list (ctrl, &ksurl)) { - log_error (_("no keyserver known\n")); + gpgrt_log (loglvl, _("no keyserver known\n")); return gpg_error (GPG_ERR_NO_KEYSERVER); } + /* Check the LDAP only flag */ + if ((opt.keyserver_options.options & KEYSERVER_LDAP_ONLY) + && !(ksurl && (!strncmp (ksurl, "ldap:", 5) + || !strncmp (ksurl, "ldaps:", 6)))) + { + if (opt.verbose) + log_info (_("upload skipped due to non-LDAP keyserver\n")); + err = 0; + goto leave; + } + /* If the option is active, we first try to import the keys given by * fingerprint from the keyserver. For example, if some PKI server * has signed a key and the user has not yet imported that updated @@ -1656,11 +1690,13 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs, int assume_new_key) kbnode_t keyblock; err = export_pubkey_buffer (ctrl, kspec->d, - opt.keyserver_options.export_options, + (opt.keyserver_options.export_options + | EXPORT_NO_STATUS), NULL, 0, NULL, &keyblock, &data, &datalen); if (err) - log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err)); + gpgrt_log (loglvl, _("skipped \"%s\": %s\n"), + kspec->d, gpg_strerror (err)); else { if (!opt.quiet) @@ -1669,18 +1705,24 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs, int assume_new_key) ksurl?ksurl:"[?]"); err = gpg_dirmngr_ks_put (ctrl, data, datalen, keyblock); - release_kbnode (keyblock); xfree (data); if (err) { - write_status_error ("keyserver_send", err); - log_error (_("keyserver send failed: %s\n"), gpg_strerror (err)); + if (warn_only) + write_status_warning ("keyserver_send", err); + else + write_status_error ("keyserver_send", err); + gpgrt_log (loglvl, _("keyserver send failed: %s\n"), + gpg_strerror (err)); } + else /* On success print a status line. */ + print_status_exported (keyblock->pkt->pkt.public_key); + release_kbnode (keyblock); } } + leave: xfree (ksurl); - return err; } diff --git a/g10/main.h b/g10/main.h index 5d96b5e27..ab01091d0 100644 --- a/g10/main.h +++ b/g10/main.h @@ -202,6 +202,7 @@ unsigned int ecdsa_qbits_from_Q (unsigned int qbits); void set_status_fd ( int fd ); int is_status_enabled ( void ); void write_status ( int no ); +void write_status_warning (const char *where, gpg_error_t err); void write_status_error (const char *where, gpg_error_t err); void write_status_errcode (const char *where, int errcode); void write_status_failure (const char *where, gpg_error_t err); @@ -419,6 +420,7 @@ typedef struct export_stats_s *export_stats_t; export_stats_t export_new_stats (void); void export_release_stats (export_stats_t stats); void export_print_stats (export_stats_t stats); +void print_status_exported (PKT_public_key *pk); int parse_export_options(char *str,unsigned int *options,int noisy); gpg_error_t parse_and_set_export_filter (const char *string); diff --git a/g10/options.h b/g10/options.h index c7f21086c..5512ecb11 100644 --- a/g10/options.h +++ b/g10/options.h @@ -286,6 +286,8 @@ struct unsigned int disable_signer_uid:1; unsigned int include_key_block:1; unsigned int auto_key_import:1; + /* Option to upload new or modified keys to an LDAP server. */ + unsigned int auto_key_upload:1; /* Flag to enable experimental features from RFC4880bis. */ unsigned int rfc4880bis:1; /* Hack: --output is not given but OUTFILE was temporary set to "-". */ @@ -445,6 +447,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define EXPORT_REVOCS (1<<11) #define EXPORT_MODE1003 (1<<12) #define EXPORT_REALCLEAN (1<<13) +#define EXPORT_NO_STATUS (1<<20) /*Do not emit status lines.*/ #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) @@ -487,6 +490,8 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define KEYSERVER_AUTO_KEY_RETRIEVE (1<<3) #define KEYSERVER_HONOR_KEYSERVER_URL (1<<4) #define KEYSERVER_UPDATE_BEFORE_SEND (1<<5) +#define KEYSERVER_LDAP_ONLY (1<<6) /* Use only LDAP servers. */ +#define KEYSERVER_WARN_ONLY (1<<7) /* no error - just warn. */ #endif /*G10_OPTIONS_H*/ |