dirmngr: Allow LDAP searches via fingerprint.

* dirmngr/ks-engine-ldap.c (keyspec_to_ldap_filter): Add arg
serverinfo and allow searching by fingerprint.
(ks_ldap_get, ks_ldap_search): First connect then create teh filter.
--

With the new schema we can finally search by fingerprint.
This commit is contained in:
Werner Koch 2020-12-17 10:20:28 +01:00
parent 2b06afbf26
commit 2cadcce3e8
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 41 additions and 23 deletions

View File

@ -333,7 +333,8 @@ ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri)
*filter. It is the caller's responsibility to free *filter. *filter. It is the caller's responsibility to free *filter.
*filter is only set if this function returns success (i.e., 0). */ *filter is only set if this function returns success (i.e., 0). */
static gpg_error_t static gpg_error_t
keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact,
unsigned int serverinfo)
{ {
/* Remove search type indicator and adjust PATTERN accordingly. /* Remove search type indicator and adjust PATTERN accordingly.
Note: don't include a preceding 0x when searching by keyid. */ Note: don't include a preceding 0x when searching by keyid. */
@ -361,9 +362,14 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact)
break; break;
case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAIL:
if (! only_exact) if (only_exact)
f = xasprintf ("(pgpUserID=*<%s>*)", break;
(freeme = ldap_escape_filter (desc.u.name))); if ((serverinfo & SERVERINFO_SCHEMAV2))
f = xasprintf ("(gpgMailbox=%s)",
(freeme = ldap_escape_filter (desc.u.name)));
else
f = xasprintf ("(pgpUserID=*<%s>*)",
(freeme = ldap_escape_filter (desc.u.name)));
break; break;
case KEYDB_SEARCH_MODE_MAILSUB: case KEYDB_SEARCH_MODE_MAILSUB:
@ -387,6 +393,19 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact)
break; break;
case KEYDB_SEARCH_MODE_FPR: case KEYDB_SEARCH_MODE_FPR:
if ((serverinfo & SERVERINFO_SCHEMAV2))
{
freeme = bin2hex (desc.u.fpr, desc.fprlen, NULL);
if (!freeme)
return gpg_error_from_syserror ();
f = xasprintf ("(|(gpgFingerprint=%s)(gpgSubFingerprint=%s))",
freeme, freeme);
/* FIXME: For an exact search and in case of a match on
* gpgSubFingerprint we need to check that there is only one
* matching value. */
}
break;
case KEYDB_SEARCH_MODE_ISSUER: case KEYDB_SEARCH_MODE_ISSUER:
case KEYDB_SEARCH_MODE_ISSUER_SN: case KEYDB_SEARCH_MODE_ISSUER_SN:
case KEYDB_SEARCH_MODE_SN: case KEYDB_SEARCH_MODE_SN:
@ -872,13 +891,6 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
return gpg_error (GPG_ERR_NOT_SUPPORTED); return gpg_error (GPG_ERR_NOT_SUPPORTED);
} }
/* Before connecting to the server, make sure we have a sane
keyspec. If not, there is no need to establish a network
connection. */
err = keyspec_to_ldap_filter (keyspec, &filter, 1);
if (err)
return (err);
/* Make sure we are talking to an OpenPGP LDAP server. */ /* Make sure we are talking to an OpenPGP LDAP server. */
ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo); ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo);
if (ldap_err || !basedn) if (ldap_err || !basedn)
@ -886,10 +898,17 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
if (ldap_err) if (ldap_err)
err = ldap_err_to_gpg_err (ldap_err); err = ldap_err_to_gpg_err (ldap_err);
else else
err = GPG_ERR_GENERAL; err = gpg_error (GPG_ERR_GENERAL);
goto out; goto out;
} }
/* Now that we have information about the server we can construct a
* query best suited for the capabilities of the server. */
err = keyspec_to_ldap_filter (keyspec, &filter, 1, serverinfo);
if (err)
goto out;
{ {
/* The ordering is significant. Specifically, "pgpcertid" needs /* The ordering is significant. Specifically, "pgpcertid" needs
to be the second item in the list, since everything after it to be the second item in the list, since everything after it
@ -1054,16 +1073,6 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
return gpg_error (GPG_ERR_NOT_SUPPORTED); return gpg_error (GPG_ERR_NOT_SUPPORTED);
} }
/* Before connecting to the server, make sure we have a sane
keyspec. If not, there is no need to establish a network
connection. */
err = keyspec_to_ldap_filter (pattern, &filter, 0);
if (err)
{
log_error ("Bad search pattern: '%s'\n", pattern);
return (err);
}
/* Make sure we are talking to an OpenPGP LDAP server. */ /* Make sure we are talking to an OpenPGP LDAP server. */
ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo); ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo);
if (ldap_err || !basedn) if (ldap_err || !basedn)
@ -1075,6 +1084,15 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
goto out; goto out;
} }
/* Now that we have information about the server we can construct a
* query best suited for the capabilities of the server. */
err = keyspec_to_ldap_filter (pattern, &filter, 0, serverinfo);
if (err)
{
log_error ("Bad search pattern: '%s'\n", pattern);
goto out;
}
/* Even if we have no results, we want to return a stream. */ /* Even if we have no results, we want to return a stream. */
fp = es_fopenmem(0, "rw"); fp = es_fopenmem(0, "rw");
if (!fp) if (!fp)
@ -1911,7 +1929,7 @@ ks_ldap_put (ctrl_t ctrl, parsed_uri_t uri,
const char *infoend = (const char *) info + infolen - 1; const char *infoend = (const char *) info + infolen - 1;
/* Enable this code to dump the modlist to /tmp/modlist.txt. */ /* Enable this code to dump the modlist to /tmp/modlist.txt. */
#if 1 #if 0
# warning Disable debug code before checking in. # warning Disable debug code before checking in.
const int dump_modlist = 1; const int dump_modlist = 1;
#else #else