1.13.1
by Colin Watson
Import upstream version 4.6p1 |
1 |
/* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
2 |
|
3 |
/*
|
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
4 |
* Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
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 |
* 1. Redistributions of source code must retain the above copyright
|
|
10 |
* notice, this list of conditions and the following disclaimer.
|
|
11 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
12 |
* notice, this list of conditions and the following disclaimer in the
|
|
13 |
* documentation and/or other materials provided with the distribution.
|
|
14 |
*
|
|
15 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
|
|
16 |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
17 |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
18 |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
19 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
20 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
21 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
22 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
24 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25 |
*/
|
|
26 |
||
27 |
#include "includes.h" |
|
28 |
||
29 |
#ifdef GSSAPI
|
|
30 |
#ifdef KRB5
|
|
31 |
||
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
32 |
#include <sys/types.h> |
33 |
||
34 |
#include <stdarg.h> |
|
35 |
#include <string.h> |
|
36 |
||
37 |
#include "xmalloc.h" |
|
38 |
#include "key.h" |
|
39 |
#include "hostfile.h" |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
40 |
#include "auth.h" |
41 |
#include "log.h" |
|
42 |
#include "servconf.h" |
|
43 |
||
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
44 |
#include "buffer.h" |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
45 |
#include "ssh-gss.h" |
46 |
||
47 |
extern ServerOptions options; |
|
48 |
||
49 |
#ifdef HEIMDAL
|
|
50 |
# include <krb5.h>
|
|
51 |
#else
|
|
5
by Colin Watson
Resynchronise with Debian. |
52 |
# ifdef HAVE_GSSAPI_KRB5_H
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
53 |
# include <gssapi_krb5.h>
|
5
by Colin Watson
Resynchronise with Debian. |
54 |
# elif HAVE_GSSAPI_GSSAPI_KRB5_H
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
55 |
# include <gssapi/gssapi_krb5.h>
|
56 |
# endif
|
|
57 |
#endif
|
|
58 |
||
59 |
static krb5_context krb_context = NULL; |
|
60 |
||
61 |
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
|
|
62 |
||
63 |
static int |
|
1.1.1
by Colin Watson
Import upstream version 3.9p1 |
64 |
ssh_gssapi_krb5_init(void) |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
65 |
{
|
66 |
krb5_error_code problem; |
|
67 |
||
68 |
if (krb_context != NULL) |
|
69 |
return 1; |
|
70 |
||
71 |
problem = krb5_init_context(&krb_context); |
|
72 |
if (problem) { |
|
73 |
logit("Cannot initialize krb5 context"); |
|
74 |
return 0; |
|
75 |
}
|
|
76 |
||
77 |
return 1; |
|
78 |
}
|
|
79 |
||
80 |
/* Check if this user is OK to login. This only works with krb5 - other
|
|
81 |
* GSSAPI mechanisms will need their own.
|
|
82 |
* Returns true if the user is OK to log in, otherwise returns 0
|
|
83 |
*/
|
|
84 |
||
85 |
static int |
|
86 |
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) |
|
87 |
{
|
|
88 |
krb5_principal princ; |
|
89 |
int retval; |
|
90 |
||
91 |
if (ssh_gssapi_krb5_init() == 0) |
|
92 |
return 0; |
|
93 |
||
94 |
if ((retval = krb5_parse_name(krb_context, client->exportedname.value, |
|
95 |
&princ))) { |
|
96 |
logit("krb5_parse_name(): %.100s", |
|
97 |
krb5_get_err_text(krb_context, retval)); |
|
98 |
return 0; |
|
99 |
}
|
|
100 |
if (krb5_kuserok(krb_context, princ, name)) { |
|
101 |
retval = 1; |
|
102 |
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", |
|
103 |
name, (char *)client->displayname.value); |
|
104 |
} else |
|
105 |
retval = 0; |
|
106 |
||
107 |
krb5_free_principal(krb_context, princ); |
|
108 |
return retval; |
|
109 |
}
|
|
110 |
||
111 |
||
112 |
/* This writes out any forwarded credentials from the structure populated
|
|
113 |
* during userauth. Called after we have setuid to the user */
|
|
114 |
||
115 |
static void |
|
116 |
ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) |
|
117 |
{
|
|
118 |
krb5_ccache ccache; |
|
119 |
krb5_error_code problem; |
|
120 |
krb5_principal princ; |
|
121 |
OM_uint32 maj_status, min_status; |
|
122 |
int len; |
|
21
by Colin Watson
* New upstream release (closes: #395507, #397961, #420035). Important |
123 |
const char *new_ccname; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
124 |
|
125 |
if (client->creds == NULL) { |
|
126 |
debug("No credentials stored"); |
|
127 |
return; |
|
128 |
}
|
|
129 |
||
130 |
if (ssh_gssapi_krb5_init() == 0) |
|
131 |
return; |
|
132 |
||
133 |
#ifdef HEIMDAL
|
|
134 |
if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { |
|
135 |
logit("krb5_cc_gen_new(): %.100s", |
|
136 |
krb5_get_err_text(krb_context, problem)); |
|
137 |
return; |
|
138 |
}
|
|
139 |
#else
|
|
1.1.3
by Colin Watson
Import upstream version 4.2p1 |
140 |
if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { |
141 |
logit("ssh_krb5_cc_gen(): %.100s", |
|
142 |
krb5_get_err_text(krb_context, problem)); |
|
143 |
return; |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
144 |
}
|
145 |
#endif /* #ifdef HEIMDAL */ |
|
146 |
||
147 |
if ((problem = krb5_parse_name(krb_context, |
|
148 |
client->exportedname.value, &princ))) { |
|
149 |
logit("krb5_parse_name(): %.100s", |
|
150 |
krb5_get_err_text(krb_context, problem)); |
|
151 |
krb5_cc_destroy(krb_context, ccache); |
|
152 |
return; |
|
153 |
}
|
|
154 |
||
155 |
if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { |
|
156 |
logit("krb5_cc_initialize(): %.100s", |
|
157 |
krb5_get_err_text(krb_context, problem)); |
|
158 |
krb5_free_principal(krb_context, princ); |
|
159 |
krb5_cc_destroy(krb_context, ccache); |
|
160 |
return; |
|
161 |
}
|
|
162 |
||
163 |
krb5_free_principal(krb_context, princ); |
|
164 |
||
165 |
if ((maj_status = gss_krb5_copy_ccache(&min_status, |
|
166 |
client->creds, ccache))) { |
|
167 |
logit("gss_krb5_copy_ccache() failed"); |
|
168 |
krb5_cc_destroy(krb_context, ccache); |
|
169 |
return; |
|
170 |
}
|
|
171 |
||
21
by Colin Watson
* New upstream release (closes: #395507, #397961, #420035). Important |
172 |
new_ccname = krb5_cc_get_name(krb_context, ccache); |
173 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
174 |
client->store.envvar = "KRB5CCNAME"; |
21
by Colin Watson
* New upstream release (closes: #395507, #397961, #420035). Important |
175 |
#ifdef USE_CCAPI
|
176 |
xasprintf(&client->store.envval, "API:%s", new_ccname); |
|
177 |
client->store.filename = NULL; |
|
178 |
#else
|
|
179 |
xasprintf(&client->store.envval, "FILE:%s", new_ccname); |
|
180 |
client->store.filename = xstrdup(new_ccname); |
|
181 |
#endif
|
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
182 |
|
183 |
#ifdef USE_PAM
|
|
184 |
if (options.use_pam) |
|
185 |
do_pam_putenv(client->store.envvar, client->store.envval); |
|
186 |
#endif
|
|
187 |
||
188 |
krb5_cc_close(krb_context, ccache); |
|
189 |
||
190 |
return; |
|
191 |
}
|
|
192 |
||
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
193 |
int
|
194 |
ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, |
|
195 |
ssh_gssapi_client *client) |
|
196 |
{
|
|
197 |
krb5_ccache ccache = NULL; |
|
198 |
krb5_principal principal = NULL; |
|
199 |
char *name = NULL; |
|
200 |
krb5_error_code problem; |
|
201 |
OM_uint32 maj_status, min_status; |
|
202 |
||
203 |
if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) { |
|
204 |
logit("krb5_cc_resolve(): %.100s", |
|
205 |
krb5_get_err_text(krb_context, problem)); |
|
206 |
return 0; |
|
207 |
}
|
|
208 |
||
209 |
/* Find out who the principal in this cache is */
|
|
210 |
if ((problem = krb5_cc_get_principal(krb_context, ccache, |
|
211 |
&principal))) { |
|
212 |
logit("krb5_cc_get_principal(): %.100s", |
|
213 |
krb5_get_err_text(krb_context, problem)); |
|
214 |
krb5_cc_close(krb_context, ccache); |
|
215 |
return 0; |
|
216 |
}
|
|
217 |
||
218 |
if ((problem = krb5_unparse_name(krb_context, principal, &name))) { |
|
219 |
logit("krb5_unparse_name(): %.100s", |
|
220 |
krb5_get_err_text(krb_context, problem)); |
|
221 |
krb5_free_principal(krb_context, principal); |
|
222 |
krb5_cc_close(krb_context, ccache); |
|
223 |
return 0; |
|
224 |
}
|
|
225 |
||
226 |
||
227 |
if (strcmp(name,client->exportedname.value)!=0) { |
|
228 |
debug("Name in local credentials cache differs. Not storing"); |
|
229 |
krb5_free_principal(krb_context, principal); |
|
230 |
krb5_cc_close(krb_context, ccache); |
|
231 |
krb5_free_unparsed_name(krb_context, name); |
|
232 |
return 0; |
|
233 |
}
|
|
234 |
krb5_free_unparsed_name(krb_context, name); |
|
235 |
||
236 |
/* Name matches, so lets get on with it! */
|
|
237 |
||
238 |
if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) { |
|
239 |
logit("krb5_cc_initialize(): %.100s", |
|
240 |
krb5_get_err_text(krb_context, problem)); |
|
241 |
krb5_free_principal(krb_context, principal); |
|
242 |
krb5_cc_close(krb_context, ccache); |
|
243 |
return 0; |
|
244 |
}
|
|
245 |
||
246 |
krb5_free_principal(krb_context, principal); |
|
247 |
||
248 |
if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds, |
|
249 |
ccache))) { |
|
250 |
logit("gss_krb5_copy_ccache() failed. Sorry!"); |
|
251 |
krb5_cc_close(krb_context, ccache); |
|
252 |
return 0; |
|
253 |
}
|
|
254 |
||
255 |
return 1; |
|
256 |
}
|
|
257 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
258 |
ssh_gssapi_mech gssapi_kerberos_mech = { |
259 |
"toWM5Slw5Ew8Mqkay+al2g==", |
|
260 |
"Kerberos", |
|
261 |
{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, |
|
262 |
NULL, |
|
263 |
&ssh_gssapi_krb5_userok, |
|
264 |
NULL, |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
265 |
&ssh_gssapi_krb5_storecreds, |
266 |
&ssh_gssapi_krb5_updatecreds |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
267 |
};
|
268 |
||
269 |
#endif /* KRB5 */ |
|
270 |
||
271 |
#endif /* GSSAPI */ |