LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/gss_preauth - pa_common.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 0 132 0.0 %
Date: 2024-05-31 13:13:24 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2021, PADL Software Pty Ltd.
       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             :  *
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer.
      11             :  *
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * 3. Neither the name of PADL Software nor the names of its contributors
      17             :  *    may be used to endorse or promote products derived from this software
      18             :  *    without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
      21             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
      24             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      25             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      26             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      27             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      28             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      29             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      30             :  * SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #include <krb5_locl.h>
      34             : #include <mech_locl.h>
      35             : #include <heimntlm.h>
      36             : 
      37             : #include "gss-preauth-protos.h"
      38             : #include "gss-preauth-private.h"
      39             : 
      40             : krb5_error_code
      41           0 : _krb5_gss_map_error(OM_uint32 major, OM_uint32 minor)
      42             : {
      43           0 :     krb5_error_code ret;
      44             : 
      45           0 :     if (minor != 0)
      46           0 :         return (krb5_error_code)minor;
      47             : 
      48           0 :     switch (major) {
      49           0 :     case GSS_S_COMPLETE:
      50           0 :         ret = 0;
      51           0 :         break;
      52           0 :     case GSS_S_CONTINUE_NEEDED:
      53           0 :         ret = HEIM_ERR_PA_CONTINUE_NEEDED;
      54           0 :         break;
      55           0 :     case GSS_S_BAD_NAME:
      56             :     case GSS_S_BAD_NAMETYPE:
      57           0 :         ret = KRB5_PRINC_NOMATCH;
      58           0 :         break;
      59           0 :     case GSS_S_NO_CRED:
      60           0 :         ret = KRB5_CC_NOTFOUND;
      61           0 :         break;
      62           0 :     case GSS_S_BAD_MIC:
      63             :     case GSS_S_DEFECTIVE_CREDENTIAL:
      64           0 :         ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
      65           0 :         break;
      66           0 :     case GSS_S_FAILURE:
      67             :     default:
      68           0 :         ret = KRB5KDC_ERR_PREAUTH_FAILED;
      69           0 :         break;
      70             :     }
      71             : 
      72           0 :     return ret;
      73             : }
      74             : 
      75             : krb5_error_code
      76           0 : _krb5_gss_pa_derive_key(krb5_context context,
      77             :                         gss_ctx_id_t ctx,
      78             :                         krb5int32 nonce,
      79             :                         krb5_enctype enctype,
      80             :                         krb5_keyblock **keyblock)
      81             : {
      82           0 :     krb5_error_code ret;
      83           0 :     u_char saltdata[12] = "KRB-GSS";
      84           0 :     krb5_keyblock kdkey;
      85           0 :     size_t keysize;
      86             : 
      87           0 :     OM_uint32 major, minor;
      88           0 :     gss_buffer_desc salt, dkey = GSS_C_EMPTY_BUFFER;
      89             : 
      90           0 :     *keyblock = NULL;
      91             : 
      92           0 :     ret = krb5_enctype_keysize(context, enctype, &keysize);
      93           0 :     if (ret)
      94           0 :         return ret;
      95             : 
      96           0 :     saltdata[ 8] = (nonce >> 0 ) & 0xFF;
      97           0 :     saltdata[ 9] = (nonce >> 8 ) & 0xFF;
      98           0 :     saltdata[10] = (nonce >> 16) & 0xFF;
      99           0 :     saltdata[11] = (nonce >> 24) & 0xFF;
     100             : 
     101           0 :     salt.value = saltdata;
     102           0 :     salt.length = sizeof(saltdata);
     103             : 
     104           0 :     major = gss_pseudo_random(&minor, ctx, GSS_C_PRF_KEY_FULL,
     105             :                               &salt, keysize, &dkey);
     106           0 :     if (GSS_ERROR(major))
     107           0 :         return KRB5_PREAUTH_NO_KEY;
     108             : 
     109           0 :     kdkey.keytype = enctype;
     110           0 :     kdkey.keyvalue.data = dkey.value;
     111           0 :     kdkey.keyvalue.length = dkey.length;
     112             : 
     113           0 :     ret = krb5_copy_keyblock(context, &kdkey, keyblock);
     114             : 
     115           0 :     if (dkey.value) {
     116           0 :         memset_s(dkey.value, dkey.length, 0, dkey.length);
     117           0 :         gss_release_buffer(&minor, &dkey);
     118             :     }
     119             : 
     120           0 :     return ret;
     121             : }
     122             : 
     123             : krb5_error_code
     124           0 : _krb5_gss_pa_unparse_name(krb5_context context,
     125             :                           krb5_const_principal principal,
     126             :                           gss_name_t *namep)
     127             : {
     128           0 :     krb5_error_code ret;
     129           0 :     char *name = NULL;
     130             : 
     131           0 :     OM_uint32 major, minor;
     132           0 :     gss_buffer_desc name_buf;
     133             : 
     134           0 :     *namep = GSS_C_NO_NAME;
     135             : 
     136           0 :     if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     137           0 :         if (principal->name.name_string.len != 1)
     138           0 :             return EINVAL;
     139             : 
     140           0 :         name = principal->name.name_string.val[0];
     141             :     } else {
     142           0 :         ret = krb5_unparse_name(context, principal, &name);
     143           0 :         if (ret)
     144           0 :             return ret;
     145             :     }
     146             : 
     147           0 :     name_buf.length = strlen(name);
     148           0 :     name_buf.value = name;
     149             : 
     150           0 :     major = gss_import_name(&minor, &name_buf,
     151             :                             GSS_KRB5_NT_PRINCIPAL_NAME, namep);
     152           0 :     if (major == GSS_S_BAD_NAMETYPE) {
     153           0 :         gss_OID name_type = GSS_C_NO_OID;
     154           0 :         int flags = 0;
     155             : 
     156           0 :         if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     157           0 :             name_type = GSS_C_NT_USER_NAME;
     158           0 :         } else if (principal->name.name_type == KRB5_NT_PRINCIPAL) {
     159           0 :             flags = KRB5_PRINCIPAL_UNPARSE_SHORT;
     160           0 :             name_type = GSS_C_NT_USER_NAME;
     161           0 :         } else if ((principal->name.name_type == KRB5_NT_SRV_HST ||
     162           0 :                     principal->name.name_type == KRB5_NT_SRV_INST) &&
     163           0 :             principal->name.name_string.len == 2) {
     164           0 :             flags = KRB5_PRINCIPAL_UNPARSE_NO_REALM;
     165           0 :             name_type = GSS_C_NT_HOSTBASED_SERVICE;
     166             :         }
     167             : 
     168           0 :         if (flags) {
     169           0 :             krb5_xfree(name);
     170             : 
     171           0 :             ret = krb5_unparse_name_flags(context, principal, flags, &name);
     172           0 :             if (ret)
     173           0 :                 return ret;
     174             : 
     175           0 :             if (gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE)) {
     176           0 :                 char *inst = strchr(name, '/');
     177           0 :                 if (inst)
     178           0 :                     *inst = '@';
     179             :             }
     180             : 
     181           0 :             name_buf.length = strlen(name);
     182           0 :             name_buf.value = name;
     183             :         }
     184             : 
     185           0 :         if (name_type)
     186           0 :             major = gss_import_name(&minor, &name_buf, name_type, namep);
     187             :     }
     188             : 
     189           0 :     if (name != principal->name.name_string.val[0])
     190           0 :         krb5_xfree(name);
     191             : 
     192           0 :     return _krb5_gss_map_error(major, minor);
     193             : }
     194             : 
     195             : krb5_error_code
     196           0 : _krb5_gss_pa_parse_name(krb5_context context,
     197             :                         gss_const_name_t name,
     198             :                         int flags,
     199             :                         krb5_principal *principal)
     200             : {
     201           0 :     krb5_error_code ret;
     202           0 :     char *displayed_name0;
     203             : 
     204           0 :     OM_uint32 major, minor;
     205           0 :     gss_OID name_type = GSS_C_NO_OID;
     206           0 :     gss_buffer_desc displayed_name = GSS_C_EMPTY_BUFFER;
     207             : 
     208           0 :     major = gss_display_name(&minor, name, &displayed_name, &name_type);
     209           0 :     if (GSS_ERROR(major))
     210           0 :         return _krb5_gss_map_error(major, minor);
     211             : 
     212           0 :     if (gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)) {
     213           0 :         ret = krb5_make_principal(context, principal, KRB5_ANON_REALM,
     214             :                                   KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, NULL);
     215           0 :         if (ret == 0)
     216           0 :             (*principal)->name.name_type = KRB5_NT_WELLKNOWN;
     217             :     } else {
     218           0 :         displayed_name0 = malloc(displayed_name.length + 1);
     219           0 :             if (displayed_name0 == NULL)
     220           0 :                 return krb5_enomem(context);
     221             : 
     222           0 :         memcpy(displayed_name0, displayed_name.value, displayed_name.length);
     223           0 :         displayed_name0[displayed_name.length] = '\0';
     224             : 
     225           0 :         ret = krb5_parse_name_flags(context, displayed_name0, flags, principal);
     226           0 :                                     gss_release_buffer(&minor, &displayed_name);
     227           0 :         free(displayed_name0);
     228             :     }
     229             : 
     230           0 :     gss_release_buffer(&minor, &displayed_name);
     231             : 
     232           0 :     return ret;
     233             : }
     234             : 
     235             : void
     236           0 : _krb5_gss_data_to_buffer(const krb5_data *data, gss_buffer_t buffer)
     237             : {
     238           0 :     if (data) {
     239           0 :         buffer->length = data->length;
     240           0 :         buffer->value = data->data;
     241             :     } else {
     242           0 :         _mg_buffer_zero(buffer);
     243             :     }
     244           0 : }
     245             : 
     246             : void
     247           0 : _krb5_gss_buffer_to_data(gss_const_buffer_t buffer, krb5_data *data)
     248             : {
     249           0 :     if (buffer) {
     250           0 :         data->length = buffer->length;
     251           0 :         data->data = buffer->value;
     252             :     } else {
     253           0 :         krb5_data_zero(data);
     254             :     }
     255           0 : }

Generated by: LCOV version 1.14