gss: merge gss_name_to_oid and gss_mg_name_to_oid

The recently introduced gss_mg_name_to_oid() function supported looking up
dynamically loaded mechanisms by name, but did not support partial matches or
the legacy "Kerberos 5" name as supported by gss_name_to_oid().

Consolidate these into a single function, and also add support for dynamically
loaded mechanisms to gss_oid_to_name().

API behavior difference: the Kerberos mechanism is now referred to by "krb5"
rather tha "Kerberos 5", although for legacy compatibility gss_name_to_oid()
will recognize the old name. However, gss_oid_to_name() will return "krb5". The
anticipated impact is minimal as these are not standard GSS-APIs and do not
appear to have any public usage outside Heimdal.
This commit is contained in:
Luke Howard
2021-08-08 11:28:32 +10:00
parent 5966c00701
commit 18c18d84b1
8 changed files with 97 additions and 114 deletions

View File

@@ -491,20 +491,77 @@ _gss_mg_support_mechanism(gss_const_OID mech)
return NULL;
}
GSSAPI_LIB_FUNCTION gss_const_OID GSSAPI_CALLCONV
gss_mg_name_to_oid(const char *name)
enum mech_name_match {
MATCH_NONE = 0,
MATCH_COMPLETE,
MATCH_PARTIAL
};
static enum mech_name_match
match_mech_name(const char *gm_mech_name,
const char *name,
size_t namelen)
{
struct _gss_mech_switch *m;
if (gm_mech_name == NULL)
return MATCH_NONE;
else if (strcasecmp(gm_mech_name, name) == 0)
return MATCH_COMPLETE;
else if (strncasecmp(gm_mech_name, name, namelen) == 0)
return MATCH_PARTIAL;
else
return MATCH_NONE;
}
/*
* Return an OID for a built-in or dynamically loaded mechanism. For
* API compatibility with previous versions, we treat "Kerberos 5"
* as an alias for "krb5". Unique partial matches are supported.
*/
GSSAPI_LIB_FUNCTION gss_OID GSSAPI_CALLCONV
gss_name_to_oid(const char *name)
{
struct _gss_mech_switch *m, *partial = NULL;
gss_OID oid = GSS_C_NO_OID;
size_t namelen = strlen(name);
if (isdigit(name[0]) && _gss_string_to_oid(name, &oid) == 0)
return oid;
_gss_load_mech();
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
if (m->gm_mech.gm_name &&
strcmp(m->gm_mech.gm_name, name) == 0)
enum mech_name_match match;
match = match_mech_name(m->gm_mech.gm_name, name, namelen);
if (match == MATCH_NONE &&
gss_oid_equal(m->gm_mech_oid, GSS_KRB5_MECHANISM))
match = match_mech_name("Kerberos 5", name, namelen);
if (match == MATCH_COMPLETE)
return m->gm_mech_oid;
else if (match == MATCH_PARTIAL) {
if (partial)
return NULL;
else
partial = m;
}
}
if (partial)
return partial->gm_mech_oid;
return NULL;
}
GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL
gss_oid_to_name(gss_const_OID oid)
{
struct _gss_mech_switch *m;
_gss_load_mech();
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
if (gss_oid_equal(m->gm_mech_oid, oid))
return m->gm_mech.gm_name;
}
return NULL;
}

View File

@@ -65,34 +65,3 @@ gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
*minor_status = 0;
return GSS_S_COMPLETE;
}
GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL
gss_oid_to_name(gss_const_OID oid)
{
size_t i;
for (i = 0; _gss_ont_mech[i].oid; i++) {
if (gss_oid_equal(oid, _gss_ont_mech[i].oid))
return _gss_ont_mech[i].name;
}
return NULL;
}
GSSAPI_LIB_FUNCTION gss_OID GSSAPI_LIB_CALL
gss_name_to_oid(const char *name)
{
size_t i, partial = (size_t)-1;
for (i = 0; _gss_ont_mech[i].oid; i++) {
if (strcasecmp(name, _gss_ont_mech[i].short_desc) == 0)
return _gss_ont_mech[i].oid;
if (strncasecmp(name, _gss_ont_mech[i].short_desc, strlen(name)) == 0) {
if (partial != (size_t)-1)
return NULL;
partial = i;
}
}
if (partial != (size_t)-1)
return _gss_ont_mech[partial].oid;
return NULL;
}