diff options
| author | Simo Sorce <simo@redhat.com> | 2012-06-11 11:50:26 -0400 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2012-10-02 00:54:36 -0400 |
| commit | acc8f98c9be4d10f325367cbdb3b0521fbdb3afa (patch) | |
| tree | 7bfa7a3c4f2ce04abed418e8177867dfe019c5d8 /src/lib/gssapi | |
| parent | 046c9028aa79d5e9c9b1910f93d39a4891609883 (diff) | |
| download | krb5-acc8f98c9be4d10f325367cbdb3b0521fbdb3afa.tar.gz krb5-acc8f98c9be4d10f325367cbdb3b0521fbdb3afa.tar.xz krb5-acc8f98c9be4d10f325367cbdb3b0521fbdb3afa.zip | |
Add primitives for using interposed mechanisms
Add gssint_select_mechanism() to determine what mechanism to use for a
caller-specified OID, gssint_get_public_oid() to determine what
mechanism to expose to the caller, and gssint_make_public_oid_set to
translate an array of mech OIDs into a set of public OIDs. In
gssint_get_mechanism(), match interposed OIDs as well as real ones.
[ghudson@mit.edu: Stylistic changes, commit squashing, commit message]
Diffstat (limited to 'src/lib/gssapi')
| -rw-r--r-- | src/lib/gssapi/mechglue/g_initialize.c | 151 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/mglueP.h | 5 |
2 files changed, 152 insertions, 4 deletions
diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c index dc6b8eaf6..fbd0b07e6 100644 --- a/src/lib/gssapi/mechglue/g_initialize.c +++ b/src/lib/gssapi/mechglue/g_initialize.c @@ -75,6 +75,7 @@ static void getRegKeyValue(HKEY key, const char *keyPath, const char *valueName, static void loadConfigFromRegistry(HKEY keyBase, const char *keyPath); #endif static void updateMechList(void); +static void initMechList(void); static void loadInterMech(gss_mech_info aMech); static void freeMechList(void); @@ -457,6 +458,19 @@ updateMechList(void) } } /* updateMechList */ +/* Update the mech list from system configuration if we have never done so. + * Must be invoked with the g_mechListLock mutex held. */ +static void +initMechList(void) +{ + static int lazy_init = 0; + + if (lazy_init == 0) { + updateMechList(); + lazy_init = 1; + } +} + static void releaseMechInfo(gss_mech_info *pCf) { @@ -885,6 +899,124 @@ freeMechList(void) } /* + * Determine the mechanism to use for a caller-specified mech OID. For the + * real mech OID of an interposed mech, return the interposed OID. For an + * interposed mech OID (which an interposer mech uses when re-entering the + * mechglue), return the real mech OID. The returned OID is an alias and + * should not be modified or freed. + */ +OM_uint32 +gssint_select_mech_type(OM_uint32 *minor, gss_const_OID oid, + gss_OID *selected_oid) +{ + gss_mech_info minfo; + OM_uint32 status; + + *selected_oid = GSS_C_NO_OID; + + if (gssint_mechglue_initialize_library() != 0) + return GSS_S_FAILURE; + + if (k5_mutex_lock(&g_mechListLock) != 0) + return GSS_S_FAILURE; + + /* Read conf file at least once so that interposer plugins have a + * chance of getting initialized. */ + initMechList(); + + minfo = g_mechList; + if (oid == GSS_C_NULL_OID) + oid = minfo->mech_type; + while (minfo != NULL) { + if (g_OID_equal(minfo->mech_type, oid)) { + if (minfo->int_mech_type != GSS_C_NO_OID) + *selected_oid = minfo->int_mech_type; + else + *selected_oid = minfo->mech_type; + status = GSS_S_COMPLETE; + goto done; + } else if ((minfo->int_mech_type != GSS_C_NO_OID) && + (g_OID_equal(minfo->int_mech_type, oid))) { + *selected_oid = minfo->mech_type; + status = GSS_S_COMPLETE; + goto done; + } + minfo = minfo->next; + } + status = GSS_S_BAD_MECH; + +done: + (void)k5_mutex_unlock(&g_mechListLock); + return status; +} + +/* If oid is an interposed OID, return the corresponding real mech OID. If + * it's a real mech OID, return it unmodified. Otherwised return null. */ +gss_OID +gssint_get_public_oid(gss_const_OID oid) +{ + gss_mech_info minfo; + gss_OID public_oid = GSS_C_NO_OID; + + /* if oid is null -> then get default which is the first in the list */ + if (oid == GSS_C_NO_OID) + return GSS_C_NO_OID; + + if (gssint_mechglue_initialize_library() != 0) + return GSS_C_NO_OID; + + if (k5_mutex_lock(&g_mechListLock) != 0) + return GSS_C_NO_OID; + + for (minfo = g_mechList; minfo != NULL; minfo = minfo->next) { + if (minfo->is_interposer) + continue; + if (g_OID_equal(minfo->mech_type, oid) || + ((minfo->int_mech_type != GSS_C_NO_OID) && + (g_OID_equal(minfo->int_mech_type, oid)))) { + public_oid = minfo->mech_type; + break; + } + } + + (void)k5_mutex_unlock(&g_mechListLock); + return public_oid; +} + +/* Translate a vector of oids (as from a union cred struct) into a set of + * public OIDs using gssint_get_public_oid. */ +OM_uint32 +gssint_make_public_oid_set(OM_uint32 *minor_status, gss_OID oids, int count, + gss_OID_set *public_set) +{ + OM_uint32 status, tmpmin; + gss_OID_set set; + gss_OID public_oid; + int i; + + *public_set = GSS_C_NO_OID_SET; + + status = generic_gss_create_empty_oid_set(minor_status, &set); + if (GSS_ERROR(status)) + return status; + + for (i = 0; i < count; i++) { + public_oid = gssint_get_public_oid(&oids[i]); + if (public_oid == GSS_C_NO_OID) + continue; + status = generic_gss_add_oid_set_member(minor_status, + public_oid, &set); + if (GSS_ERROR(status)) { + (void) generic_gss_release_oid_set(&tmpmin, &set); + return status; + } + } + + *public_set = set; + return GSS_S_COMPLETE; +} + +/* * Register a mechanism. Called with g_mechListLock held. */ @@ -908,10 +1040,21 @@ gssint_get_mechanism(gss_const_OID oid) if (k5_mutex_lock(&g_mechListLock) != 0) return NULL; - /* check if the mechanism is already loaded */ - if ((aMech = searchMechList(oid)) != NULL && aMech->mech) { - (void) k5_mutex_unlock(&g_mechListLock); - return (aMech->mech); + + /* Check if the mechanism is already loaded. */ + aMech = g_mechList; + if (oid == GSS_C_NULL_OID) + oid = aMech->mech_type; + while (aMech != NULL) { + if (g_OID_equal(aMech->mech_type, oid) && aMech->mech) { + (void)k5_mutex_unlock(&g_mechListLock); + return aMech->mech; + } else if (aMech->int_mech_type != GSS_C_NO_OID && + g_OID_equal(aMech->int_mech_type, oid)) { + (void)k5_mutex_unlock(&g_mechListLock); + return aMech->int_mech; + } + aMech = aMech->next; } /* diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h index 21eefdb7b..2d0fd4a83 100644 --- a/src/lib/gssapi/mechglue/mglueP.h +++ b/src/lib/gssapi/mechglue/mglueP.h @@ -682,6 +682,11 @@ int gssint_mechglue_init(void); void gssint_mechglue_fini(void); #endif +OM_uint32 gssint_select_mech_type(OM_uint32 *minor, gss_const_OID in_oid, + gss_OID *selected_oid); +gss_OID gssint_get_public_oid(gss_const_OID internal_oid); +OM_uint32 gssint_make_public_oid_set(OM_uint32 *minor_status, gss_OID oids, + int count, gss_OID_set *public_set); gss_mechanism gssint_get_mechanism (gss_const_OID); OM_uint32 gssint_get_mech_type (gss_OID, gss_buffer_t); char *gssint_get_kmodName(const gss_OID); |
