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 c28cb5282b
commit c75fd75532
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 40 additions and 22 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 is only set if this function returns success (i.e., 0). */
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.
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;
case KEYDB_SEARCH_MODE_MAIL:
if (! only_exact)
f = xasprintf ("(pgpUserID=*<%s>*)",
(freeme = ldap_escape_filter (desc.u.name)));
if (only_exact)
break;
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;
case KEYDB_SEARCH_MODE_MAILSUB:
@ -389,6 +395,19 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact)
case KEYDB_SEARCH_MODE_FPR16:
case KEYDB_SEARCH_MODE_FPR20:
case KEYDB_SEARCH_MODE_FPR:
if ((serverinfo & SERVERINFO_SCHEMAV2))
{
freeme = bin2hex (desc.u.fpr, 20, 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_SN:
case KEYDB_SEARCH_MODE_SN:
@ -874,13 +893,6 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
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. */
ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo);
if (ldap_err || !basedn)
@ -888,10 +900,17 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec,
if (ldap_err)
err = ldap_err_to_gpg_err (ldap_err);
else
err = GPG_ERR_GENERAL;
err = gpg_error (GPG_ERR_GENERAL);
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
to be the second item in the list, since everything after it
@ -1056,16 +1075,6 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
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. */
ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo);
if (ldap_err || !basedn)
@ -1077,6 +1086,15 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
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. */
fp = es_fopenmem(0, "rw");
if (!fp)