From 4a3836e2b2f9a91995d5ce058820e1121298f548 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 17 Dec 2020 18:18:52 +0100 Subject: [PATCH] gpg: New AKL method "ntds" * dirmngr/ks-engine-ldap.c (keyspec_to_ldap_filter): Change the new support for KEYDB_SEARCH_MODE_MAIL. (ks_ldap_get): Add a debug. * g10/options.h (AKL_NTDS): New. * g10/keyserver.c (keyserver_import_ntds): New. (keyserver_get_chunk): Allow KEYDB_SEARCH_MODE_MAIL. * g10/getkey.c (parse_auto_key_locate): Support "ntds". (get_pubkey_byname): Ditto. --- dirmngr/ks-engine-ldap.c | 25 +++++++++++++++++++------ doc/gpg.texi | 3 +++ g10/getkey.c | 9 +++++++++ g10/gpgv.c | 11 +++++++++++ g10/keyserver-internal.h | 2 ++ g10/keyserver.c | 34 ++++++++++++++++++++++++++++++++++ g10/options.h | 1 + g10/test-stubs.c | 11 +++++++++++ 8 files changed, 90 insertions(+), 6 deletions(-) diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 7dfd7ea94..9b65a5dda 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -343,6 +343,7 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact, KEYDB_SEARCH_DESC desc; char *f = NULL; char *freeme = NULL; + char *p; gpg_error_t err = classify_user_id (keyspec, &desc, 1); if (err) @@ -362,14 +363,24 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact, break; case KEYDB_SEARCH_MODE_MAIL: - if (only_exact) + freeme = ldap_escape_filter (desc.u.name); + if (!freeme) break; - if ((serverinfo & SERVERINFO_SCHEMAV2)) - f = xasprintf ("(gpgMailbox=%s)", - (freeme = ldap_escape_filter (desc.u.name))); + if (*freeme == '<' && freeme[1] && freeme[2]) + { + /* Strip angle brackets. Note that it is does not + * matter whether we work on the plan or LDAP escaped + * version of the mailbox. */ + p = freeme + 1; + if (p[strlen(p)-1] == '>') + p[strlen(p)-1] = 0; + } else - f = xasprintf ("(pgpUserID=*<%s>*)", - (freeme = ldap_escape_filter (desc.u.name))); + p = freeme; + if ((serverinfo & SERVERINFO_SCHEMAV2)) + f = xasprintf ("(gpgMailbox=%s)", p); + else if (!only_exact) + f = xasprintf ("(pgpUserID=*<%s>*)", p); break; case KEYDB_SEARCH_MODE_MAILSUB: @@ -934,6 +945,8 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, if (err) goto out; + if (opt.debug) + log_debug ("ks-ldap: using filter: %s\n", filter); { /* The ordering is significant. Specifically, "pgpcertid" needs diff --git a/doc/gpg.texi b/doc/gpg.texi index 9f12fbc88..ccf1a2a5c 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1825,6 +1825,9 @@ list. The default is "local,wkd". keyservers to use. If this fails, attempt to locate the key using the PGP Universal method of checking @samp{ldap://keys.(thedomain)}. + @item ntds + Locate the key using the Active Directory (Windows only). + @item keyserver Locate a key using a keyserver. diff --git a/g10/getkey.c b/g10/getkey.c index a0b71407a..85c7d3fdd 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1107,6 +1107,13 @@ get_pubkey_byname (ctrl_t ctrl, enum get_pubkey_modes mode, glo_ctrl.in_auto_key_retrieve--; break; + case AKL_NTDS: + mechanism_string = "NTDS"; + glo_ctrl.in_auto_key_retrieve++; + rc = keyserver_import_ntds (ctrl, name, &fpr, &fpr_len); + glo_ctrl.in_auto_key_retrieve--; + break; + case AKL_KEYSERVER: /* Strictly speaking, we don't need to only use a valid * mailbox for the getname search, but it helps cut down @@ -4152,6 +4159,8 @@ parse_auto_key_locate (const char *options_arg) akl->type = AKL_DANE; else if (ascii_strcasecmp (tok, "wkd") == 0) akl->type = AKL_WKD; + else if (ascii_strcasecmp (tok, "ntds") == 0) + akl->type = AKL_NTDS; else if ((akl->spec = parse_keyserver_uri (tok, 1))) akl->type = AKL_SPEC; else diff --git a/g10/gpgv.c b/g10/gpgv.c index 9f8dca82f..f80458db4 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -478,6 +478,17 @@ keyserver_import_name (const char *name,struct keyserver_spec *spec) return -1; } +int +keyserver_import_ntds (ctrl_t ctrl, const char *mbox, + unsigned char **fpr, size_t *fprlen) +{ + (void)ctrl; + (void)mbox; + (void)fpr; + (void)fprlen; + return -1; +} + int keyserver_import_ldap (const char *name) { diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index 46a1e1d9f..f5f7f3620 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -47,6 +47,8 @@ gpg_error_t keyserver_import_pka (ctrl_t ctrl, const char *name, unsigned char **fpr,size_t *fpr_len); gpg_error_t keyserver_import_wkd (ctrl_t ctrl, const char *name, int quick, unsigned char **fpr, size_t *fpr_len); +int keyserver_import_ntds (ctrl_t ctrl, const char *name, + unsigned char **fpr,size_t *fpr_len); int keyserver_import_name (ctrl_t ctrl, const char *name,unsigned char **fpr,size_t *fpr_len, struct keyserver_spec *keyserver); diff --git a/g10/keyserver.c b/g10/keyserver.c index bae604d10..f42bca15c 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1141,6 +1141,21 @@ keyserver_import_name (ctrl_t ctrl, const char *name, } +/* Import the keys that match exactly MBOX */ +int +keyserver_import_ntds (ctrl_t ctrl, const char *mbox, + unsigned char **fpr, size_t *fprlen) +{ + KEYDB_SEARCH_DESC desc = { 0 }; + struct keyserver_spec keyserver = { NULL, "ldap:///" }; + + desc.mode = KEYDB_SEARCH_MODE_MAIL; + desc.u.name = mbox; + + return keyserver_get (ctrl, &desc, 1, &keyserver, 0, fpr, fprlen); +} + + int keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len, struct keyserver_spec *keyserver, int quick) @@ -1669,6 +1684,25 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, quiet = 1; } } + else if(desc[idx].mode == KEYDB_SEARCH_MODE_MAIL) + { + n = 1 + strlen (desc[idx].u.name) + 1 + 1; + if (idx && linelen + n > MAX_KS_GET_LINELEN) + break; /* Declare end of this chunk. */ + linelen += n; + + if (desc[idx].u.name[0] == '<') + pattern[npat] = xtrystrdup (desc[idx].u.name); + else + pattern[npat] = strconcat ("<", desc[idx].u.name, ">", NULL); + if (!pattern[npat]) + err = gpg_error_from_syserror (); + else + { + npat++; + quiet = 1; + } + } else if (desc[idx].mode == KEYDB_SEARCH_MODE_NONE) continue; else diff --git a/g10/options.h b/g10/options.h index b014514e5..2f4a76960 100644 --- a/g10/options.h +++ b/g10/options.h @@ -265,6 +265,7 @@ struct AKL_DANE, AKL_WKD, AKL_LDAP, + AKL_NTDS, AKL_KEYSERVER, AKL_SPEC } type; diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 9542d318b..f7b6a22ad 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -236,6 +236,17 @@ keyserver_import_name (const char *name,struct keyserver_spec *spec) return -1; } +int +keyserver_import_ntds (ctrl_t ctrl, const char *mbox, + unsigned char **fpr, size_t *fprlen) +{ + (void)ctrl; + (void)mbox; + (void)fpr; + (void)fprlen; + return -1; +} + int keyserver_import_ldap (const char *name) {