1.13.3
by Colin Watson
Import upstream version 5.1p1 |
1 |
/* $OpenBSD: gss-serv.c,v 1.22 2008/05/08 12:02:23 djm 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-2009 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 |
||
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
31 |
#include <sys/types.h> |
1.13.2
by Colin Watson
Import upstream version 4.7p1 |
32 |
#include <sys/param.h> |
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
33 |
|
34 |
#include <stdarg.h> |
|
35 |
#include <string.h> |
|
36 |
#include <unistd.h> |
|
37 |
||
1.13.3
by Colin Watson
Import upstream version 5.1p1 |
38 |
#include "openbsd-compat/sys-queue.h" |
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
39 |
#include "xmalloc.h" |
40 |
#include "buffer.h" |
|
41 |
#include "key.h" |
|
42 |
#include "hostfile.h" |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
43 |
#include "auth.h" |
44 |
#include "log.h" |
|
45 |
#include "channels.h" |
|
46 |
#include "session.h" |
|
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
47 |
#include "misc.h" |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
48 |
#include "servconf.h" |
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
49 |
#include "uidswap.h" |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
50 |
|
51 |
#include "ssh-gss.h" |
|
10
by Colin Watson
* Resynchronise with Debian. |
52 |
#include "monitor_wrap.h" |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
53 |
|
21
by Colin Watson
* New upstream release (closes: #395507, #397961, #420035). Important |
54 |
extern ServerOptions options; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
55 |
|
56 |
static ssh_gssapi_client gssapi_client = |
|
57 |
{ GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
58 |
GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME, NULL, {NULL, NULL, NULL}, 0, 0}; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
59 |
|
60 |
ssh_gssapi_mech gssapi_null_mech = |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
61 |
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL}; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
62 |
|
63 |
#ifdef KRB5
|
|
64 |
extern ssh_gssapi_mech gssapi_kerberos_mech; |
|
65 |
#endif
|
|
66 |
||
67 |
ssh_gssapi_mech* supported_mechs[]= { |
|
68 |
#ifdef KRB5
|
|
69 |
&gssapi_kerberos_mech, |
|
70 |
#endif
|
|
71 |
&gssapi_null_mech, |
|
72 |
};
|
|
73 |
||
1.13.2
by Colin Watson
Import upstream version 4.7p1 |
74 |
|
75 |
/*
|
|
76 |
* Acquire credentials for a server running on the current host.
|
|
77 |
* Requires that the context structure contains a valid OID
|
|
78 |
*/
|
|
79 |
||
80 |
/* Returns a GSSAPI error code */
|
|
81 |
/* Privileged (called from ssh_gssapi_server_ctx) */
|
|
82 |
static OM_uint32 |
|
83 |
ssh_gssapi_acquire_cred(Gssctxt *ctx) |
|
84 |
{
|
|
85 |
OM_uint32 status; |
|
86 |
char lname[MAXHOSTNAMELEN]; |
|
87 |
gss_OID_set oidset; |
|
88 |
||
34
by Colin Watson
* Resynchronise with Debian. Remaining changes: |
89 |
if (options.gss_strict_acceptor) { |
90 |
gss_create_empty_oid_set(&status, &oidset); |
|
91 |
gss_add_oid_set_member(&status, ctx->oid, &oidset); |
|
92 |
||
93 |
if (gethostname(lname, MAXHOSTNAMELEN)) { |
|
94 |
gss_release_oid_set(&status, &oidset); |
|
95 |
return (-1); |
|
96 |
}
|
|
97 |
||
98 |
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { |
|
99 |
gss_release_oid_set(&status, &oidset); |
|
100 |
return (ctx->major); |
|
101 |
}
|
|
102 |
||
103 |
if ((ctx->major = gss_acquire_cred(&ctx->minor, |
|
104 |
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, |
|
105 |
NULL, NULL))) |
|
106 |
ssh_gssapi_error(ctx); |
|
107 |
||
1.13.2
by Colin Watson
Import upstream version 4.7p1 |
108 |
gss_release_oid_set(&status, &oidset); |
109 |
return (ctx->major); |
|
34
by Colin Watson
* Resynchronise with Debian. Remaining changes: |
110 |
} else { |
111 |
ctx->name = GSS_C_NO_NAME; |
|
112 |
ctx->creds = GSS_C_NO_CREDENTIAL; |
|
1.13.2
by Colin Watson
Import upstream version 4.7p1 |
113 |
}
|
34
by Colin Watson
* Resynchronise with Debian. Remaining changes: |
114 |
return GSS_S_COMPLETE; |
1.13.2
by Colin Watson
Import upstream version 4.7p1 |
115 |
}
|
116 |
||
117 |
/* Privileged */
|
|
118 |
OM_uint32
|
|
119 |
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) |
|
120 |
{
|
|
121 |
if (*ctx) |
|
122 |
ssh_gssapi_delete_ctx(ctx); |
|
123 |
ssh_gssapi_build_ctx(ctx); |
|
124 |
ssh_gssapi_set_oid(*ctx, oid); |
|
125 |
return (ssh_gssapi_acquire_cred(*ctx)); |
|
126 |
}
|
|
127 |
||
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
128 |
/* Unprivileged */
|
5
by Colin Watson
Resynchronise with Debian. |
129 |
char * |
130 |
ssh_gssapi_server_mechanisms() { |
|
131 |
gss_OID_set supported; |
|
132 |
||
133 |
ssh_gssapi_supported_oids(&supported); |
|
134 |
return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech, |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
135 |
NULL, NULL)); |
5
by Colin Watson
Resynchronise with Debian. |
136 |
}
|
137 |
||
10
by Colin Watson
* Resynchronise with Debian. |
138 |
/* Unprivileged */
|
5
by Colin Watson
Resynchronise with Debian. |
139 |
int
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
140 |
ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data, |
141 |
const char *dummy) { |
|
21
by Colin Watson
* New upstream release (closes: #395507, #397961, #420035). Important |
142 |
Gssctxt *ctx = NULL; |
5
by Colin Watson
Resynchronise with Debian. |
143 |
int res; |
10
by Colin Watson
* Resynchronise with Debian. |
144 |
|
5
by Colin Watson
Resynchronise with Debian. |
145 |
res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); |
146 |
ssh_gssapi_delete_ctx(&ctx); |
|
147 |
||
148 |
return (res); |
|
149 |
}
|
|
150 |
||
10
by Colin Watson
* Resynchronise with Debian. |
151 |
/* Unprivileged */
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
152 |
void
|
153 |
ssh_gssapi_supported_oids(gss_OID_set *oidset) |
|
154 |
{
|
|
155 |
int i = 0; |
|
156 |
OM_uint32 min_status; |
|
157 |
int present; |
|
158 |
gss_OID_set supported; |
|
159 |
||
160 |
gss_create_empty_oid_set(&min_status, oidset); |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
161 |
|
162 |
if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported))) |
|
163 |
return; |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
164 |
|
165 |
while (supported_mechs[i]->name != NULL) { |
|
166 |
if (GSS_ERROR(gss_test_oid_set_member(&min_status, |
|
167 |
&supported_mechs[i]->oid, supported, &present))) |
|
168 |
present = 0; |
|
169 |
if (present) |
|
170 |
gss_add_oid_set_member(&min_status, |
|
171 |
&supported_mechs[i]->oid, oidset); |
|
172 |
i++; |
|
173 |
}
|
|
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
174 |
|
175 |
gss_release_oid_set(&min_status, &supported); |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
176 |
}
|
177 |
||
178 |
||
179 |
/* Wrapper around accept_sec_context
|
|
180 |
* Requires that the context contains:
|
|
181 |
* oid
|
|
182 |
* credentials (from ssh_gssapi_acquire_cred)
|
|
183 |
*/
|
|
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
184 |
/* Privileged */
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
185 |
OM_uint32
|
186 |
ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, |
|
187 |
gss_buffer_desc *send_tok, OM_uint32 *flags) |
|
188 |
{
|
|
189 |
OM_uint32 status; |
|
190 |
gss_OID mech; |
|
191 |
||
192 |
ctx->major = gss_accept_sec_context(&ctx->minor, |
|
193 |
&ctx->context, ctx->creds, recv_tok, |
|
194 |
GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech, |
|
195 |
send_tok, flags, NULL, &ctx->client_creds); |
|
196 |
||
197 |
if (GSS_ERROR(ctx->major)) |
|
198 |
ssh_gssapi_error(ctx); |
|
199 |
||
200 |
if (ctx->client_creds) |
|
201 |
debug("Received some client credentials"); |
|
202 |
else
|
|
203 |
debug("Got no client credentials"); |
|
204 |
||
205 |
status = ctx->major; |
|
206 |
||
207 |
/* Now, if we're complete and we have the right flags, then
|
|
208 |
* we flag the user as also having been authenticated
|
|
209 |
*/
|
|
210 |
||
211 |
if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && |
|
212 |
(*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { |
|
213 |
if (ssh_gssapi_getclient(ctx, &gssapi_client)) |
|
214 |
fatal("Couldn't convert client name"); |
|
215 |
}
|
|
216 |
||
217 |
return (status); |
|
218 |
}
|
|
219 |
||
220 |
/*
|
|
221 |
* This parses an exported name, extracting the mechanism specific portion
|
|
222 |
* to use for ACL checking. It verifies that the name belongs the mechanism
|
|
223 |
* originally selected.
|
|
224 |
*/
|
|
225 |
static OM_uint32 |
|
226 |
ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) |
|
227 |
{
|
|
1.1.3
by Colin Watson
Import upstream version 4.2p1 |
228 |
u_char *tok; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
229 |
OM_uint32 offset; |
230 |
OM_uint32 oidl; |
|
231 |
||
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
232 |
tok = ename->value; |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
233 |
|
234 |
/*
|
|
235 |
* Check that ename is long enough for all of the fixed length
|
|
236 |
* header, and that the initial ID bytes are correct
|
|
237 |
*/
|
|
238 |
||
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
239 |
if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0) |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
240 |
return GSS_S_FAILURE; |
241 |
||
242 |
/*
|
|
243 |
* Extract the OID, and check it. Here GSSAPI breaks with tradition
|
|
244 |
* and does use the OID type and length bytes. To confuse things
|
|
245 |
* there are two lengths - the first including these, and the
|
|
246 |
* second without.
|
|
247 |
*/
|
|
248 |
||
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
249 |
oidl = get_u16(tok+2); /* length including next two bytes */ |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
250 |
oidl = oidl-2; /* turn it into the _real_ length of the variable OID */ |
251 |
||
252 |
/*
|
|
253 |
* Check the BER encoding for correct type and length, that the
|
|
254 |
* string is long enough and that the OID matches that in our context
|
|
255 |
*/
|
|
256 |
if (tok[4] != 0x06 || tok[5] != oidl || |
|
257 |
ename->length < oidl+6 || |
|
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
258 |
!ssh_gssapi_check_oid(ctx, tok+6, oidl)) |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
259 |
return GSS_S_FAILURE; |
260 |
||
261 |
offset = oidl+6; |
|
262 |
||
263 |
if (ename->length < offset+4) |
|
264 |
return GSS_S_FAILURE; |
|
265 |
||
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
266 |
name->length = get_u32(tok+offset); |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
267 |
offset += 4; |
268 |
||
269 |
if (ename->length < offset+name->length) |
|
270 |
return GSS_S_FAILURE; |
|
271 |
||
272 |
name->value = xmalloc(name->length+1); |
|
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
273 |
memcpy(name->value, tok+offset, name->length); |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
274 |
((char *)name->value)[name->length] = 0; |
275 |
||
276 |
return GSS_S_COMPLETE; |
|
277 |
}
|
|
278 |
||
279 |
/* Extract the client details from a given context. This can only reliably
|
|
280 |
* be called once for a context */
|
|
281 |
||
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
282 |
/* Privileged (called from accept_secure_ctx) */
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
283 |
OM_uint32
|
284 |
ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) |
|
285 |
{
|
|
286 |
int i = 0; |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
287 |
int equal = 0; |
288 |
gss_name_t new_name = GSS_C_NO_NAME; |
|
289 |
gss_buffer_desc ename = GSS_C_EMPTY_BUFFER; |
|
290 |
||
291 |
if (options.gss_store_rekey && client->used && ctx->client_creds) { |
|
292 |
if (client->mech->oid.length != ctx->oid->length || |
|
293 |
(memcmp(client->mech->oid.elements, |
|
294 |
ctx->oid->elements, ctx->oid->length) !=0)) { |
|
295 |
debug("Rekeyed credentials have different mechanism"); |
|
296 |
return GSS_S_COMPLETE; |
|
297 |
}
|
|
298 |
||
299 |
if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, |
|
300 |
ctx->client_creds, ctx->oid, &new_name, |
|
301 |
NULL, NULL, NULL))) { |
|
302 |
ssh_gssapi_error(ctx); |
|
303 |
return (ctx->major); |
|
304 |
}
|
|
305 |
||
306 |
ctx->major = gss_compare_name(&ctx->minor, client->name, |
|
307 |
new_name, &equal); |
|
308 |
||
309 |
if (GSS_ERROR(ctx->major)) { |
|
310 |
ssh_gssapi_error(ctx); |
|
311 |
return (ctx->major); |
|
312 |
}
|
|
313 |
||
314 |
if (!equal) { |
|
315 |
debug("Rekeyed credentials have different name"); |
|
316 |
return GSS_S_COMPLETE; |
|
317 |
}
|
|
318 |
||
319 |
debug("Marking rekeyed credentials for export"); |
|
320 |
||
321 |
gss_release_name(&ctx->minor, &client->name); |
|
322 |
gss_release_cred(&ctx->minor, &client->creds); |
|
323 |
client->name = new_name; |
|
324 |
client->creds = ctx->client_creds; |
|
325 |
ctx->client_creds = GSS_C_NO_CREDENTIAL; |
|
326 |
client->updated = 1; |
|
327 |
return GSS_S_COMPLETE; |
|
328 |
}
|
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
329 |
|
330 |
client->mech = NULL; |
|
331 |
||
332 |
while (supported_mechs[i]->name != NULL) { |
|
333 |
if (supported_mechs[i]->oid.length == ctx->oid->length && |
|
334 |
(memcmp(supported_mechs[i]->oid.elements, |
|
335 |
ctx->oid->elements, ctx->oid->length) == 0)) |
|
336 |
client->mech = supported_mechs[i]; |
|
337 |
i++; |
|
338 |
}
|
|
339 |
||
340 |
if (client->mech == NULL) |
|
341 |
return GSS_S_FAILURE; |
|
342 |
||
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
343 |
if (ctx->client_creds && |
344 |
(ctx->major = gss_inquire_cred_by_mech(&ctx->minor, |
|
345 |
ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) { |
|
346 |
ssh_gssapi_error(ctx); |
|
347 |
return (ctx->major); |
|
348 |
}
|
|
349 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
350 |
if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, |
351 |
&client->displayname, NULL))) { |
|
352 |
ssh_gssapi_error(ctx); |
|
353 |
return (ctx->major); |
|
354 |
}
|
|
355 |
||
356 |
if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, |
|
357 |
&ename))) { |
|
358 |
ssh_gssapi_error(ctx); |
|
359 |
return (ctx->major); |
|
360 |
}
|
|
361 |
||
362 |
if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, |
|
363 |
&client->exportedname))) { |
|
364 |
return (ctx->major); |
|
365 |
}
|
|
366 |
||
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
367 |
gss_release_buffer(&ctx->minor, &ename); |
368 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
369 |
/* We can't copy this structure, so we just move the pointer to it */
|
370 |
client->creds = ctx->client_creds; |
|
371 |
ctx->client_creds = GSS_C_NO_CREDENTIAL; |
|
372 |
return (ctx->major); |
|
373 |
}
|
|
374 |
||
375 |
/* As user - called on fatal/exit */
|
|
376 |
void
|
|
377 |
ssh_gssapi_cleanup_creds(void) |
|
378 |
{
|
|
379 |
if (gssapi_client.store.filename != NULL) { |
|
380 |
/* Unlink probably isn't sufficient */
|
|
1.13.1
by Colin Watson
Import upstream version 4.6p1 |
381 |
debug("removing gssapi cred file\"%s\"", |
382 |
gssapi_client.store.filename); |
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
383 |
unlink(gssapi_client.store.filename); |
384 |
}
|
|
385 |
}
|
|
386 |
||
387 |
/* As user */
|
|
388 |
void
|
|
389 |
ssh_gssapi_storecreds(void) |
|
390 |
{
|
|
391 |
if (gssapi_client.mech && gssapi_client.mech->storecreds) { |
|
392 |
(*gssapi_client.mech->storecreds)(&gssapi_client); |
|
393 |
} else |
|
394 |
debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); |
|
395 |
}
|
|
396 |
||
397 |
/* This allows GSSAPI methods to do things to the childs environment based
|
|
398 |
* on the passed authentication process and credentials.
|
|
399 |
*/
|
|
400 |
/* As user */
|
|
401 |
void
|
|
402 |
ssh_gssapi_do_child(char ***envp, u_int *envsizep) |
|
403 |
{
|
|
404 |
||
405 |
if (gssapi_client.store.envvar != NULL && |
|
406 |
gssapi_client.store.envval != NULL) { |
|
407 |
debug("Setting %s to %s", gssapi_client.store.envvar, |
|
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
408 |
gssapi_client.store.envval); |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
409 |
child_set_env(envp, envsizep, gssapi_client.store.envvar, |
1.1.3
by Colin Watson
Import upstream version 4.2p1 |
410 |
gssapi_client.store.envval); |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
411 |
}
|
412 |
}
|
|
413 |
||
1.6.1
by Colin Watson
Import upstream version 4.3p2 |
414 |
/* Privileged */
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
415 |
int
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
416 |
ssh_gssapi_userok(char *user, struct passwd *pw) |
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
417 |
{
|
4
by Colin Watson
* Add /usr/games to the default $PATH for non-privileged users. |
418 |
OM_uint32 lmin; |
419 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
420 |
if (gssapi_client.exportedname.length == 0 || |
421 |
gssapi_client.exportedname.value == NULL) { |
|
422 |
debug("No suitable client data"); |
|
423 |
return 0; |
|
424 |
}
|
|
425 |
if (gssapi_client.mech && gssapi_client.mech->userok) |
|
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
426 |
if ((*gssapi_client.mech->userok)(&gssapi_client, user)) { |
427 |
gssapi_client.used = 1; |
|
428 |
gssapi_client.store.owner = pw; |
|
4
by Colin Watson
* Add /usr/games to the default $PATH for non-privileged users. |
429 |
return 1; |
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
430 |
} else { |
4
by Colin Watson
* Add /usr/games to the default $PATH for non-privileged users. |
431 |
/* Destroy delegated credentials if userok fails */
|
432 |
gss_release_buffer(&lmin, &gssapi_client.displayname); |
|
433 |
gss_release_buffer(&lmin, &gssapi_client.exportedname); |
|
434 |
gss_release_cred(&lmin, &gssapi_client.creds); |
|
435 |
memset(&gssapi_client, 0, sizeof(ssh_gssapi_client)); |
|
436 |
return 0; |
|
437 |
}
|
|
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
438 |
else
|
439 |
debug("ssh_gssapi_userok: Unknown GSSAPI mechanism"); |
|
440 |
return (0); |
|
441 |
}
|
|
442 |
||
23.1.7
by Colin Watson
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out |
443 |
/* These bits are only used for rekeying. The unpriviledged child is running
|
444 |
* as the user, the monitor is root.
|
|
445 |
*
|
|
446 |
* In the child, we want to :
|
|
447 |
* *) Ask the monitor to store our credentials into the store we specify
|
|
448 |
* *) If it succeeds, maybe do a PAM update
|
|
449 |
*/
|
|
450 |
||
451 |
/* Stuff for PAM */
|
|
452 |
||
453 |
#ifdef USE_PAM
|
|
454 |
static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, |
|
455 |
struct pam_response **resp, void *data) |
|
456 |
{
|
|
457 |
return (PAM_CONV_ERR); |
|
458 |
}
|
|
459 |
#endif
|
|
460 |
||
461 |
void
|
|
462 |
ssh_gssapi_rekey_creds() { |
|
463 |
int ok; |
|
464 |
int ret; |
|
465 |
#ifdef USE_PAM
|
|
466 |
pam_handle_t *pamh = NULL; |
|
467 |
struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL}; |
|
468 |
char *envstr; |
|
469 |
#endif
|
|
470 |
||
471 |
if (gssapi_client.store.filename == NULL && |
|
472 |
gssapi_client.store.envval == NULL && |
|
473 |
gssapi_client.store.envvar == NULL) |
|
474 |
return; |
|
475 |
||
476 |
ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); |
|
477 |
||
478 |
if (!ok) |
|
479 |
return; |
|
480 |
||
481 |
debug("Rekeyed credentials stored successfully"); |
|
482 |
||
483 |
/* Actually managing to play with the ssh pam stack from here will
|
|
484 |
* be next to impossible. In any case, we may want different options
|
|
485 |
* for rekeying. So, use our own :)
|
|
486 |
*/
|
|
487 |
#ifdef USE_PAM
|
|
488 |
if (!use_privsep) { |
|
489 |
debug("Not even going to try and do PAM with privsep disabled"); |
|
490 |
return; |
|
491 |
}
|
|
492 |
||
493 |
ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, |
|
494 |
&pamconv, &pamh); |
|
495 |
if (ret) |
|
496 |
return; |
|
497 |
||
498 |
xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, |
|
499 |
gssapi_client.store.envval); |
|
500 |
||
501 |
ret = pam_putenv(pamh, envstr); |
|
502 |
if (!ret) |
|
503 |
pam_setcred(pamh, PAM_REINITIALIZE_CRED); |
|
504 |
pam_end(pamh, PAM_SUCCESS); |
|
505 |
#endif
|
|
506 |
}
|
|
507 |
||
508 |
int
|
|
509 |
ssh_gssapi_update_creds(ssh_gssapi_ccache *store) { |
|
510 |
int ok = 0; |
|
511 |
||
512 |
/* Check we've got credentials to store */
|
|
513 |
if (!gssapi_client.updated) |
|
514 |
return 0; |
|
515 |
||
516 |
gssapi_client.updated = 0; |
|
517 |
||
518 |
temporarily_use_uid(gssapi_client.store.owner); |
|
519 |
if (gssapi_client.mech && gssapi_client.mech->updatecreds) |
|
520 |
ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client); |
|
521 |
else
|
|
522 |
debug("No update function for this mechanism"); |
|
523 |
||
524 |
restore_uid(); |
|
525 |
||
526 |
return ok; |
|
527 |
}
|
|
528 |
||
1
by Noah Meyerhans
Import upstream version 3.8.1p1 |
529 |
#endif
|