1 /* meta.c --- Implementation of function selection depending on mechanism.
2  * Copyright (C) 2003-2014 Simon Josefsson
3  *
4  * This file is part of the Generic Security Service (GSS).
5  *
6  * GSS is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS; if not, see http://www.gnu.org/licenses or write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19  * Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "internal.h"
24 #include "meta.h"
25 
26 #ifdef USE_KERBEROS5
27 # include <gss/krb5.h>
28 # include "krb5/protos.h"
29 #endif
30 
31 static _gss_mech_api_desc _gss_mech_apis[] = {
32 #ifdef USE_KERBEROS5
33   {
34    &GSS_KRB5_static,
35    "GS2-KRB5",
36    "Kerberos V5",
37    N_("Kerberos V5 GSS-API mechanism"),
38    {
39     /* Mandatory name-types. */
40     &GSS_KRB5_NT_PRINCIPAL_NAME_static,
41     &GSS_C_NT_HOSTBASED_SERVICE_static,
42     &GSS_C_NT_EXPORT_NAME_static},
43    gss_krb5_init_sec_context,
44    gss_krb5_canonicalize_name,
45    gss_krb5_export_name,
46    gss_krb5_wrap,
47    gss_krb5_unwrap,
48    gss_krb5_get_mic,
49    gss_krb5_verify_mic,
50    gss_krb5_display_status,
51    gss_krb5_acquire_cred,
52    gss_krb5_release_cred,
53    gss_krb5_accept_sec_context,
54    gss_krb5_delete_sec_context,
55    gss_krb5_context_time,
56    gss_krb5_inquire_cred,
57    gss_krb5_inquire_cred_by_mech},
58 #endif
59   {
60    NULL,
61    NULL,
62    NULL,
63    NULL,
64    {
65     NULL,
66     NULL,
67     NULL},
68    NULL,
69    NULL,
70    NULL,
71    NULL,
72    NULL,
73    NULL,
74    NULL,
75    NULL,
76    NULL,
77    NULL,
78    NULL,
79    NULL,
80    NULL,
81    NULL,
82    NULL}
83 };
84 
85 _gss_mech_api_t
_gss_find_mech_no_default(const gss_OID oid)86 _gss_find_mech_no_default (const gss_OID oid)
87 {
88   size_t i;
89 
90   for (i = 0; _gss_mech_apis[i].mech; i++)
91     if (gss_oid_equal (oid, _gss_mech_apis[i].mech))
92       return &_gss_mech_apis[i];
93 
94   return NULL;
95 }
96 
97 _gss_mech_api_t
_gss_find_mech(const gss_OID oid)98 _gss_find_mech (const gss_OID oid)
99 {
100   _gss_mech_api_t p = _gss_find_mech_no_default (oid);
101 
102   if (!p && _gss_mech_apis[0].mech)
103     /* FIXME.  When we support more than one mechanism, make it possible
104        to configure the default mechanism. */
105     return &_gss_mech_apis[0];
106 
107   return p;
108 }
109 
110 _gss_mech_api_t
_gss_find_mech_by_saslname(const gss_buffer_t sasl_mech_name)111 _gss_find_mech_by_saslname (const gss_buffer_t sasl_mech_name)
112 {
113   size_t i;
114 
115   if (sasl_mech_name == NULL
116       || sasl_mech_name->value == NULL || sasl_mech_name->length == 0)
117     return NULL;
118 
119   for (i = 0; _gss_mech_apis[i].mech; i++)
120     if (strlen (_gss_mech_apis[i].sasl_name) == sasl_mech_name->length &&
121 	memcmp (_gss_mech_apis[i].sasl_name, sasl_mech_name->value,
122 		sasl_mech_name->length) == 0)
123       return &_gss_mech_apis[i];
124 
125   return NULL;
126 }
127 
128 OM_uint32
_gss_indicate_mechs1(OM_uint32 * minor_status,gss_OID_set * mech_set)129 _gss_indicate_mechs1 (OM_uint32 * minor_status, gss_OID_set * mech_set)
130 {
131   OM_uint32 maj_stat;
132   int i;
133 
134   for (i = 0; _gss_mech_apis[i].mech; i++)
135     {
136       maj_stat = gss_add_oid_set_member (minor_status,
137 					 _gss_mech_apis[i].mech, mech_set);
138       if (GSS_ERROR (maj_stat))
139 	return maj_stat;
140     }
141 
142   if (minor_status)
143     *minor_status = 0;
144   return GSS_S_COMPLETE;
145 }
146