X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=gss-genr.c;h=69bf82da2707e2a971ef898ff4ed06b6c0c7af50;hb=7380abd26abc7d48a80ee671cd9b734184aab5e8;hp=f9b39cfd54f6f321d7640881b8d06f6a148f5e93;hpb=7c8d07158e13532fa7e5173ce9379c38bb413f74;p=openssh.git diff --git a/gss-genr.c b/gss-genr.c index f9b39cf..69bf82d 100644 --- a/gss-genr.c +++ b/gss-genr.c @@ -42,12 +42,16 @@ #include "cipher.h" #include "key.h" #include "kex.h" +#include "misc.h" +#include "ssh.h" +#include "readconf.h" #include #include "ssh-gss.h" extern u_char *session_id2; extern u_int session_id2_len; +extern Options options; typedef struct { char *encoded; @@ -63,6 +67,17 @@ Gssctxt *gss_kex_context = NULL; static ssh_gss_kex_mapping *gss_enc2oid = NULL; +static char *gss_password = NULL; + +static void +ssh_gssapi_cleanup_password(void) +{ + if (gss_password) { + memset(gss_password, 0, strlen(gss_password)); + xfree(gss_password); + } +} + int ssh_gssapi_oid_table_ok() { return (gss_enc2oid != NULL); @@ -78,9 +93,20 @@ ssh_gssapi_oid_table_ok() { char * ssh_gssapi_client_mechanisms(const char *host, const char *client) { gss_OID_set gss_supported; - OM_uint32 min_status; + OM_uint32 maj_status, min_status; + + if (options.gss_mechanism_oid) { + maj_status = gss_create_empty_oid_set(&min_status, + &gss_supported); + if (!GSS_ERROR(maj_status)) + maj_status = gss_add_oid_set_member(&min_status, + options.gss_mechanism_oid, + &gss_supported); + } else { + maj_status = gss_indicate_mechs(&min_status, &gss_supported); + } - if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported))) + if (GSS_ERROR(maj_status)) return NULL; return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism, @@ -398,18 +424,51 @@ ssh_gssapi_client_identity(Gssctxt *ctx, const char *name) ctx->major = gss_import_name(&ctx->minor, &gssbuf, GSS_C_NT_USER_NAME, &gssname); - if (!ctx->major) - ctx->major = gss_acquire_cred(&ctx->minor, - gssname, 0, oidset, GSS_C_INITIATE, - &ctx->client_creds, NULL, NULL); + if (GSS_ERROR(ctx->major)) { + ssh_gssapi_error(ctx); + return ctx->major; + } + + if (options.gss_password_prompt) { + char prompt[150]; + + if (!gss_password) { + snprintf(prompt, sizeof(prompt), "%.30s's password: ", name); + gss_password = read_passphrase(prompt, 0); + + atexit(ssh_gssapi_cleanup_password); + } + + gssbuf.value = gss_password; + gssbuf.length = strlen(gss_password); + + ctx->major = gss_acquire_cred_with_password(&ctx->minor, + gssname, + &gssbuf, + GSS_C_INDEFINITE, + oidset, + GSS_C_INITIATE, + &ctx->client_creds, + NULL, + NULL); + } else { + ctx->major = gss_acquire_cred(&ctx->minor, + gssname, + GSS_C_INDEFINITE, + oidset, + GSS_C_INITIATE, + &ctx->client_creds, + NULL, + NULL); + } gss_release_name(&status, &gssname); gss_release_oid_set(&status, &oidset); - if (ctx->major) + if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx); - return(ctx->major); + return ctx->major; } OM_uint32 @@ -462,8 +521,12 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, if (ctx == NULL) ctx = &intctx; - /* RFC 4462 says we MUST NOT do SPNEGO */ - if (oid->length == spnego_oid.length && + /* + * RFC 4462 says we MUST NOT do SPNEGO, but we relax that if + * the SPNEGO mechanism was explicitly specified by the user. + */ + if (options.gss_mechanism_oid == GSS_C_NO_OID && + oid->length == spnego_oid.length && (memcmp(oid->elements, spnego_oid.elements, oid->length) == 0)) return 0; /* false */ @@ -545,5 +608,4 @@ ssh_gssapi_credentials_updated(Gssctxt *ctxt) { return 0; } - #endif /* GSSAPI */