diff options
author | Colin Watson <cjwatson@debian.org> | 2010-01-01 17:15:23 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-01-01 17:15:23 +0000 |
commit | 99b402ea4c8457b0a3cafff37f5b3410a8dc6476 (patch) | |
tree | 1d24ce54c9981ea8cbb4c5a9309964a0e4c4b320 /gss-genr.c | |
parent | 87552344215a38d3a2b0d4d63dc151e05978bbe1 (diff) | |
parent | 54af7a4ae8d455791a631bdfaade4b64436ae16a (diff) |
import openssh-5.2p1-gsskex-all-20090726.patch
Diffstat (limited to 'gss-genr.c')
-rw-r--r-- | gss-genr.c | 116 |
1 files changed, 108 insertions, 8 deletions
diff --git a/gss-genr.c b/gss-genr.c index 822a08212..c51fa727d 100644 --- a/gss-genr.c +++ b/gss-genr.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */ | 1 | /* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. | 4 | * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. |
5 | * | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions |
@@ -76,19 +76,20 @@ ssh_gssapi_oid_table_ok() { | |||
76 | */ | 76 | */ |
77 | 77 | ||
78 | char * | 78 | char * |
79 | ssh_gssapi_client_mechanisms(const char *host) { | 79 | ssh_gssapi_client_mechanisms(const char *host, const char *client) { |
80 | gss_OID_set gss_supported; | 80 | gss_OID_set gss_supported; |
81 | OM_uint32 min_status; | 81 | OM_uint32 min_status; |
82 | 82 | ||
83 | gss_indicate_mechs(&min_status, &gss_supported); | 83 | if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) |
84 | return NULL; | ||
84 | 85 | ||
85 | return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, | 86 | return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, |
86 | host)); | 87 | host, client)); |
87 | } | 88 | } |
88 | 89 | ||
89 | char * | 90 | char * |
90 | ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, | 91 | ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, |
91 | const char *data) { | 92 | const char *host, const char *client) { |
92 | Buffer buf; | 93 | Buffer buf; |
93 | size_t i; | 94 | size_t i; |
94 | int oidpos, enclen; | 95 | int oidpos, enclen; |
@@ -112,7 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, | |||
112 | oidpos = 0; | 113 | oidpos = 0; |
113 | for (i = 0; i < gss_supported->count; i++) { | 114 | for (i = 0; i < gss_supported->count; i++) { |
114 | if (gss_supported->elements[i].length < 128 && | 115 | if (gss_supported->elements[i].length < 128 && |
115 | (*check)(NULL, &(gss_supported->elements[i]), data)) { | 116 | (*check)(NULL, &(gss_supported->elements[i]), host, client)) { |
116 | 117 | ||
117 | deroid[0] = SSH_GSS_OIDTYPE; | 118 | deroid[0] = SSH_GSS_OIDTYPE; |
118 | deroid[1] = gss_supported->elements[i].length; | 119 | deroid[1] = gss_supported->elements[i].length; |
@@ -171,12 +172,18 @@ ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) { | |||
171 | 172 | ||
172 | switch (kex_type) { | 173 | switch (kex_type) { |
173 | case KEX_GSS_GRP1_SHA1: | 174 | case KEX_GSS_GRP1_SHA1: |
175 | if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID)) | ||
176 | return GSS_C_NO_OID; | ||
174 | name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; | 177 | name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1; |
175 | break; | 178 | break; |
176 | case KEX_GSS_GRP14_SHA1: | 179 | case KEX_GSS_GRP14_SHA1: |
180 | if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID)) | ||
181 | return GSS_C_NO_OID; | ||
177 | name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; | 182 | name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1; |
178 | break; | 183 | break; |
179 | case KEX_GSS_GEX_SHA1: | 184 | case KEX_GSS_GEX_SHA1: |
185 | if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID)) | ||
186 | return GSS_C_NO_OID; | ||
180 | name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; | 187 | name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1; |
181 | break; | 188 | break; |
182 | default: | 189 | default: |
@@ -345,7 +352,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, | |||
345 | } | 352 | } |
346 | 353 | ||
347 | ctx->major = gss_init_sec_context(&ctx->minor, | 354 | ctx->major = gss_init_sec_context(&ctx->minor, |
348 | GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, | 355 | ctx->client_creds, &ctx->context, ctx->name, ctx->oid, |
349 | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, | 356 | GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, |
350 | 0, NULL, recv_tok, NULL, send_tok, flags, NULL); | 357 | 0, NULL, recv_tok, NULL, send_tok, flags, NULL); |
351 | 358 | ||
@@ -375,6 +382,37 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) | |||
375 | } | 382 | } |
376 | 383 | ||
377 | OM_uint32 | 384 | OM_uint32 |
385 | ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) | ||
386 | { | ||
387 | gss_buffer_desc gssbuf; | ||
388 | gss_name_t gssname; | ||
389 | OM_uint32 status; | ||
390 | gss_OID_set oidset; | ||
391 | |||
392 | gssbuf.value = (void *) name; | ||
393 | gssbuf.length = strlen(gssbuf.value); | ||
394 | |||
395 | gss_create_empty_oid_set(&status, &oidset); | ||
396 | gss_add_oid_set_member(&status, ctx->oid, &oidset); | ||
397 | |||
398 | ctx->major = gss_import_name(&ctx->minor, &gssbuf, | ||
399 | GSS_C_NT_USER_NAME, &gssname); | ||
400 | |||
401 | if (!ctx->major) | ||
402 | ctx->major = gss_acquire_cred(&ctx->minor, | ||
403 | gssname, 0, oidset, GSS_C_INITIATE, | ||
404 | &ctx->client_creds, NULL, NULL); | ||
405 | |||
406 | gss_release_name(&status, &gssname); | ||
407 | gss_release_oid_set(&status, &oidset); | ||
408 | |||
409 | if (ctx->major) | ||
410 | ssh_gssapi_error(ctx); | ||
411 | |||
412 | return(ctx->major); | ||
413 | } | ||
414 | |||
415 | OM_uint32 | ||
378 | ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) | 416 | ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) |
379 | { | 417 | { |
380 | if (ctx == NULL) | 418 | if (ctx == NULL) |
@@ -413,7 +451,8 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, | |||
413 | } | 451 | } |
414 | 452 | ||
415 | int | 453 | int |
416 | ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | 454 | ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, |
455 | const char *client) | ||
417 | { | 456 | { |
418 | gss_buffer_desc token = GSS_C_EMPTY_BUFFER; | 457 | gss_buffer_desc token = GSS_C_EMPTY_BUFFER; |
419 | OM_uint32 major, minor; | 458 | OM_uint32 major, minor; |
@@ -431,6 +470,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | |||
431 | ssh_gssapi_build_ctx(ctx); | 470 | ssh_gssapi_build_ctx(ctx); |
432 | ssh_gssapi_set_oid(*ctx, oid); | 471 | ssh_gssapi_set_oid(*ctx, oid); |
433 | major = ssh_gssapi_import_name(*ctx, host); | 472 | major = ssh_gssapi_import_name(*ctx, host); |
473 | |||
474 | if (!GSS_ERROR(major) && client) | ||
475 | major = ssh_gssapi_client_identity(*ctx, client); | ||
476 | |||
434 | if (!GSS_ERROR(major)) { | 477 | if (!GSS_ERROR(major)) { |
435 | major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, | 478 | major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, |
436 | NULL); | 479 | NULL); |
@@ -446,4 +489,61 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) | |||
446 | return (!GSS_ERROR(major)); | 489 | return (!GSS_ERROR(major)); |
447 | } | 490 | } |
448 | 491 | ||
492 | int | ||
493 | ssh_gssapi_credentials_updated(Gssctxt *ctxt) { | ||
494 | static gss_name_t saved_name = GSS_C_NO_NAME; | ||
495 | static OM_uint32 saved_lifetime = 0; | ||
496 | static gss_OID saved_mech = GSS_C_NO_OID; | ||
497 | static gss_name_t name; | ||
498 | static OM_uint32 last_call = 0; | ||
499 | OM_uint32 lifetime, now, major, minor; | ||
500 | int equal; | ||
501 | gss_cred_usage_t usage = GSS_C_INITIATE; | ||
502 | |||
503 | now = time(NULL); | ||
504 | |||
505 | if (ctxt) { | ||
506 | debug("Rekey has happened - updating saved versions"); | ||
507 | |||
508 | if (saved_name != GSS_C_NO_NAME) | ||
509 | gss_release_name(&minor, &saved_name); | ||
510 | |||
511 | major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, | ||
512 | &saved_name, &saved_lifetime, NULL, NULL); | ||
513 | |||
514 | if (!GSS_ERROR(major)) { | ||
515 | saved_mech = ctxt->oid; | ||
516 | saved_lifetime+= now; | ||
517 | } else { | ||
518 | /* Handle the error */ | ||
519 | } | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | if (now - last_call < 10) | ||
524 | return 0; | ||
525 | |||
526 | last_call = now; | ||
527 | |||
528 | if (saved_mech == GSS_C_NO_OID) | ||
529 | return 0; | ||
530 | |||
531 | major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, | ||
532 | &name, &lifetime, NULL, NULL); | ||
533 | if (major == GSS_S_CREDENTIALS_EXPIRED) | ||
534 | return 0; | ||
535 | else if (GSS_ERROR(major)) | ||
536 | return 0; | ||
537 | |||
538 | major = gss_compare_name(&minor, saved_name, name, &equal); | ||
539 | gss_release_name(&minor, &name); | ||
540 | if (GSS_ERROR(major)) | ||
541 | return 0; | ||
542 | |||
543 | if (equal && (saved_lifetime < lifetime + now - 10)) | ||
544 | return 1; | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
449 | #endif /* GSSAPI */ | 549 | #endif /* GSSAPI */ |