X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/dfddba3d7e01aaef75b0f84b9f3c53f34e2504c9..826a9049465ce20a8a4ce06ed284048d07c699c8:/openssh/sshconnect2.c diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index 448648a..0485095 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $"); #include "openbsd-compat/sys-queue.h" @@ -58,6 +58,12 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.138 2004/06/13 12:53:24 djm Exp $"); extern char *client_version_string; extern char *server_version_string; extern Options options; +extern Kex *xxx_kex; + +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */ +/* if it is set then prevent the switch to the null cipher */ + +extern int tty_flag; /* * SSH2 key exchange @@ -83,9 +89,11 @@ void ssh_kex2(char *host, struct sockaddr *hostaddr) { Kex *kex; + #ifdef GSSAPI - char *orig, *gss; + char *orig = NULL, *gss = NULL; int len; + char *gss_host = NULL; #endif xxx_host = host; @@ -96,11 +104,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) /* Add the GSSAPI mechanisms currently supported on this client to * the key exchange algorithm proposal */ orig = myproposal[PROPOSAL_KEX_ALGS]; - gss = ssh_gssapi_client_mechanisms((char *)get_canonical_hostname(1)); + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); + else + gss_host = host; + + gss = ssh_gssapi_client_mechanisms(gss_host); if (gss) { - len = strlen(orig)+strlen(gss)+2; - myproposal[PROPOSAL_KEX_ALGS]=xmalloc(len); - snprintf(myproposal[PROPOSAL_KEX_ALGS],len,"%s,%s",gss,orig); + debug("Offering GSSAPI proposal: %s", gss); + len = strlen(orig) + strlen(gss) + 2; + myproposal[PROPOSAL_KEX_ALGS] = xmalloc(len); + snprintf(myproposal[PROPOSAL_KEX_ALGS], len, "%s,%s", gss, + orig); } } #endif @@ -119,10 +134,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); if (options.compression) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; } else { myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib"; } if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = @@ -133,13 +148,14 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) options.hostkeyalgorithms; #ifdef GSSAPI - /* If we've got GSSAPI algorithms, then we also support the - * 'null' hostkey, as a last resort */ + /* If we've got GSSAPI algorithms, then we also support the + * 'null' hostkey, as a last resort */ if (options.gss_keyex && gss) { - orig=myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; - len = strlen(orig)+sizeof(",null"); - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]=xmalloc(len); - snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],len,"%s,null",orig); + orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + len = strlen(orig) + sizeof(",null"); + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xmalloc(len); + snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], len, + "%s,null", orig); } #endif @@ -153,12 +169,16 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; #ifdef GSSAPI kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; + kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; #endif kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; + #ifdef GSSAPI - kex->options.gss_deleg_creds=options.gss_deleg_creds; + kex->gss_deleg_creds = options.gss_deleg_creds; + kex->gss_trust_dns = options.gss_trust_dns; + kex->gss_host = gss_host; #endif xxx_kex = kex; @@ -236,15 +256,6 @@ int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); int userauth_kerberos(Authctxt *); -#ifdef GSSAPI -int userauth_gssapi(Authctxt *authctxt); -void input_gssapi_response(int type, u_int32_t, void *); -void input_gssapi_token(int type, u_int32_t, void *); -void input_gssapi_hash(int type, u_int32_t, void *); -void input_gssapi_error(int, u_int32_t, void *); -void input_gssapi_errtok(int, u_int32_t, void *); -#endif - #ifdef GSSAPI int userauth_external(Authctxt *authctxt); int userauth_gssapi(Authctxt *authctxt); @@ -255,6 +266,7 @@ void input_gssapi_token(int type, u_int32_t, void *); void input_gssapi_hash(int type, u_int32_t, void *); void input_gssapi_error(int, u_int32_t, void *); void input_gssapi_errtok(int, u_int32_t, void *); +int userauth_gsskeyex(Authctxt *authctxt); #endif void userauth(Authctxt *, char *); @@ -270,6 +282,10 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI + {"gssapi-keyex", + userauth_gsskeyex, + &options.gss_authentication, + NULL}, {"external-keyx", userauth_external, &options.gss_authentication, @@ -364,7 +380,15 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, pubkey_cleanup(&authctxt); dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); - + if ((options.none_switch == 1) && !tty_flag) /* no null on tty sessions */ + { + debug("Requesting none rekeying..."); + myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; + myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; + kex_prop2buf(&xxx_kex->my,myproposal); + packet_request_rekeying(); + fprintf(stderr, "WARNING: ENABLED NULL CIPHER\n"); + } debug("Authentication succeeded (%s).", authctxt.method->name); } @@ -407,7 +431,7 @@ void input_userauth_error(int type, u_int32_t seq, void *ctxt) { fatal("input_userauth_error: bad message during authentication: " - "type %d", type); + "type %d", type); } void @@ -537,15 +561,21 @@ userauth_gssapi(Authctxt *authctxt) { Gssctxt *gssctxt = NULL; static gss_OID_set gss_supported = NULL; - static int mech = 0; + static u_int mech = 0; OM_uint32 min; int ok = 0; + char *gss_host = NULL; if (!options.gss_authentication) { verbose("GSSAPI authentication disabled."); return 0; } + if (options.gss_trust_dns) + gss_host = (char *)get_canonical_hostname(1); + else + gss_host = (char *)authctxt->host; + /* Try one GSSAPI method at a time, rather than sending them all at * once. */ @@ -562,16 +592,17 @@ userauth_gssapi(Authctxt *authctxt) /* My DER encoding requires length<128 */ if (gss_supported->elements[mech].length < 128 && ssh_gssapi_check_mechanism(&gss_supported->elements[mech], - get_canonical_hostname(1)) && + gss_host) && !GSS_ERROR(ssh_gssapi_import_name(gssctxt, - get_canonical_hostname(1)))) { + gss_host))) { ok = 1; /* Mechanism works */ } else { mech++; } } - if (!ok) return 0; + if (!ok) + return 0; authctxt->methoddata=(void *)gssctxt; @@ -606,7 +637,8 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) Authctxt *authctxt = ctxt; Gssctxt *gssctxt = authctxt->methoddata; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gssbuf, mic; + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; + gss_buffer_desc gssbuf; OM_uint32 status, ms, flags; Buffer b; @@ -659,8 +691,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; - int oidlen; - char *oidv; + unsigned int oidlen; + unsigned char *oidv; if (authctxt == NULL) fatal("input_gssapi_response: no authentication context"); @@ -741,7 +773,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) /* Stick it into GSSAPI and see what it says */ status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, - &recv_tok, &send_tok, NULL); + &recv_tok, &send_tok, NULL); xfree(recv_tok.value); gss_release_buffer(&ms, &send_tok); @@ -763,11 +795,20 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) packet_check_eom(); - debug("Server GSSAPI Error:\n%s\n", msg); + debug("Server GSSAPI Error:\n%s", msg); xfree(msg); xfree(lang); } +#ifdef GSI +extern +const gss_OID_desc * const gss_mech_globus_gssapi_openssl; +#define is_gsi_oid(oid) \ + (oid->length == gss_mech_globus_gssapi_openssl->length && \ + (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \ + oid->length) == 0)) +#endif + int userauth_external(Authctxt *authctxt) { @@ -779,7 +820,7 @@ userauth_external(Authctxt *authctxt) /* The client MUST NOT try this method if initial key exchange was not performed using a GSSAPI-based key exchange method. */ - if (xxx_kex->kex_type != KEX_GSS_GRP1_SHA1) { + if (gss_kex_context == NULL) { debug2("gsskex not performed, skipping external-keyx"); return 0; } @@ -787,11 +828,11 @@ userauth_external(Authctxt *authctxt) debug2("userauth_external"); packet_start(SSH2_MSG_USERAUTH_REQUEST); #ifdef GSI - if(options.implicit) { - packet_put_cstring(""); + if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { + packet_put_cstring(""); } else { #endif - packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->server_user); #ifdef GSI } #endif @@ -801,6 +842,63 @@ userauth_external(Authctxt *authctxt) packet_write_wait(); return 1; } +int +userauth_gsskeyex(Authctxt *authctxt) +{ + Buffer b; + gss_buffer_desc gssbuf; + gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; + OM_uint32 ms; + + static int attempt = 0; + if (attempt++ >= 1) + return (0); + + if (gss_kex_context == NULL) { + debug("No valid Key exchange context"); + return (0); + } + +#ifdef GSI + if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { + ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex"); + } else { +#endif + ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, + "gssapi-keyex"); +#ifdef GSI + } +#endif + + gssbuf.value = buffer_ptr(&b); + gssbuf.length = buffer_len(&b); + + if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { + buffer_free(&b); + return (0); + } + + packet_start(SSH2_MSG_USERAUTH_REQUEST); +#ifdef GSI + if (options.implicit && is_gsi_oid(gss_kex_context->oid)) { + packet_put_cstring(""); + } else { +#endif + packet_put_cstring(authctxt->server_user); +#ifdef GSI + } +#endif + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_string(mic.value, mic.length); + packet_send(); + + buffer_free(&b); + gss_release_buffer(&ms, &mic); + + return (1); +} + #endif /* GSSAPI */ int