summaryrefslogtreecommitdiff
path: root/gss-genr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gss-genr.c')
-rw-r--r--gss-genr.c116
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
78char * 78char *
79ssh_gssapi_client_mechanisms(const char *host) { 79ssh_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
89char * 90char *
90ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, 91ssh_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
377OM_uint32 384OM_uint32
385ssh_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
415OM_uint32
378ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) 416ssh_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
415int 453int
416ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) 454ssh_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
492int
493ssh_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 */