LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/gssapi/krb5 - import_name.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 53 143 37.1 %
Date: 2024-04-21 15:09:00 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "gsskrb5_locl.h"
      35             : 
      36             : static OM_uint32
      37       24237 : parse_krb5_name (OM_uint32 *minor_status,
      38             :                  krb5_context context,
      39             :                  const char *name,
      40             :                  gss_name_t *output_name)
      41             : {
      42        1035 :     krb5_principal princ;
      43        1035 :     krb5_error_code kerr;
      44             : 
      45       25272 :     kerr = krb5_parse_name (context, name, &princ);
      46             : 
      47       24237 :     if (kerr == 0) {
      48       24237 :         *output_name = (gss_name_t)princ;
      49       24237 :         return GSS_S_COMPLETE;
      50             :     }
      51           0 :     *minor_status = kerr;
      52             : 
      53           0 :     if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
      54           0 :         return GSS_S_BAD_NAME;
      55             : 
      56           0 :     return GSS_S_FAILURE;
      57             : }
      58             : 
      59             : static OM_uint32
      60       24237 : import_krb5_name (OM_uint32 *minor_status,
      61             :                   krb5_context context,
      62             :                   const gss_buffer_t input_name_buffer,
      63             :                   gss_name_t *output_name)
      64             : {
      65        1035 :     OM_uint32 ret;
      66        1035 :     char *tmp;
      67             : 
      68       24237 :     tmp = malloc (input_name_buffer->length + 1);
      69       24237 :     if (tmp == NULL) {
      70           0 :         *minor_status = ENOMEM;
      71           0 :         return GSS_S_FAILURE;
      72             :     }
      73       24237 :     memcpy (tmp,
      74       24237 :             input_name_buffer->value,
      75             :             input_name_buffer->length);
      76       24237 :     tmp[input_name_buffer->length] = '\0';
      77             : 
      78       24237 :     ret = parse_krb5_name(minor_status, context, tmp, output_name);
      79       24237 :     free(tmp);
      80             : 
      81       24237 :     return ret;
      82             : }
      83             : 
      84             : OM_uint32
      85       24237 : _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
      86             :                     gss_const_name_t targetname, krb5_principal *out)
      87             : {
      88       24237 :     krb5_const_principal p = (krb5_const_principal)targetname;
      89        1035 :     krb5_error_code ret;
      90       24237 :     char *hostname = NULL, *service;
      91        1035 :     int type;
      92        1035 :     const char *comp;
      93             : 
      94       24237 :     *minor_status = 0;
      95             : 
      96             :     /* If its not a hostname */
      97       24237 :     type = krb5_principal_get_type(context, p);
      98       24237 :     comp = krb5_principal_get_comp_string(context, p, 0);
      99       24237 :     if (type == KRB5_NT_SRV_HST || type == KRB5_NT_SRV_HST_NEEDS_CANON ||
     100        1007 :         (type == KRB5_NT_UNKNOWN && comp != NULL && strcmp(comp, "host") == 0)) {
     101        1748 :         if (p->name.name_string.len == 0)
     102           0 :             return GSS_S_BAD_NAME;
     103        1748 :         else if (p->name.name_string.len > 1)
     104        1748 :             hostname = p->name.name_string.val[1];
     105             : 
     106        1748 :         service = p->name.name_string.val[0];
     107             : 
     108        1748 :         ret = krb5_sname_to_principal(context,
     109             :                                       hostname,
     110             :                                       service,
     111             :                                       KRB5_NT_SRV_HST,
     112             :                                       out);
     113        1748 :         if (ret == 0) {
     114        1748 :             const char *in_realm = krb5_principal_get_realm(context,
     115             :                                                             p);
     116        1748 :             const char *out_realm = krb5_principal_get_realm(context,
     117             :                                                              *out);
     118             : 
     119             :             /*
     120             :              * Avoid loss of information, check for the "referral
     121             :              * realm" and set back what was specified.
     122             :              */
     123        1748 :             if (out_realm != NULL && out_realm[0] == '\0') {
     124        1748 :                 ret = krb5_principal_set_realm(context, *out, in_realm);
     125             :             }
     126             :         }
     127             :     } else {
     128       22489 :         ret = krb5_copy_principal(context, p, out);
     129             :     }
     130             : 
     131       24237 :     if (ret) {
     132           0 :         *minor_status = ret;
     133           0 :         return GSS_S_FAILURE;
     134             :     }
     135             : 
     136       23202 :     return 0;
     137             : }
     138             : 
     139             : 
     140             : static OM_uint32
     141           0 : import_hostbased_name(OM_uint32 *minor_status,
     142             :                       krb5_context context,
     143             :                       const gss_buffer_t input_name_buffer,
     144             :                       gss_name_t *output_name)
     145             : {
     146           0 :     krb5_principal princ = NULL;
     147           0 :     krb5_error_code kerr;
     148           0 :     char *tmp, *p, *host = NULL;
     149             : 
     150           0 :     tmp = malloc (input_name_buffer->length + 1);
     151           0 :     if (tmp == NULL) {
     152           0 :         *minor_status = ENOMEM;
     153           0 :         return GSS_S_FAILURE;
     154             :     }
     155           0 :     memcpy (tmp,
     156           0 :             input_name_buffer->value,
     157             :             input_name_buffer->length);
     158           0 :     tmp[input_name_buffer->length] = '\0';
     159             : 
     160           0 :     p = strchr (tmp, '@');
     161           0 :     if (p != NULL) {
     162           0 :         *p = '\0';
     163           0 :         host = p + 1;
     164             :     }
     165             : 
     166           0 :     kerr = krb5_make_principal(context, &princ, "", tmp, host, NULL);
     167           0 :     free (tmp);
     168           0 :     *minor_status = kerr;
     169           0 :     if (kerr == KRB5_PARSE_ILLCHAR || kerr == KRB5_PARSE_MALFORMED)
     170           0 :         return GSS_S_BAD_NAME;
     171           0 :     else if (kerr)
     172           0 :         return GSS_S_FAILURE;
     173             : 
     174           0 :     krb5_principal_set_type(context, princ, KRB5_NT_SRV_HST);
     175           0 :     *output_name = (gss_name_t)princ;
     176             : 
     177           0 :     return 0;
     178             : }
     179             : 
     180             : static OM_uint32
     181           0 : import_export_name (OM_uint32 *minor_status,
     182             :                     krb5_context context,
     183             :                     const gss_buffer_t input_name_buffer,
     184             :                     gss_name_t *output_name)
     185             : {
     186           0 :     CompositePrincipal *composite;
     187           0 :     unsigned char *p;
     188           0 :     uint32_t length;
     189           0 :     size_t sz;
     190           0 :     OM_uint32 ret;
     191           0 :     int is_composite;
     192           0 :     char *name;
     193             : 
     194           0 :     if (input_name_buffer->length < 10 + GSS_KRB5_MECHANISM->length)
     195           0 :         return GSS_S_BAD_NAME;
     196             : 
     197             :     /* TOK, MECH_OID_LEN, DER(MECH_OID), NAME_LEN, NAME */
     198             : 
     199           0 :     p = input_name_buffer->value;
     200             : 
     201           0 :     if (p[0] != 0x04 ||
     202           0 :         (p[1] != 0x01 && p[1] != 0x02) ||
     203           0 :         p[2] != 0x00 ||
     204           0 :         p[3] != GSS_KRB5_MECHANISM->length + 2 ||
     205           0 :         p[4] != 0x06 ||
     206           0 :         p[5] != GSS_KRB5_MECHANISM->length ||
     207           0 :         memcmp(&p[6], GSS_KRB5_MECHANISM->elements,
     208           0 :                GSS_KRB5_MECHANISM->length) != 0)
     209           0 :         return GSS_S_BAD_NAME;
     210             : 
     211           0 :     is_composite = p[1] == 0x02;
     212             : 
     213           0 :     p += 6 + GSS_KRB5_MECHANISM->length;
     214             : 
     215           0 :     length = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
     216           0 :     p += 4;
     217             : 
     218           0 :     if (length > input_name_buffer->length - 10 - GSS_KRB5_MECHANISM->length)
     219           0 :         return GSS_S_BAD_NAME;
     220             : 
     221           0 :     if (is_composite) {
     222           0 :         if ((composite = calloc(1, sizeof(*composite))) == NULL) {
     223           0 :             *minor_status = ENOMEM;
     224           0 :             return GSS_S_FAILURE;
     225             :         }
     226             : 
     227           0 :         ret = decode_CompositePrincipal(p, length, composite, &sz);
     228           0 :         if (ret) {
     229           0 :             *minor_status = ret;
     230           0 :             return GSS_S_FAILURE;
     231             :         }
     232           0 :         if (sz != length) {
     233           0 :             free_CompositePrincipal(composite);
     234           0 :             free(composite);
     235           0 :             *minor_status = EINVAL;
     236           0 :             return GSS_S_FAILURE;
     237             :         }
     238             : 
     239           0 :         *output_name = (void *)composite;
     240           0 :         return GSS_S_COMPLETE;
     241             :     }
     242             : 
     243           0 :     name = malloc(length + 1);
     244           0 :     if (name == NULL) {
     245           0 :         *minor_status = ENOMEM;
     246           0 :         return GSS_S_FAILURE;
     247             :     }
     248           0 :     memcpy(name, p, length);
     249           0 :     name[length] = '\0';
     250             : 
     251           0 :     ret = parse_krb5_name(minor_status, context, name, output_name);
     252           0 :     free(name);
     253           0 :     return ret;
     254             : }
     255             : 
     256       24237 : OM_uint32 GSSAPI_CALLCONV _gsskrb5_import_name
     257             :            (OM_uint32 * minor_status,
     258             :             const gss_buffer_t input_name_buffer,
     259             :             const gss_OID input_name_type,
     260             :             gss_name_t * output_name
     261             :            )
     262             : {
     263        1035 :     krb5_context context;
     264             : 
     265       24237 :     *minor_status = 0;
     266       24237 :     *output_name = GSS_C_NO_NAME;
     267             : 
     268       24237 :     GSSAPI_KRB5_INIT (&context);
     269             : 
     270       48474 :     if (gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE) ||
     271       24237 :         gss_oid_equal(input_name_type, GSS_C_NT_HOSTBASED_SERVICE_X))
     272           0 :         return import_hostbased_name (minor_status,
     273             :                                       context,
     274             :                                       input_name_buffer,
     275             :                                       output_name);
     276       24237 :     else if (input_name_type == GSS_C_NO_OID
     277       24116 :              || gss_oid_equal(input_name_type, GSS_C_NT_USER_NAME)
     278          21 :              || gss_oid_equal(input_name_type, GSS_KRB5_NT_PRINCIPAL_NAME))
     279             :         /* default printable syntax */
     280       24237 :         return import_krb5_name (minor_status,
     281             :                                  context,
     282             :                                  input_name_buffer,
     283             :                                  output_name);
     284           0 :     else if (gss_oid_equal(input_name_type, GSS_C_NT_EXPORT_NAME) ||
     285           0 :              gss_oid_equal(input_name_type, GSS_C_NT_COMPOSITE_EXPORT)) {
     286           0 :         return import_export_name(minor_status,
     287             :                                   context,
     288             :                                   input_name_buffer,
     289             :                                   output_name);
     290             :     } else {
     291           0 :         *minor_status = 0;
     292           0 :         return GSS_S_BAD_NAMETYPE;
     293             :     }
     294             : }

Generated by: LCOV version 1.14