File: name.c

package info (click to toggle)
gss 1.0.4-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,172 kB
  • sloc: ansic: 22,018; sh: 7,411; python: 2,873; perl: 861; makefile: 335; xml: 52; sed: 16
file content (155 lines) | stat: -rw-r--r-- 4,384 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* krb5/name.c --- Implementation of Kerberos 5 GSS-API Name functions.
 * Copyright (C) 2003-2022 Simon Josefsson
 *
 * This file is part of the GNU Generic Security Service Library.
 *
 * This file is free software: you can redistribute it and/or modify
 * it under the terms of either:
 *
 *  * the GNU Lesser General Public License as published by the Free
 *    Software Foundation; either version 3 of the License, or (at
 *    your option) any later version.
 *
 * or
 *
 * * the GNU General Public License as published by the Free Software
 *   Foundation; either version 2 of the License, or (at your option)
 *   any later version.
 *
 * or both in parallel, as here.
 *
 * This file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received copies of the GNU General Public License
 * and the GNU Lesser General Public License along with this file.  If
 * not, see <http://www.gnu.org/licenses/>.
 *
 */

/* Get specification. */
#include "k5internal.h"

OM_uint32
gss_krb5_canonicalize_name (OM_uint32 * minor_status,
			    const gss_name_t input_name,
			    const gss_OID mech_type, gss_name_t * output_name)
{
  OM_uint32 maj_stat;

  if (minor_status)
    *minor_status = 0;

  /* We consider (a zero terminated) GSS_KRB5_NT_PRINCIPAL_NAME the
     canonical mechanism name type.  Convert everything into it.  */

  if (gss_oid_equal (input_name->type, GSS_C_NT_EXPORT_NAME))
    {
      if (input_name->length > 15)
	{
	  *output_name = malloc (sizeof (**output_name));
	  if (!*output_name)
	    {
	      if (minor_status)
		*minor_status = ENOMEM;
	      return GSS_S_FAILURE;
	    }
	  (*output_name)->type = GSS_KRB5_NT_PRINCIPAL_NAME;
	  (*output_name)->length = input_name->length - 15;
	  (*output_name)->value = malloc ((*output_name)->length + 1);
	  if (!(*output_name)->value)
	    {
	      free (*output_name);
	      if (minor_status)
		*minor_status = ENOMEM;
	      return GSS_S_FAILURE;
	    }
	  memcpy ((*output_name)->value, input_name->value + 15,
		  (*output_name)->length);
	  (*output_name)->value[(*output_name)->length] = '\0';
	}
      else
	{
	  return GSS_S_BAD_NAME;
	}
    }
  else if (gss_oid_equal (input_name->type, GSS_C_NT_HOSTBASED_SERVICE))
    {
      char *p;

      /* We don't support service-names without hostname part because
         we can't compute a canonicalized name of the local host.
         Calling gethostname does not give a canonicalized name. */
      if (!memchr (input_name->value, '@', input_name->length))
	{
	  *minor_status = GSS_KRB5_S_G_BAD_SERVICE_NAME;
	  return GSS_S_COMPLETE;
	}

      /* We don't do DNS name canoncalization since that is
         insecure. */

      maj_stat = gss_duplicate_name (minor_status, input_name, output_name);
      if (GSS_ERROR (maj_stat))
	return maj_stat;

      (*output_name)->type = GSS_KRB5_NT_PRINCIPAL_NAME;

      p = memchr ((*output_name)->value, '@', (*output_name)->length);
      if (p)
	*p = '/';
    }
  else if (gss_oid_equal (input_name->type, GSS_KRB5_NT_PRINCIPAL_NAME))
    {
      maj_stat = gss_duplicate_name (minor_status, input_name, output_name);
      if (GSS_ERROR (maj_stat))
	return maj_stat;
    }
  else
    {
      *output_name = GSS_C_NO_NAME;
      return GSS_S_BAD_NAMETYPE;
    }

  return GSS_S_COMPLETE;
}

#define TOK_LEN 2
#define MECH_OID_LEN_LEN 2
#define MECH_OID_ASN1_LEN_LEN 2
#define NAME_LEN_LEN 4

OM_uint32
gss_krb5_export_name (OM_uint32 * minor_status,
		      const gss_name_t input_name, gss_buffer_t exported_name)
{
  size_t msglen = input_name->length & 0xFFFFFFFF;
  size_t len = TOK_LEN +
    MECH_OID_LEN_LEN + MECH_OID_ASN1_LEN_LEN + GSS_KRB5->length +
    NAME_LEN_LEN + msglen;
  char *p;

  exported_name->length = len;
  p = exported_name->value = malloc (len);
  if (!p)
    {
      if (minor_status)
	*minor_status = ENOMEM;
      return GSS_S_FAILURE;
    }

  sprintf (p, "\x04\x01\x01\x0B\x06\x09%s", (char *) GSS_KRB5->elements);
  p[2] = '\0';
  p += 15;
  *p++ = (msglen >> 24) & 0xFF;
  *p++ = (msglen >> 16) & 0xFF;
  *p++ = (msglen >> 8) & 0xFF;
  *p++ = msglen & 0xFF;
  memcpy (p, input_name->value, msglen);

  if (minor_status)
    *minor_status = 0;
  return GSS_S_COMPLETE;
}