LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/gssapi/mech - gss_mech_switch.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 49 161 30.4 %
Date: 2024-05-31 13:13:24 Functions: 5 9 55.6 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2005 Doug Rabson
       3             :  * All rights reserved.
       4             :  *
       5             :  * Redistribution and use in source and binary forms, with or without
       6             :  * modification, are permitted provided that the following conditions
       7             :  * are met:
       8             :  * 1. Redistributions of source code must retain the above copyright
       9             :  *    notice, this list of conditions and the following disclaimer.
      10             :  * 2. Redistributions in binary form must reproduce the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer in the
      12             :  *    documentation and/or other materials provided with the distribution.
      13             :  *
      14             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      15             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      16             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      17             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      18             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      19             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      20             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      21             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      22             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      23             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      24             :  * SUCH DAMAGE.
      25             :  *
      26             :  *      $FreeBSD: src/lib/libgssapi/gss_mech_switch.c,v 1.2 2006/02/04 09:40:21 dfr Exp $
      27             :  */
      28             : 
      29             : #include "mech_locl.h"
      30             : #include <heim_threads.h>
      31             : 
      32             : #ifndef _PATH_GSS_MECH
      33             : #define _PATH_GSS_MECH  "/etc/gss/mech"
      34             : #endif
      35             : 
      36             : struct _gss_mech_switch_list _gss_mechs = { NULL, NULL } ;
      37             : gss_OID_set _gss_mech_oids;
      38             : static HEIMDAL_MUTEX _gss_mech_mutex = HEIMDAL_MUTEX_INITIALIZER;
      39             : 
      40             : /*
      41             :  * Convert a string containing an OID in 'dot' form
      42             :  * (e.g. 1.2.840.113554.1.2.2) to a gss_OID.
      43             :  */
      44             : static int
      45           0 : _gss_string_to_oid(const char* s, gss_OID *oidp)
      46             : {
      47           0 :         int                     number_count, i, j;
      48           0 :         size_t                  byte_count;
      49           0 :         const char              *p, *q;
      50           0 :         char                    *res;
      51           0 :         gss_OID_desc            oid;
      52             : 
      53           0 :         *oidp = GSS_C_NO_OID;
      54             : 
      55             :         /*
      56             :          * First figure out how many numbers in the oid, then
      57             :          * calculate the compiled oid size.
      58             :          */
      59           0 :         number_count = 0;
      60           0 :         for (p = s; p; p = q) {
      61           0 :                 q = strchr(p, '.');
      62           0 :                 if (q) q = q + 1;
      63           0 :                 number_count++;
      64             :         }
      65             : 
      66             :         /*
      67             :          * The first two numbers are in the first byte and each
      68             :          * subsequent number is encoded in a variable byte sequence.
      69             :          */
      70           0 :         if (number_count < 2)
      71           0 :                 return (EINVAL);
      72             : 
      73             :         /*
      74             :          * We do this in two passes. The first pass, we just figure
      75             :          * out the size. Second time around, we actually encode the
      76             :          * number.
      77             :          */
      78           0 :         res = 0;
      79           0 :         for (i = 0; i < 2; i++) {
      80           0 :                 byte_count = 0;
      81           0 :                 for (p = s, j = 0; p; p = q, j++) {
      82           0 :                         unsigned int number = 0;
      83             : 
      84             :                         /*
      85             :                          * Find the end of this number.
      86             :                          */
      87           0 :                         q = strchr(p, '.');
      88           0 :                         if (q) q = q + 1;
      89             : 
      90             :                         /*
      91             :                          * Read the number of of the string. Don't
      92             :                          * bother with anything except base ten.
      93             :                          */
      94           0 :                         while (*p && *p != '.') {
      95           0 :                                 number = 10 * number + (*p - '0');
      96           0 :                                 p++;
      97             :                         }
      98             : 
      99             :                         /*
     100             :                          * Encode the number. The first two numbers
     101             :                          * are packed into the first byte. Subsequent
     102             :                          * numbers are encoded in bytes seven bits at
     103             :                          * a time with the last byte having the high
     104             :                          * bit set.
     105             :                          */
     106           0 :                         if (j == 0) {
     107           0 :                                 if (res)
     108           0 :                                         *res = number * 40;
     109           0 :                         } else if (j == 1) {
     110           0 :                                 if (res) {
     111           0 :                                         *res += number;
     112           0 :                                         res++;
     113             :                                 }
     114           0 :                                 byte_count++;
     115           0 :                         } else if (j >= 2) {
     116             :                                 /*
     117             :                                  * The number is encoded in seven bit chunks.
     118             :                                  */
     119             :                                 unsigned int t;
     120             :                                 unsigned int bytes;
     121             : 
     122           0 :                                 bytes = 0;
     123           0 :                                 for (t = number; t; t >>= 7)
     124           0 :                                         bytes++;
     125           0 :                                 if (bytes == 0) bytes = 1;
     126           0 :                                 while (bytes) {
     127           0 :                                         if (res) {
     128           0 :                                                 int bit = 7*(bytes-1);
     129             : 
     130           0 :                                                 *res = (number >> bit) & 0x7f;
     131           0 :                                                 if (bytes != 1)
     132           0 :                                                         *res |= 0x80;
     133           0 :                                                 res++;
     134             :                                         }
     135           0 :                                         byte_count++;
     136           0 :                                         bytes--;
     137             :                                 }
     138             :                         }
     139             :                 }
     140           0 :                 if (byte_count == 0)
     141           0 :                     return EINVAL;
     142           0 :                 if (!res) {
     143           0 :                         res = malloc(byte_count);
     144           0 :                         if (!res)
     145           0 :                                 return (ENOMEM);
     146           0 :                         oid.length = byte_count;
     147           0 :                         oid.elements = res;
     148             :                 }
     149             :         }
     150             : 
     151             :         {
     152           0 :                 OM_uint32 minor_status, tmp;
     153             : 
     154           0 :                 if (GSS_ERROR(_gss_intern_oid(&minor_status, &oid, oidp))) {
     155           0 :                         _gss_free_oid(&tmp, &oid);
     156           0 :                         return (minor_status);
     157             :                 }
     158             : 
     159           0 :                 _gss_free_oid(&tmp, &oid);
     160             :         }
     161             : 
     162           0 :         return (0);
     163             : }
     164             : 
     165             : #define SYM(name)                                                       \
     166             : do {                                                                    \
     167             :         m->gm_mech.gm_ ## name = (_gss_##name##_t *)dlsym(so, "gss_" #name); \
     168             :         if (!m->gm_mech.gm_ ## name ||                                       \
     169             :             m->gm_mech.gm_ ##name == gss_ ## name) {                 \
     170             :                 _gss_mg_log(1, "can't find symbol gss_" #name "\n");        \
     171             :                 goto bad;                                               \
     172             :         }                                                               \
     173             : } while (0)
     174             : 
     175             : #define OPTSYM(name)                                                    \
     176             : do {                                                                    \
     177             :         m->gm_mech.gm_ ## name =  (_gss_##name##_t *)dlsym(so, "gss_" #name); \
     178             :         if (m->gm_mech.gm_ ## name == gss_ ## name)                  \
     179             :                 m->gm_mech.gm_ ## name = NULL;                               \
     180             : } while (0)
     181             : 
     182             : /* mech exports gssspi_XXX, internally referred to as gss_XXX */
     183             : #define OPTSPISYM(name)                                                 \
     184             : do {                                                                    \
     185             :         m->gm_mech.gm_ ## name =  (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \
     186             : } while (0)
     187             : 
     188             : /* mech exports gssspi_XXX, internally referred to as gssspi_XXX */
     189             : #define OPTSPISPISYM(name)                                                      \
     190             : do {                                                                    \
     191             :         m->gm_mech.gm_ ## name =  (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \
     192             :         if (m->gm_mech.gm_ ## name == gssspi_ ## name)                       \
     193             :                 m->gm_mech.gm_ ## name = NULL;                               \
     194             : } while (0)
     195             : 
     196             : #define COMPATSYM(name)                                                 \
     197             : do {                                                                    \
     198             :         m->gm_mech.gm_compat->gmc_ ## name =  (_gss_##name##_t *)dlsym(so, "gss_" #name); \
     199             :         if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name)           \
     200             :                 m->gm_mech.gm_compat->gmc_ ## name = NULL;                \
     201             : } while (0)
     202             : 
     203             : #define COMPATSPISYM(name)                                              \
     204             : do {                                                                    \
     205             :         m->gm_mech.gm_compat->gmc_ ## name =  (_gss_##name##_t *)dlsym(so, "gssspi_" #name); \
     206             :         if (m->gm_mech.gm_compat->gmc_ ## name == gss_ ## name)           \
     207             :                 m->gm_mech.gm_compat->gmc_ ## name = NULL;                \
     208             : } while (0)
     209             : 
     210             : /*
     211             :  *
     212             :  */
     213             : static int
     214       64664 : add_builtin(gssapi_mech_interface mech)
     215             : {
     216        3660 :     struct _gss_mech_switch *m;
     217        3660 :     OM_uint32 minor_status;
     218             : 
     219             :     /* not registering any mech is ok */
     220       64664 :     if (mech == NULL)
     221       30502 :         return 0;
     222             : 
     223       32332 :     m = calloc(1, sizeof(*m));
     224       32332 :     if (m == NULL)
     225           0 :         return ENOMEM;
     226       32332 :     m->gm_so = NULL;
     227       32332 :     m->gm_mech = *mech;
     228       32332 :     _gss_intern_oid(&minor_status, &mech->gm_mech_oid, &m->gm_mech_oid);
     229       32332 :     if (minor_status) {
     230           0 :         free(m);
     231           0 :         return minor_status;
     232             :     }
     233             : 
     234       32332 :     if (gss_add_oid_set_member(&minor_status, &m->gm_mech.gm_mech_oid,
     235             :                                &_gss_mech_oids) != GSS_S_COMPLETE) {
     236           0 :         free(m);
     237           0 :         return ENOMEM;
     238             :     }
     239             : 
     240             :     /* pick up the oid sets of names */
     241             : 
     242       32332 :     if (m->gm_mech.gm_inquire_names_for_mech)
     243       16166 :         (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
     244       15251 :             &m->gm_mech.gm_mech_oid, &m->gm_name_types);
     245             : 
     246       48498 :     if (m->gm_name_types == NULL &&
     247       16166 :         gss_create_empty_oid_set(&minor_status,
     248             :                                  &m->gm_name_types) != GSS_S_COMPLETE) {
     249           0 :         free(m);
     250           0 :         return ENOMEM;
     251             :     }
     252             : 
     253       32332 :     HEIM_TAILQ_INSERT_TAIL(&_gss_mechs, m, gm_link);
     254       32332 :     return 0;
     255             : }
     256             : 
     257             : static void
     258       16166 : init_mech_switch_list(void *p)
     259             : {
     260       16166 :     struct _gss_mech_switch_list *mechs = p;
     261             : 
     262       16166 :     HEIM_TAILQ_INIT(mechs);
     263       16166 : }
     264             : 
     265             : /*
     266             :  * Load the mechanisms file (/etc/gss/mech).
     267             :  */
     268             : void
     269      496748 : _gss_load_mech(void)
     270             : {
     271       18388 :         OM_uint32       major_status, minor_status;
     272       18388 :         static heim_base_once_t once = HEIM_BASE_ONCE_INIT;
     273             : #ifdef HAVE_DLOPEN
     274             :         FILE            *fp;
     275             :         char            buf[256];
     276             :         char            *p;
     277             :         char            *name, *oid, *lib, *kobj;
     278             :         struct _gss_mech_switch *m;
     279             :         void            *so;
     280             :         gss_OID         mech_oid;
     281             :         int             found;
     282             :         const char      *conf = secure_getenv("GSS_MECH_CONFIG");
     283             : #endif
     284             : 
     285      496748 :         heim_base_once_f(&once, &_gss_mechs, init_mech_switch_list);
     286             : 
     287       18388 :         HEIMDAL_MUTEX_lock(&_gss_mech_mutex);
     288             : 
     289      496748 :         if (!HEIM_TAILQ_EMPTY(&_gss_mechs)) {
     290             :                 HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
     291      480582 :                 return;
     292             :         }
     293             : 
     294       16166 :         major_status = gss_create_empty_oid_set(&minor_status,
     295             :             &_gss_mech_oids);
     296       16166 :         if (major_status) {
     297             :                 HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
     298           0 :                 return;
     299             :         }
     300             : 
     301       16166 :         if (add_builtin(__gss_krb5_initialize()))
     302           0 :             _gss_mg_log(1, "Out of memory while adding builtin Kerberos GSS "
     303             :                         "mechanism to the GSS mechanism switch");
     304       16166 :         if (add_builtin(__gss_spnego_initialize()))
     305           0 :             _gss_mg_log(1, "Out of memory while adding builtin SPNEGO "
     306             :                         "mechanism to the GSS mechanism switch");
     307       16166 :         if (add_builtin(__gss_ntlm_initialize()))
     308           0 :             _gss_mg_log(1, "Out of memory while adding builtin NTLM "
     309             :                         "mechanism to the GSS mechanism switch");
     310             : 
     311             : #ifdef HAVE_DLOPEN
     312             :         fp = fopen(conf ? conf : _PATH_GSS_MECH, "r");
     313             :         if (!fp)
     314             :                 goto out;
     315             :         rk_cloexec_file(fp);
     316             : 
     317             :         while (fgets(buf, sizeof(buf), fp)) {
     318             :                 _gss_mo_init *mi;
     319             : 
     320             :                 if (*buf == '#')
     321             :                         continue;
     322             :                 p = buf;
     323             :                 name = strsep(&p, "\t\n ");
     324             :                 if (p) while (isspace((unsigned char)*p)) p++;
     325             :                 oid = strsep(&p, "\t\n ");
     326             :                 if (p) while (isspace((unsigned char)*p)) p++;
     327             :                 lib = strsep(&p, "\t\n ");
     328             :                 if (p) while (isspace((unsigned char)*p)) p++;
     329             :                 kobj = strsep(&p, "\t\n ");
     330             :                 if (!name || !oid || !lib || !kobj)
     331             :                         continue;
     332             : 
     333             :                 if (_gss_string_to_oid(oid, &mech_oid))
     334             :                         continue;
     335             : 
     336             :                 /*
     337             :                  * Check for duplicates, already loaded mechs.
     338             :                  */
     339             :                 found = 0;
     340             :                 HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
     341             :                         if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech_oid)) {
     342             :                                 found = 1;
     343             :                                 break;
     344             :                         }
     345             :                 }
     346             :                 if (found)
     347             :                         continue;
     348             : 
     349             :                 so = dlopen(lib, RTLD_LAZY | RTLD_LOCAL | RTLD_GROUP);
     350             :                 if (so == NULL) {
     351             :                         _gss_mg_log(1, "dlopen: %s\n", dlerror());
     352             :                         goto bad;
     353             :                 }
     354             : 
     355             :                 m = calloc(1, sizeof(*m));
     356             :                 if (m == NULL)
     357             :                         goto bad;
     358             : 
     359             :                 m->gm_so = so;
     360             :                 m->gm_mech_oid = mech_oid;
     361             :                 m->gm_mech.gm_name = strdup(name);
     362             :                 m->gm_mech.gm_mech_oid = *mech_oid;
     363             :                 m->gm_mech.gm_flags = 0;
     364             :                 m->gm_mech.gm_compat = calloc(1, sizeof(struct gss_mech_compat_desc_struct));
     365             :                 if (m->gm_mech.gm_compat == NULL)
     366             :                         goto bad;
     367             : 
     368             :                 major_status = gss_add_oid_set_member(&minor_status,
     369             :                     &m->gm_mech.gm_mech_oid, &_gss_mech_oids);
     370             :                 if (GSS_ERROR(major_status))
     371             :                         goto bad;
     372             : 
     373             :                 SYM(acquire_cred);
     374             :                 SYM(release_cred);
     375             :                 SYM(init_sec_context);
     376             :                 SYM(accept_sec_context);
     377             :                 SYM(process_context_token);
     378             :                 SYM(delete_sec_context);
     379             :                 SYM(context_time);
     380             :                 SYM(get_mic);
     381             :                 SYM(verify_mic);
     382             :                 SYM(wrap);
     383             :                 SYM(unwrap);
     384             :                 OPTSYM(display_status);
     385             :                 OPTSYM(indicate_mechs);
     386             :                 SYM(compare_name);
     387             :                 SYM(display_name);
     388             :                 SYM(import_name);
     389             :                 SYM(export_name);
     390             :                 SYM(release_name);
     391             :                 OPTSYM(inquire_cred);
     392             :                 SYM(inquire_context);
     393             :                 SYM(wrap_size_limit);
     394             :                 OPTSYM(add_cred);
     395             :                 OPTSYM(inquire_cred_by_mech);
     396             :                 SYM(export_sec_context);
     397             :                 SYM(import_sec_context);
     398             :                 OPTSYM(inquire_names_for_mech);
     399             :                 OPTSYM(inquire_mechs_for_name);
     400             :                 SYM(canonicalize_name);
     401             :                 SYM(duplicate_name);
     402             :                 OPTSYM(inquire_cred_by_oid);
     403             :                 OPTSYM(inquire_sec_context_by_oid);
     404             :                 OPTSYM(set_sec_context_option);
     405             :                 OPTSPISYM(set_cred_option);
     406             :                 OPTSYM(pseudo_random);
     407             :                 OPTSYM(wrap_iov);
     408             :                 OPTSYM(unwrap_iov);
     409             :                 OPTSYM(wrap_iov_length);
     410             :                 OPTSYM(store_cred);
     411             :                 OPTSYM(export_cred);
     412             :                 OPTSYM(import_cred);
     413             :                 OPTSYM(acquire_cred_from);
     414             :                 OPTSYM(acquire_cred_impersonate_name);
     415             : #if 0
     416             :                 OPTSYM(iter_creds);
     417             :                 OPTSYM(destroy_cred);
     418             :                 OPTSYM(cred_hold);
     419             :                 OPTSYM(cred_unhold);
     420             :                 OPTSYM(cred_label_get);
     421             :                 OPTSYM(cred_label_set);
     422             : #endif
     423             :                 OPTSYM(display_name_ext);
     424             :                 OPTSYM(inquire_name);
     425             :                 OPTSYM(get_name_attribute);
     426             :                 OPTSYM(set_name_attribute);
     427             :                 OPTSYM(delete_name_attribute);
     428             :                 OPTSYM(export_name_composite);
     429             :                 OPTSYM(localname);
     430             :                 OPTSYM(duplicate_cred);
     431             :                 OPTSYM(add_cred_from);
     432             :                 OPTSYM(store_cred_into);
     433             :                 OPTSPISYM(authorize_localname);
     434             :                 OPTSPISPISYM(query_mechanism_info);
     435             :                 OPTSPISPISYM(query_meta_data);
     436             :                 OPTSPISPISYM(exchange_meta_data);
     437             : 
     438             :                 mi = (_gss_mo_init *)dlsym(so, "gss_mo_init");
     439             :                 if (mi != NULL) {
     440             :                         major_status = mi(&minor_status, mech_oid,
     441             :                                           &m->gm_mech.gm_mo, &m->gm_mech.gm_mo_num);
     442             :                         if (GSS_ERROR(major_status))
     443             :                                 goto bad;
     444             :                 } else {
     445             :                         /* API-as-SPI compatibility */
     446             :                         COMPATSYM(inquire_saslname_for_mech);
     447             :                         COMPATSYM(inquire_mech_for_saslname);
     448             :                         COMPATSYM(inquire_attrs_for_mech);
     449             :                         COMPATSPISYM(acquire_cred_with_password);
     450             :                 }
     451             : 
     452             :                 /* pick up the oid sets of names */
     453             : 
     454             :                 if (m->gm_mech.gm_inquire_names_for_mech)
     455             :                         (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
     456             :                         &m->gm_mech.gm_mech_oid, &m->gm_name_types);
     457             : 
     458             :                 if (m->gm_name_types == NULL)
     459             :                         gss_create_empty_oid_set(&minor_status, &m->gm_name_types);
     460             : 
     461             :                 HEIM_TAILQ_INSERT_TAIL(&_gss_mechs, m, gm_link);
     462             :                 continue;
     463             : 
     464             :         bad:
     465             :                 if (m != NULL) {
     466             :                         free(m->gm_mech.gm_compat);
     467             :                         /* do not free OID, it has been interned */
     468             :                         free((char *)m->gm_mech.gm_name);
     469             :                         free(m);
     470             :                 }
     471             :                 if (so != NULL)
     472             :                         dlclose(so);
     473             :                 continue;
     474             :         }
     475             :         fclose(fp);
     476             : 
     477             : out:
     478             : 
     479             : #endif
     480       16166 :         if (add_builtin(__gss_sanon_initialize()))
     481           0 :             _gss_mg_log(1, "Out of memory while adding builtin SANON "
     482             :                         "mechanism to the GSS mechanism switch");
     483         915 :         HEIMDAL_MUTEX_unlock(&_gss_mech_mutex);
     484             : }
     485             : 
     486             : gssapi_mech_interface
     487       67623 : __gss_get_mechanism(gss_const_OID mech)
     488             : {
     489        1834 :         struct _gss_mech_switch *m;
     490             : 
     491       67623 :         _gss_load_mech();
     492       67623 :         HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
     493       67623 :                 if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech))
     494       67623 :                         return &m->gm_mech;
     495             :         }
     496           0 :         return NULL;
     497             : }
     498             : 
     499             : gss_OID
     500       20282 : _gss_mg_support_mechanism(gss_const_OID mech)
     501             : {
     502         792 :         struct _gss_mech_switch *m;
     503             : 
     504       20282 :         _gss_load_mech();
     505       20282 :         HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
     506       20282 :                 if (gss_oid_equal(&m->gm_mech.gm_mech_oid, mech))
     507       20282 :                         return m->gm_mech_oid;
     508             :         }
     509           0 :         return NULL;
     510             : }
     511             : 
     512             : enum mech_name_match {
     513             :         MATCH_NONE = 0,
     514             :         MATCH_COMPLETE,
     515             :         MATCH_PARTIAL
     516             : };
     517             : 
     518             : static enum mech_name_match
     519           0 : match_mech_name(const char *gm_mech_name,
     520             :                 const char *name,
     521             :                 size_t namelen)
     522             : {
     523           0 :         if (gm_mech_name == NULL)
     524           0 :                 return MATCH_NONE;
     525           0 :         else if (strcasecmp(gm_mech_name, name) == 0)
     526           0 :                 return MATCH_COMPLETE;
     527           0 :         else if (strncasecmp(gm_mech_name, name, namelen) == 0)
     528           0 :                 return MATCH_PARTIAL;
     529             :         else
     530           0 :                 return MATCH_NONE;
     531             : }
     532             : 
     533             : /*
     534             :  * Return an OID for a built-in or dynamically loaded mechanism. For
     535             :  * API compatibility with previous versions, we treat "Kerberos 5"
     536             :  * as an alias for "krb5". Unique partial matches are supported.
     537             :  */
     538             : GSSAPI_LIB_FUNCTION gss_OID GSSAPI_CALLCONV
     539           0 : gss_name_to_oid(const char *name)
     540             : {
     541           0 :         struct _gss_mech_switch *m, *partial = NULL;
     542           0 :         gss_OID oid = GSS_C_NO_OID;
     543           0 :         size_t namelen = strlen(name);
     544             : 
     545           0 :         if (isdigit((unsigned char)name[0]) &&
     546           0 :             _gss_string_to_oid(name, &oid) == 0)
     547           0 :                 return oid;
     548             : 
     549           0 :         _gss_load_mech();
     550           0 :         HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
     551           0 :                 enum mech_name_match match;
     552             : 
     553           0 :                 match = match_mech_name(m->gm_mech.gm_name, name, namelen);
     554           0 :                 if (match == MATCH_NONE &&
     555           0 :                     gss_oid_equal(m->gm_mech_oid, GSS_KRB5_MECHANISM))
     556           0 :                         match = match_mech_name("Kerberos 5", name, namelen);
     557             : 
     558           0 :                 if (match == MATCH_COMPLETE)
     559           0 :                         return m->gm_mech_oid;
     560           0 :                 else if (match == MATCH_PARTIAL) {
     561           0 :                         if (partial)
     562           0 :                                 return NULL;
     563             :                         else
     564           0 :                                 partial = m;
     565             :                 }
     566             :         }
     567             : 
     568           0 :         if (partial)
     569           0 :                 return partial->gm_mech_oid;
     570             : 
     571           0 :         return NULL;
     572             : }
     573             : 
     574             : GSSAPI_LIB_FUNCTION const char * GSSAPI_LIB_CALL
     575           0 : gss_oid_to_name(gss_const_OID oid)
     576             : {
     577           0 :         struct _gss_mech_switch *m;
     578             : 
     579           0 :         _gss_load_mech();
     580           0 :         HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
     581           0 :                 if (gss_oid_equal(m->gm_mech_oid, oid))
     582           0 :                         return m->gm_mech.gm_name;
     583             :         }
     584             : 
     585           0 :         return NULL;
     586             : }

Generated by: LCOV version 1.14