Branch data Line data Source code
1 : : /* krb5/cred.c --- Kerberos 5 GSS-API credential management functions.
2 : : * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010 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 : : /* Get specification. */
24 : : #include "k5internal.h"
25 : :
26 : : static OM_uint32
27 : 1 : acquire_cred1 (OM_uint32 * minor_status,
28 : : const gss_name_t desired_name,
29 : : OM_uint32 time_req,
30 : : const gss_OID_set desired_mechs,
31 : : gss_cred_usage_t cred_usage,
32 : : gss_cred_id_t * output_cred_handle,
33 : : gss_OID_set * actual_mechs, OM_uint32 * time_rec)
34 : : {
35 : 1 : gss_name_t name = desired_name;
36 : 1 : _gss_krb5_cred_t k5 = (*output_cred_handle)->krb5;
37 : : OM_uint32 maj_stat;
38 : :
39 [ - + ]: 1 : if (desired_name == GSS_C_NO_NAME)
40 : : {
41 : 0 : gss_buffer_desc buf = { 4, (char *) "host" };
42 : :
43 : 0 : maj_stat = gss_import_name (minor_status, &buf,
44 : : GSS_C_NT_HOSTBASED_SERVICE, &name);
45 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
46 : 0 : return maj_stat;
47 : : }
48 : :
49 : 1 : maj_stat = gss_krb5_canonicalize_name (minor_status, name,
50 : : GSS_KRB5, &k5->peerptr);
51 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
52 : 0 : return maj_stat;
53 : :
54 [ - + ]: 1 : if (desired_name == GSS_C_NO_NAME)
55 : : {
56 : 0 : maj_stat = gss_release_name (minor_status, &name);
57 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
58 : 0 : return maj_stat;
59 : : }
60 : :
61 [ - + ]: 1 : if (shishi_init_server (&k5->sh) != SHISHI_OK)
62 : 0 : return GSS_S_FAILURE;
63 : :
64 : : {
65 : : char *p;
66 : :
67 : 1 : p = malloc (k5->peerptr->length + 1);
68 [ - + ]: 1 : if (!p)
69 : : {
70 [ # # ]: 0 : if (minor_status)
71 : 0 : *minor_status = ENOMEM;
72 : 0 : return GSS_S_FAILURE;
73 : : }
74 : 1 : memcpy (p, k5->peerptr->value, k5->peerptr->length);
75 : 1 : p[k5->peerptr->length] = 0;
76 : :
77 : 1 : k5->key = shishi_hostkeys_for_serverrealm (k5->sh, p, NULL);
78 : :
79 : 1 : free (p);
80 : : }
81 : :
82 [ - + ]: 1 : if (!k5->key)
83 : : {
84 [ # # ]: 0 : if (minor_status)
85 : 0 : *minor_status = GSS_KRB5_S_KG_KEYTAB_NOMATCH;
86 : 0 : return GSS_S_NO_CRED;
87 : : }
88 : :
89 [ - + ]: 1 : if (time_rec)
90 : 0 : *time_rec = GSS_C_INDEFINITE;
91 : :
92 : 1 : return GSS_S_COMPLETE;
93 : : }
94 : :
95 : : OM_uint32
96 : 1 : gss_krb5_acquire_cred (OM_uint32 * minor_status,
97 : : const gss_name_t desired_name,
98 : : OM_uint32 time_req,
99 : : const gss_OID_set desired_mechs,
100 : : gss_cred_usage_t cred_usage,
101 : : gss_cred_id_t * output_cred_handle,
102 : : gss_OID_set * actual_mechs, OM_uint32 * time_rec)
103 : : {
104 : : OM_uint32 maj_stat;
105 : 1 : gss_cred_id_t p = *output_cred_handle;
106 : :
107 : 1 : p->krb5 = calloc (sizeof (*p->krb5), 1);
108 [ - + ]: 1 : if (!p->krb5)
109 : : {
110 [ # # ]: 0 : if (minor_status)
111 : 0 : *minor_status = ENOMEM;
112 : 0 : return GSS_S_FAILURE;
113 : : }
114 : :
115 [ - + ]: 1 : if (actual_mechs)
116 : : {
117 : 0 : maj_stat = gss_create_empty_oid_set (minor_status, actual_mechs);
118 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
119 : : {
120 : 0 : free (p->krb5);
121 : 0 : return maj_stat;
122 : : }
123 : 0 : maj_stat = gss_add_oid_set_member (minor_status, GSS_KRB5,
124 : : actual_mechs);
125 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
126 : : {
127 : 0 : free (p->krb5);
128 : 0 : return maj_stat;
129 : : }
130 : : }
131 : :
132 : 1 : maj_stat = acquire_cred1 (minor_status, desired_name, time_req,
133 : : desired_mechs, cred_usage,
134 : : &p, actual_mechs, time_rec);
135 [ - + ]: 1 : if (GSS_ERROR (maj_stat))
136 : : {
137 [ # # ]: 0 : if (actual_mechs)
138 : 0 : gss_release_oid_set (NULL, actual_mechs);
139 : 0 : free (p->krb5);
140 : :
141 : 0 : return maj_stat;
142 : : }
143 : :
144 [ + - ]: 1 : if (minor_status)
145 : 1 : *minor_status = 0;
146 : 1 : return GSS_S_COMPLETE;
147 : : }
148 : :
149 : : static OM_uint32
150 : 0 : inquire_cred (OM_uint32 * minor_status,
151 : : const gss_cred_id_t cred_handle,
152 : : gss_name_t * name,
153 : : OM_uint32 * lifetime,
154 : : gss_cred_usage_t * cred_usage, gss_OID_set * mechanisms)
155 : : {
156 : : OM_uint32 maj_stat;
157 : :
158 [ # # ]: 0 : if (cred_handle == GSS_C_NO_CREDENTIAL)
159 : 0 : return GSS_S_NO_CRED;
160 : :
161 [ # # ]: 0 : if (mechanisms)
162 : : {
163 : 0 : maj_stat = gss_create_empty_oid_set (minor_status, mechanisms);
164 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
165 : 0 : return maj_stat;
166 : 0 : maj_stat = gss_add_oid_set_member (minor_status, GSS_KRB5, mechanisms);
167 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
168 : 0 : return maj_stat;
169 : : }
170 : :
171 [ # # ]: 0 : if (name)
172 : : {
173 : 0 : maj_stat = gss_duplicate_name (minor_status, cred_handle->krb5->peerptr,
174 : : name);
175 [ # # ]: 0 : if (GSS_ERROR (maj_stat))
176 : 0 : return maj_stat;
177 : : }
178 : :
179 [ # # ]: 0 : if (cred_usage)
180 : 0 : *cred_usage = GSS_C_BOTH;
181 : :
182 [ # # ]: 0 : if (lifetime)
183 : 0 : *lifetime = GSS_C_INDEFINITE;
184 : :
185 [ # # ]: 0 : if (minor_status)
186 : 0 : *minor_status = 0;
187 : 0 : return GSS_S_COMPLETE;
188 : : }
189 : :
190 : : OM_uint32
191 : 0 : gss_krb5_inquire_cred (OM_uint32 * minor_status,
192 : : const gss_cred_id_t cred_handle,
193 : : gss_name_t * name,
194 : : OM_uint32 * lifetime,
195 : : gss_cred_usage_t * cred_usage,
196 : : gss_OID_set * mechanisms)
197 : : {
198 : 0 : return inquire_cred (minor_status, cred_handle, name, lifetime,
199 : : cred_usage, mechanisms);
200 : : }
201 : :
202 : : OM_uint32
203 : 0 : gss_krb5_inquire_cred_by_mech (OM_uint32 * minor_status,
204 : : const gss_cred_id_t cred_handle,
205 : : const gss_OID mech_type,
206 : : gss_name_t * name,
207 : : OM_uint32 * initiator_lifetime,
208 : : OM_uint32 * acceptor_lifetime,
209 : : gss_cred_usage_t * cred_usage)
210 : : {
211 : : OM_uint32 maj_stat;
212 : :
213 : 0 : maj_stat = inquire_cred (minor_status, cred_handle, name,
214 : : initiator_lifetime, cred_usage, NULL);
215 : :
216 [ # # ]: 0 : if (acceptor_lifetime)
217 : 0 : *acceptor_lifetime = *initiator_lifetime;
218 : :
219 : 0 : return maj_stat;
220 : : }
221 : :
222 : : OM_uint32
223 : 1 : gss_krb5_release_cred (OM_uint32 * minor_status, gss_cred_id_t * cred_handle)
224 : : {
225 : 1 : _gss_krb5_cred_t k5 = (*cred_handle)->krb5;
226 : :
227 [ + - ]: 1 : if (k5->peerptr != GSS_C_NO_NAME)
228 : 1 : gss_release_name (NULL, &k5->peerptr);
229 : :
230 : 1 : shishi_key_done (k5->key);
231 : 1 : shishi_done (k5->sh);
232 : 1 : free (k5);
233 : :
234 [ + - ]: 1 : if (minor_status)
235 : 1 : *minor_status = 0;
236 : 1 : return GSS_S_COMPLETE;
237 : : }
|