diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ssh/include/ssh-gss.h | 63 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/kexgssc.c | 250 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/kexgsss.c | 100 | ||||
-rw-r--r-- | usr/src/cmd/ssh/libssh/common/ssh-gss.c | 289 | ||||
-rw-r--r-- | usr/src/cmd/ssh/ssh/gss-clnt.c | 52 | ||||
-rw-r--r-- | usr/src/cmd/ssh/sshd/auth2-gss.c | 314 | ||||
-rw-r--r-- | usr/src/cmd/ssh/sshd/gss-serv.c | 116 |
7 files changed, 596 insertions, 588 deletions
diff --git a/usr/src/cmd/ssh/include/ssh-gss.h b/usr/src/cmd/ssh/include/ssh-gss.h index d3af3da78d..6e35d9ed61 100644 --- a/usr/src/cmd/ssh/include/ssh-gss.h +++ b/usr/src/cmd/ssh/include/ssh-gss.h @@ -22,12 +22,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SSH_GSS_H -#define _SSH_GSS_H +#define _SSH_GSS_H #pragma ident "%Z%%M% %I% %E% SMI" @@ -46,27 +46,27 @@ /* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */ #ifndef GSS_C_NT_HOSTBASED_SERVICE -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name #endif /* GSS_C_NT_... */ #endif /* !HEIMDAL */ #endif /* GSS_KRB5 */ #endif /* SUNW_GSSAPI */ /* draft-ietf-secsh-gsskeyex-03 */ -#define SSH2_MSG_KEXGSS_INIT 30 -#define SSH2_MSG_KEXGSS_CONTINUE 31 -#define SSH2_MSG_KEXGSS_COMPLETE 32 -#define SSH2_MSG_KEXGSS_HOSTKEY 33 -#define SSH2_MSG_KEXGSS_ERROR 34 -#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 -#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 -#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 -#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 -#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 -#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 - -#define KEX_GSS_SHA1 "gss-group1-sha1-" -#define SSH_GSS_HOSTBASED_SERVICE "host" +#define SSH2_MSG_KEXGSS_INIT 30 +#define SSH2_MSG_KEXGSS_CONTINUE 31 +#define SSH2_MSG_KEXGSS_COMPLETE 32 +#define SSH2_MSG_KEXGSS_HOSTKEY 33 +#define SSH2_MSG_KEXGSS_ERROR 34 +#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 +#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 +#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 +#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 +#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 +#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66 + +#define KEX_GSS_SHA1 "gss-group1-sha1-" +#define SSH_GSS_HOSTBASED_SERVICE "host" #ifndef HAVE_GSS_STORE_CRED typedef struct ssh_gssapi_cred_store ssh_gssapi_cred_store; /* server-only */ @@ -104,8 +104,9 @@ void ssh_gssapi_client_kex_hook(Kex *kex, char **proposal); /* Map an encoded mechanism keyex name to a mechanism OID */ void ssh_gssapi_mech_oid_to_kexname(const gss_OID mech, char **kexname); void ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, - char **kexname_list); -void ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech); /* dup oid? */ + char **kexname_list); +/* dup oid? */ +void ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech); /* * Unfortunately, the GSS-API is not generic enough for some things -- @@ -117,15 +118,14 @@ int ssh_gssapi_is_gsi(gss_OID oid); int ssh_gssapi_is_dh(gss_OID oid); /* GSS_Init/Accept_sec_context() and GSS_Acquire_cred() wrappers */ -OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, - const char *server_host, - int deleg_creds, - gss_buffer_t recv_tok, - gss_buffer_t send_tok); /* client-only */ -OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, - gss_buffer_t recv_tok, - gss_buffer_t send_tok); /* server-only */ -OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx); /* server-only */ +/* client-only */ +OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, + int deleg_creds, gss_buffer_t recv_tok, gss_buffer_t send_tok); +/* server-only */ +OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, + gss_buffer_t send_tok); +/* server-only */ +OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx); /* MIC wrappers */ OM_uint32 ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_t buffer, @@ -149,7 +149,7 @@ struct Authctxt; /* needed to avoid conflicts between auth.h, sshconnect2.c */ void ssh_gssapi_storecreds(Gssctxt *ctx, struct Authctxt *authctxt); /* ... else, if other interfaces are available for GSS-API cred storing */ -void ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, u_int *envsizep); +void ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, uint_t *envsizep); void ssh_gssapi_cleanup_creds(Gssctxt *ctx); /* Misc */ @@ -158,9 +158,8 @@ const char *ssh_gssapi_oid_to_name(gss_OID oid); char *ssh_gssapi_oid_to_str(gss_OID oid); gss_OID ssh_gssapi_dup_oid(gss_OID oid); gss_OID ssh_gssapi_make_oid(size_t length, void *elements); -gss_OID ssh_gssapi_make_oid_ext(size_t length, - void *elements, - int der_wrapped); +gss_OID ssh_gssapi_make_oid_ext(size_t length, void *elements, + int der_wrapped); void *ssh_gssapi_der_wrap(size_t, size_t *length); size_t ssh_gssapi_der_wrap_size(size_t, size_t *length); void ssh_gssapi_release_oid(gss_OID *oid); diff --git a/usr/src/cmd/ssh/libssh/common/kexgssc.c b/usr/src/cmd/ssh/libssh/common/kexgssc.c index 815044733d..60c91ed57b 100644 --- a/usr/src/cmd/ssh/libssh/common/kexgssc.c +++ b/usr/src/cmd/ssh/libssh/common/kexgssc.c @@ -22,11 +22,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +#pragma ident "%Z%%M% %I% %E% SMI" #include "includes.h" @@ -56,15 +56,15 @@ static void kexgss_verbose_cleanup(void *arg); void kexgss_client(Kex *kex) { - gss_buffer_desc gssbuf,send_tok,recv_tok, msg_tok; + gss_buffer_desc gssbuf, send_tok, recv_tok, msg_tok; gss_buffer_t token_ptr; gss_OID mech = GSS_C_NULL_OID; Gssctxt *ctxt = NULL; OM_uint32 maj_status, min_status, smaj_status, smin_status; unsigned int klen, kout; - DH *dh; + DH *dh; BIGNUM *dh_server_pub = 0; - BIGNUM *shared_secret = 0; + BIGNUM *shared_secret = 0; Key *server_host_key = NULL; unsigned char *kbuf; unsigned char *hash; @@ -72,10 +72,10 @@ kexgss_client(Kex *kex) char *msg, *lang; int type = 0; int first = 1; - u_int sbloblen = 0; - u_int strlen; - - /* Map the negotiated kex name to a mech OID*/ + uint_t sbloblen = 0; + uint_t strlen; + + /* Map the negotiated kex name to a mech OID */ ssh_gssapi_oid_of_kexname(kex->name, &mech); if (mech == GSS_C_NULL_OID) fatal("Couldn't match the negotiated GSS key exchange"); @@ -83,37 +83,34 @@ kexgss_client(Kex *kex) ssh_gssapi_build_ctx(&ctxt, 1, mech); /* This code should match that in ssh_dh1_client */ - + /* Step 1 - e is dh->pub_key */ dh = dh_new_group1(); dh_gen_key(dh, kex->we_need * 8); /* This is f, we initialise it now to make life easier */ - dh_server_pub = BN_new(); - if (dh_server_pub == NULL) { - fatal("dh_server_pub == NULL"); - } - + dh_server_pub = BN_new(); + if (dh_server_pub == NULL) { + fatal("dh_server_pub == NULL"); + } + token_ptr = GSS_C_NO_BUFFER; - - recv_tok.value=NULL; - recv_tok.length=0; + + recv_tok.value = NULL; + recv_tok.length = 0; do { debug("Calling gss_init_sec_context"); - - maj_status=ssh_gssapi_init_ctx(ctxt, - xxx_host, - kex->options.gss_deleg_creds, - token_ptr, - &send_tok); + + maj_status = ssh_gssapi_init_ctx(ctxt, xxx_host, + kex->options.gss_deleg_creds, token_ptr, &send_tok); if (GSS_ERROR(maj_status)) { ssh_gssapi_error(ctxt, "performing GSS-API protected " - "SSHv2 key exchange"); + "SSHv2 key exchange"); (void) gss_release_buffer(&min_status, &send_tok); packet_disconnect("A GSS-API error occurred during " - "GSS-API protected SSHv2 key exchange\n"); + "GSS-API protected SSHv2 key exchange\n"); } /* If we've got an old receive buffer get rid of it */ @@ -124,7 +121,7 @@ kexgss_client(Kex *kex) recv_tok.length = 0; token_ptr = GSS_C_NO_BUFFER; } - + if (maj_status == GSS_S_COMPLETE) { /* If mutual state flag is not true, kex fails */ if (!(ctxt->flags & GSS_C_MUTUAL_FLAG)) { @@ -135,29 +132,33 @@ kexgss_client(Kex *kex) fatal("Integrity check failed"); } } - - /* If we have data to send, then the last message that we - * received cannot have been a 'complete'. */ - if (send_tok.length !=0) { + + /* + * If we have data to send, then the last message that we + * received cannot have been a 'complete'. + */ + if (send_tok.length != 0) { if (first) { packet_start(SSH2_MSG_KEXGSS_INIT); packet_put_string(send_tok.value, - send_tok.length); + send_tok.length); packet_put_bignum2(dh->pub_key); - first=0; + first = 0; } else { packet_start(SSH2_MSG_KEXGSS_CONTINUE); packet_put_string(send_tok.value, - send_tok.length); + send_tok.length); } (void) gss_release_buffer(&min_status, &send_tok); packet_send(); packet_write_wait(); - - /* If we've sent them data, they'd better be polite - * and reply. */ - + + /* + * If we've sent them data, they'd better be polite and + * reply. + */ + next_packet: /* * We need to catch connection closing w/o error @@ -175,141 +176,138 @@ next_packet: case SSH2_MSG_KEXGSS_HOSTKEY: debug("Received KEXGSS_HOSTKEY"); server_host_key_blob = - packet_get_string(&sbloblen); + packet_get_string(&sbloblen); server_host_key = - key_from_blob(server_host_key_blob, - sbloblen); + key_from_blob(server_host_key_blob, + sbloblen); goto next_packet; /* there MUSt be another */ break; case SSH2_MSG_KEXGSS_CONTINUE: debug("Received GSSAPI_CONTINUE"); - if (maj_status == GSS_S_COMPLETE) + if (maj_status == GSS_S_COMPLETE) packet_disconnect("Protocol error: " - "received GSS-API context token" - " though the context was already" - " established"); - recv_tok.value=packet_get_string(&strlen); - recv_tok.length=strlen; /* u_int vs. size_t */ + "received GSS-API context token " + "though the context was already " + "established"); + recv_tok.value = packet_get_string(&strlen); + recv_tok.length = strlen; /* u_int vs. size_t */ break; case SSH2_MSG_KEXGSS_COMPLETE: debug("Received GSSAPI_COMPLETE"); - packet_get_bignum2(dh_server_pub); - msg_tok.value=packet_get_string(&strlen); - msg_tok.length=strlen; /* u_int vs. size_t */ + packet_get_bignum2(dh_server_pub); + msg_tok.value = packet_get_string(&strlen); + msg_tok.length = strlen; /* u_int vs. size_t */ /* Is there a token included? */ if (packet_get_char()) { - recv_tok.value= + recv_tok.value = packet_get_string(&strlen); - recv_tok.length=strlen; /*u_int/size_t*/ + /* u_int/size_t */ + recv_tok.length = strlen; } if (recv_tok.length > 0 && maj_status == GSS_S_COMPLETE) { packet_disconnect("Protocol error: " - "received GSS-API context token" - " though the context was already" - " established"); + "received GSS-API context token " + "though the context was already " + "established"); } else if (recv_tok.length == 0 && - maj_status == GSS_S_CONTINUE_NEEDED) { - /* No token included */ + maj_status == GSS_S_CONTINUE_NEEDED) { + /* No token included */ packet_disconnect("Protocol error: " - "did not receive expected " - "GSS-API context token"); + "did not receive expected " + "GSS-API context token"); } break; case SSH2_MSG_KEXGSS_ERROR: - smaj_status=packet_get_int(); - smin_status=packet_get_int(); + smaj_status = packet_get_int(); + smin_status = packet_get_int(); msg = packet_get_string(NULL); lang = packet_get_string(NULL); xfree(lang); error("Server had a GSS-API error; the " - "connection will close (%d/%d):\n%s", - smaj_status, smin_status, msg); + "connection will close (%d/%d):\n%s", + smaj_status, smin_status, msg); error("Use the GssKeyEx option to disable " - "GSS-API key exchange and try again."); + "GSS-API key exchange and try again."); packet_disconnect("The server had a GSS-API " - "error during GSS-API protected SSHv2 " - "key exchange\n"); + "error during GSS-API protected SSHv2 " + "key exchange\n"); break; default: packet_disconnect("Protocol error: " - "didn't expect packet type %d", type); + "didn't expect packet type %d", type); } if (recv_tok.value) - token_ptr=&recv_tok; + token_ptr = &recv_tok; } else { /* No data, and not complete */ if (maj_status != GSS_S_COMPLETE) { fatal("Not complete, and no token output"); } } - } while (maj_status == GSS_S_CONTINUE_NEEDED); - - /* We _must_ have received a COMPLETE message in reply from the - * server, which will have set dh_server_pub and msg_tok */ - - if (type != SSH2_MSG_KEXGSS_COMPLETE) - fatal("Expected SSH2_MSG_KEXGSS_COMPLETE never arrived"); - if (maj_status != GSS_S_COMPLETE) - fatal("Internal error in GSS-API protected SSHv2 key exchange"); - + } while (maj_status == GSS_S_CONTINUE_NEEDED); + + /* + * We _must_ have received a COMPLETE message in reply from the + * server, which will have set dh_server_pub and msg_tok. + */ + if (type != SSH2_MSG_KEXGSS_COMPLETE) + fatal("Expected SSH2_MSG_KEXGSS_COMPLETE never arrived"); + if (maj_status != GSS_S_COMPLETE) + fatal("Internal error in GSS-API protected SSHv2 key exchange"); + /* Check f in range [1, p-1] */ - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - /* compute K=f^x mod p */ - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); - - shared_secret = BN_new(); - BN_bin2bn(kbuf,kout, shared_secret); - (void) memset(kbuf, 0, klen); - xfree(kbuf); - - /* The GSS hash is identical to the DH one */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, /* server host key */ - dh->pub_key, /* e */ - dh_server_pub, /* f */ - shared_secret /* K */ - ); - - gssbuf.value=hash; - gssbuf.length=20; - - /* Verify that H matches the token we just got. */ - if ((maj_status = gss_verify_mic(&min_status, - ctxt->context, - &gssbuf, - &msg_tok, - NULL))) { + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + /* compute K=f^x mod p */ + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); + + shared_secret = BN_new(); + BN_bin2bn(kbuf, kout, shared_secret); + (void) memset(kbuf, 0, klen); + xfree(kbuf); + /* The GSS hash is identical to the DH one */ + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, /* server host key */ + dh->pub_key, /* e */ + dh_server_pub, /* f */ + shared_secret); /* K */ + + gssbuf.value = hash; + gssbuf.length = 20; + + /* Verify that H matches the token we just got. */ + if ((maj_status = gss_verify_mic(&min_status, ctxt->context, &gssbuf, + &msg_tok, NULL))) { packet_disconnect("Hash's MIC didn't verify"); - } + } if (server_host_key && kex->accept_host_key != NULL) (void) kex->accept_host_key(server_host_key); - - DH_free(dh); + + DH_free(dh); xxx_gssctxt = ctxt; /* for gss keyex w/ mic userauth */ - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - (void) memcpy(kex->session_id, hash, kex->session_id_len); - } - + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + (void) memcpy(kex->session_id, hash, kex->session_id_len); + } + kex_derive_keys(kex, hash, shared_secret); BN_clear_free(shared_secret); - kex_finish(kex); + kex_finish(kex); } /* ARGSUSED */ @@ -318,10 +316,10 @@ void kexgss_verbose_cleanup(void *arg) { error("The GSS-API protected key exchange has failed without " - "indication\nfrom the server, possibly due to misconfiguration " - "of the server."); + "indication\nfrom the server, possibly due to misconfiguration " + "of the server."); error("Use the GssKeyEx option to disable GSS-API key exchange " - "and try again."); + "and try again."); } #endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/libssh/common/kexgsss.c b/usr/src/cmd/ssh/libssh/common/kexgsss.c index 61f3fb70f1..9ee8b630bb 100644 --- a/usr/src/cmd/ssh/libssh/common/kexgsss.c +++ b/usr/src/cmd/ssh/libssh/common/kexgsss.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,16 +58,16 @@ kexgss_server(Kex *kex) OM_uint32 maj_status, min_status; gss_buffer_desc gssbuf, send_tok, recv_tok, msg_tok; Gssctxt *ctxt = NULL; - unsigned int klen, kout; - unsigned int sbloblen = 0; - unsigned char *kbuf, *hash; + unsigned int klen, kout; + unsigned int sbloblen = 0; + unsigned char *kbuf, *hash; unsigned char *server_host_key_blob = NULL; - DH *dh; + DH *dh; Key *server_host_key = NULL; - BIGNUM *shared_secret = NULL; - BIGNUM *dh_client_pub = NULL; - int type =0; - u_int slen; + BIGNUM *shared_secret = NULL; + BIGNUM *dh_client_pub = NULL; + int type = 0; + uint_t slen; gss_OID oid; /* @@ -96,37 +96,39 @@ kexgss_server(Kex *kex) do { debug("Wait SSH2_MSG_GSSAPI_INIT"); type = packet_read(); - switch(type) { + switch (type) { case SSH2_MSG_KEXGSS_INIT: - if (dh_client_pub!=NULL) - fatal("Received KEXGSS_INIT after initialising"); - recv_tok.value=packet_get_string(&slen); - recv_tok.length=slen; /* int vs. size_t */ + if (dh_client_pub != NULL) + fatal("Received KEXGSS_INIT after " + "initialising"); + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; /* int vs. size_t */ - dh_client_pub = BN_new(); + dh_client_pub = BN_new(); - if (dh_client_pub == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); + if (dh_client_pub == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); - /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ + /* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */ if (sbloblen) { packet_start(SSH2_MSG_KEXGSS_HOSTKEY); - packet_put_string(server_host_key_blob, sbloblen); + packet_put_string(server_host_key_blob, + sbloblen); packet_send(); packet_write_wait(); } break; case SSH2_MSG_KEXGSS_CONTINUE: - recv_tok.value=packet_get_string(&slen); - recv_tok.length=slen; /* int vs. size_t */ + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; /* int vs. size_t */ break; default: - packet_disconnect("Protocol error: didn't expect packet type %d", - type); + packet_disconnect("Protocol error: didn't expect " + "packet type %d", type); } - maj_status = ssh_gssapi_accept_ctx(ctxt,&recv_tok, &send_tok); + maj_status = ssh_gssapi_accept_ctx(ctxt, &recv_tok, &send_tok); xfree(recv_tok.value); /* We allocated this, not gss */ @@ -136,7 +138,7 @@ kexgss_server(Kex *kex) if (maj_status == GSS_S_CONTINUE_NEEDED) { debug("Sending GSSAPI_CONTINUE"); packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value,send_tok.length); + packet_put_string(send_tok.value, send_tok.length); packet_send(); packet_write_wait(); (void) gss_release_buffer(&min_status, &send_tok); @@ -145,9 +147,9 @@ kexgss_server(Kex *kex) if (GSS_ERROR(maj_status)) { kex_gss_send_error(ctxt); - if (send_tok.length>0) { + if (send_tok.length > 0) { packet_start(SSH2_MSG_KEXGSS_CONTINUE); - packet_put_string(send_tok.value,send_tok.length); + packet_put_string(send_tok.value, send_tok.length); packet_send(); packet_write_wait(); (void) gss_release_buffer(&min_status, &send_tok); @@ -165,12 +167,12 @@ kexgss_server(Kex *kex) dh = dh_new_group1(); dh_gen_key(dh, kex->we_need * 8); - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); shared_secret = BN_new(); BN_bin2bn(kbuf, kout, shared_secret); @@ -178,16 +180,16 @@ kexgss_server(Kex *kex) xfree(kbuf); /* The GSSAPI hash is identical to the Diffie Helman one */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, - dh->pub_key, - shared_secret - ); + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret); + BN_free(dh_client_pub); if (kex->session_id == NULL) { @@ -202,24 +204,24 @@ kexgss_server(Kex *kex) gssbuf.length = 20; /* yes, it's always 20 (SHA-1) */ gssbuf.value = hash; /* and it's static constant storage */ - if (GSS_ERROR(ssh_gssapi_get_mic(ctxt,&gssbuf,&msg_tok))) { + if (GSS_ERROR(ssh_gssapi_get_mic(ctxt, &gssbuf, &msg_tok))) { kex_gss_send_error(ctxt); fatal("Couldn't get MIC"); } packet_start(SSH2_MSG_KEXGSS_COMPLETE); packet_put_bignum2(dh->pub_key); - packet_put_string((char *)msg_tok.value,msg_tok.length); + packet_put_string((char *)msg_tok.value, msg_tok.length); (void) gss_release_buffer(&min_status, &msg_tok); if (send_tok.length != 0) { packet_put_char(1); /* true */ - packet_put_string((char *)send_tok.value,send_tok.length); + packet_put_string((char *)send_tok.value, send_tok.length); (void) gss_release_buffer(&min_status, &send_tok); } else { packet_put_char(0); /* false */ } - packet_send(); + packet_send(); packet_write_wait(); DH_free(dh); @@ -232,9 +234,9 @@ kexgss_server(Kex *kex) static void kex_gss_send_error(Gssctxt *ctxt) { char *errstr; - OM_uint32 maj,min; + OM_uint32 maj, min; - errstr = ssh_gssapi_last_error(ctxt,&maj,&min); + errstr = ssh_gssapi_last_error(ctxt, &maj, &min); if (errstr) { packet_start(SSH2_MSG_KEXGSS_ERROR); packet_put_int(maj); diff --git a/usr/src/cmd/ssh/libssh/common/ssh-gss.c b/usr/src/cmd/ssh/libssh/common/ssh-gss.c index fcf8e11b51..c784426e90 100644 --- a/usr/src/cmd/ssh/libssh/common/ssh-gss.c +++ b/usr/src/cmd/ssh/libssh/common/ssh-gss.c @@ -21,7 +21,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -62,7 +62,7 @@ static ssh_gss_kex_mapping **gss_enc2oid = NULL; static void ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name); static char *ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, - const char *old_kexalgs); + const char *old_kexalgs); /* * Populate gss_enc2oid table and return list of kexnames. @@ -83,7 +83,7 @@ ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) if (mechs != GSS_C_NULL_OID_SET || kexname_list == NULL) { /* Cleanup gss_enc2oid table */ - for (p = gss_enc2oid ; p != NULL && *p != NULL ; p++) { + for (p = gss_enc2oid; p != NULL && *p != NULL; p++) { if ((*p)->encoded) xfree((*p)->encoded); ssh_gssapi_release_oid(&(*p)->oid); @@ -99,24 +99,24 @@ ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) if (mechs) { gss_OID mech; /* Populate gss_enc2oid table */ - new_gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping *) * - (mechs->count + 1)); + new_gss_enc2oid = xmalloc(sizeof (ssh_gss_kex_mapping *) * + (mechs->count + 1)); memset(new_gss_enc2oid, 0, - sizeof(ssh_gss_kex_mapping *) * (mechs->count + 1)); + sizeof (ssh_gss_kex_mapping *) * (mechs->count + 1)); - for (i = 0 ; i < mechs->count ; i++) { + for (i = 0; i < mechs->count; i++) { mech = &mechs->elements[i]; ssh_gssapi_encode_oid_for_kex((const gss_OID)mech, - &enc_name); + &enc_name); if (!enc_name) continue; new_gss_enc2oid[i] = - xmalloc(sizeof(ssh_gss_kex_mapping)); + xmalloc(sizeof (ssh_gss_kex_mapping)); (new_gss_enc2oid[i])->encoded = enc_name; (new_gss_enc2oid[i])->oid = - ssh_gssapi_dup_oid(&mechs->elements[i]); + ssh_gssapi_dup_oid(&mechs->elements[i]); } /* Do this last to avoid run-ins with fatal_cleanups */ @@ -128,8 +128,8 @@ ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) /* Make kex name list */ buffer_init(&buf); - for (p = gss_enc2oid ; p && *p ; p++) { - buffer_put_char(&buf,','); + for (p = gss_enc2oid; p && *p; p++) { + buffer_put_char(&buf, ','); buffer_append(&buf, (*p)->encoded, strlen((*p)->encoded)); } @@ -139,7 +139,7 @@ ssh_gssapi_mech_oids_to_kexnames(const gss_OID_set mechs, char **kexname_list) } buffer_consume(&buf, 1); /* consume leading ',' */ - buffer_put_char(&buf,'\0'); + buffer_put_char(&buf, '\0'); *kexname_list = xstrdup(buffer_ptr(&buf)); buffer_free(&buf); @@ -155,10 +155,10 @@ ssh_gssapi_mech_oid_to_kexname(const gss_OID mech, char **kexname) *kexname = NULL; /* default to not found */ if (gss_enc2oid) { - for (p = gss_enc2oid ; p && *p ; p++) { + for (p = gss_enc2oid; p && *p; p++) { if (mech->length == (*p)->oid->length && memcmp(mech->elements, (*p)->oid->elements, - mech->length) == 0) + mech->length) == 0) *kexname = xstrdup((*p)->encoded); } } @@ -182,7 +182,7 @@ ssh_gssapi_oid_of_kexname(const char *kexname, gss_OID *mech) if (!gss_enc2oid) return; - for (p = gss_enc2oid ; p && *p ; p++) { + for (p = gss_enc2oid; p && *p; p++) { if (strcmp(kexname, (*p)->encoded) == 0) { *mech = (*p)->oid; return; @@ -194,13 +194,13 @@ static void ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name) { - Buffer buf; - OM_uint32 oidlen; - u_int enclen; - const EVP_MD *evp_md = EVP_md5(); - EVP_MD_CTX md; - u_char digest[EVP_MAX_MD_SIZE]; - char *encoded; + Buffer buf; + OM_uint32 oidlen; + uint_t enclen; + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; + uchar_t digest[EVP_MAX_MD_SIZE]; + char *encoded; if (oid == GSS_C_NULL_OID || !enc_name) return; @@ -237,22 +237,21 @@ ssh_gssapi_encode_oid_for_kex(const gss_OID oid, char **enc_name) buffer_free(&buf); /* Base 64 encoding */ - encoded=xmalloc(EVP_MD_size(evp_md)*2); - enclen=__b64_ntop(digest, EVP_MD_size(evp_md), - encoded,EVP_MD_size(evp_md)*2); + encoded = xmalloc(EVP_MD_size(evp_md)*2); + enclen = __b64_ntop(digest, EVP_MD_size(evp_md), + encoded, EVP_MD_size(evp_md) * 2); buffer_init(&buf); - buffer_append(&buf, KEX_GSS_SHA1, sizeof(KEX_GSS_SHA1)-1); + buffer_append(&buf, KEX_GSS_SHA1, sizeof (KEX_GSS_SHA1) - 1); buffer_append(&buf, encoded, enclen); buffer_put_char(&buf, '\0'); - - debug2("GSS-API Mechanism encoded as %s",encoded); + + debug2("GSS-API Mechanism encoded as %s", encoded); *enc_name = xstrdup(buffer_ptr(&buf)); buffer_free(&buf); } -static -char * +static char * ssh_gssapi_make_kexalgs_list(gss_OID_set mechs, const char *old_kexalgs) { char *gss_kexalgs, *new_kexalgs; @@ -303,10 +302,9 @@ ssh_gssapi_modify_kex(Kex *kex, gss_OID_set mechs, char **proposal) if (kex->mechs->count == mechs->count) { int present, matches = 0; - for ( i = 0 ; i < mechs->count ; i++ ) { + for (i = 0; i < mechs->count; i++) { maj = gss_test_oid_set_member(&min, - &kex->mechs->elements[i], mechs, - &present); + &kex->mechs->elements[i], mechs, &present); if (GSS_ERROR(maj)) { mechs = GSS_C_NULL_OID_SET; @@ -329,7 +327,7 @@ mod_offer: */ p = kexalgs = orig_kexalgs = proposal[PROPOSAL_KEX_ALGS]; while (p != NULL && *p != '\0' && - strncmp(p, KEX_GSS_SHA1, strlen(KEX_GSS_SHA1)) == 0) { + strncmp(p, KEX_GSS_SHA1, strlen(KEX_GSS_SHA1)) == 0) { if ((p = strchr(p, ',')) == NULL) break; @@ -350,9 +348,9 @@ mod_offer: maj = gss_create_empty_oid_set(&min, &dup_mechs); if (GSS_ERROR(maj)) return; - for ( i = 0 ; i < mechs->count ; i++ ) { + for (i = 0; i < mechs->count; i++) { maj = gss_add_oid_set_member(&min, &mechs->elements[i], - &dup_mechs); + &dup_mechs); if (GSS_ERROR(maj)) { (void) gss_release_oid_set(&min, &dup_mechs); @@ -361,7 +359,8 @@ mod_offer: } /* Add mechs to kexalgs ... */ - proposal[PROPOSAL_KEX_ALGS] = ssh_gssapi_make_kexalgs_list(mechs, kexalgs); + proposal[PROPOSAL_KEX_ALGS] = ssh_gssapi_make_kexalgs_list(mechs, + kexalgs); kex->mechs = dup_mechs; /* remember what we offer now */ /* @@ -375,7 +374,7 @@ mod_offer: proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xstrdup("null"); } else if (!kex->server) { hostalgs = xsplit(orig_hostalgs, ','); - for ( hostalg = hostalgs ; *hostalg != NULL ; hostalg++ ) { + for (hostalg = hostalgs; *hostalg != NULL; hostalg++) { if (strcmp(*hostalg, "null") == 0) { xfree_split_list(hostalgs); return; @@ -386,10 +385,10 @@ mod_offer: if (kex->mechs != GSS_C_NULL_OID_SET) { int len; - len = strlen(orig_hostalgs) + sizeof(",null"); + len = strlen(orig_hostalgs) + sizeof (",null"); new_hostalgs = xmalloc(len); (void) snprintf(new_hostalgs, len, "%s,null", - orig_hostalgs); + orig_hostalgs); proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = new_hostalgs; } @@ -427,46 +426,44 @@ int ssh_gssapi_is_spnego(gss_OID oid) { return (oid->length == 6 && - memcmp("\053\006\001\005\005\002", - oid->elements, 6) == 0); + memcmp("\053\006\001\005\005\002", oid->elements, 6) == 0); } int ssh_gssapi_is_krb5(gss_OID oid) { return (oid->length == 9 && - memcmp("\x2A\x86\x48\x86\xF7\x12\x01\x02\x02", - oid->elements, 9) == 0); + memcmp("\x2A\x86\x48\x86\xF7\x12\x01\x02\x02", + oid->elements, 9) == 0); } int ssh_gssapi_is_dh(gss_OID oid) { return (oid->length == 9 && - memcmp("\053\006\004\001\052\002\032\002\005", - oid->elements, 9) == 0); + memcmp("\053\006\004\001\052\002\032\002\005", + oid->elements, 9) == 0); } int ssh_gssapi_is_gsi(gss_OID oid) { return (oid->length == 9 && - memcmp("\x2B\x06\x01\x04\x01\x9B\x50\x01\x01", - oid->elements, 9) == 0); + memcmp("\x2B\x06\x01\x04\x01\x9B\x50\x01\x01", + oid->elements, 9) == 0); } -const -char * +const char * ssh_gssapi_oid_to_name(gss_OID oid) { #ifdef HAVE_GSS_OID_TO_MECH - return __gss_oid_to_mech(oid); + return (__gss_oid_to_mech(oid)); #else if (ssh_gssapi_is_krb5(oid)) - return "Kerberos"; + return ("Kerberos"); if (ssh_gssapi_is_gsi(oid)) - return "GSI"; - return "(unknown)"; + return ("GSI"); + return ("(unknown)"); #endif /* HAVE_GSS_OID_TO_MECH */ } @@ -481,42 +478,48 @@ ssh_gssapi_oid_to_str(gss_OID oid) maj = gss_oid_to_str(&min, oid, &str_buf); if (GSS_ERROR(maj)) - return xstrdup("<gss_oid_to_str() failed>"); + return (xstrdup("<gss_oid_to_str() failed>")); str = xmalloc(str_buf.length + 1); memset(str, 0, str_buf.length + 1); strlcpy(str, str_buf.value, str_buf.length + 1); (void) gss_release_buffer(&min, &str_buf); - return str; + return (str); #else - return xstrdup("<gss_oid_to_str() unsupported>"); + return (xstrdup("<gss_oid_to_str() unsupported>")); #endif /* HAVE_GSS_OID_TO_STR */ } /* Check that the OID in a data stream matches that in the context */ -int ssh_gssapi_check_mech_oid(Gssctxt *ctx, void *data, size_t len) { +int +ssh_gssapi_check_mech_oid(Gssctxt *ctx, void *data, size_t len) +{ - return (ctx!=NULL && ctx->desired_mech != GSS_C_NULL_OID && - ctx->desired_mech->length == len && - memcmp(ctx->desired_mech->elements,data,len)==0); + return (ctx != NULL && ctx->desired_mech != GSS_C_NULL_OID && + ctx->desired_mech->length == len && + memcmp(ctx->desired_mech->elements, data, len) == 0); } /* Set the contexts OID from a data stream */ -void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) { - if (ctx->actual_mech != GSS_C_NULL_OID) { - xfree(ctx->actual_mech->elements); - xfree(ctx->actual_mech); - } - ctx->actual_mech=xmalloc(sizeof(gss_OID_desc)); - ctx->actual_mech->length=len; - ctx->actual_mech->elements=xmalloc(len); - memcpy(ctx->actual_mech->elements,data,len); +void +ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) +{ + if (ctx->actual_mech != GSS_C_NULL_OID) { + xfree(ctx->actual_mech->elements); + xfree(ctx->actual_mech); + } + ctx->actual_mech = xmalloc(sizeof (gss_OID_desc)); + ctx->actual_mech->length = len; + ctx->actual_mech->elements = xmalloc(len); + memcpy(ctx->actual_mech->elements, data, len); } /* Set the contexts OID */ -void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) { - ssh_gssapi_set_oid_data(ctx,oid->elements,oid->length); +void +ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) +{ + ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); } /* All this effort to report an error ... */ @@ -536,16 +539,17 @@ ssh_gssapi_error(Gssctxt *ctxt, const char *where) } char * -ssh_gssapi_last_error(Gssctxt *ctxt, - OM_uint32 *major_status, OM_uint32 *minor_status) { +ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, + OM_uint32 *minor_status) +{ OM_uint32 lmin, more; OM_uint32 maj, min; gss_OID mech = GSS_C_NULL_OID; - gss_buffer_desc msg; - Buffer b; - char *ret; + gss_buffer_desc msg; + Buffer b; + char *ret; - buffer_init(&b); + buffer_init(&b); if (ctxt) { /* Get status codes from the Gssctxt */ @@ -558,7 +562,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, *minor_status = min; /* Get mechanism for minor status display */ mech = (ctxt->actual_mech != GSS_C_NULL_OID) ? - ctxt->actual_mech : ctxt->desired_mech; + ctxt->actual_mech : ctxt->desired_mech; } else if (major_status && minor_status) { maj = *major_status; min = *major_status; @@ -567,43 +571,42 @@ ssh_gssapi_last_error(Gssctxt *ctxt, min = 0; } - more = 0; + more = 0; /* The GSSAPI error */ - do { - gss_display_status(&lmin, maj, - GSS_C_GSS_CODE, GSS_C_NULL_OID, - &more, &msg); - - buffer_append(&b,msg.value,msg.length); - buffer_put_char(&b,'\n'); - gss_release_buffer(&lmin, &msg); - } while (more!=0); - - /* The mechanism specific error */ - do { + do { + gss_display_status(&lmin, maj, GSS_C_GSS_CODE, + GSS_C_NULL_OID, &more, &msg); + + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); + gss_release_buffer(&lmin, &msg); + } while (more != 0); + + /* The mechanism specific error */ + do { /* * If mech == GSS_C_NULL_OID we may get the default * mechanism, whatever that is, and that may not be * useful. */ - gss_display_status(&lmin, min, - GSS_C_MECH_CODE, mech, - &more, &msg); + gss_display_status(&lmin, min, GSS_C_MECH_CODE, mech, &more, + &msg); - buffer_append(&b,msg.value,msg.length); - buffer_put_char(&b,'\n'); + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); - gss_release_buffer(&lmin, &msg); - } while (more!=0); + gss_release_buffer(&lmin, &msg); + } while (more != 0); - buffer_put_char(&b,'\0'); - ret=xstrdup(buffer_ptr(&b)); - buffer_free(&b); + buffer_put_char(&b, '\0'); + ret = xstrdup(buffer_ptr(&b)); + buffer_free(&b); - return (ret); + return (ret); } -/* Initialise our GSSAPI context. We use this opaque structure to contain all +/* + * Initialise our GSSAPI context. We use this opaque structure to contain all * of the data which both the client and server need to persist across * {accept,init}_sec_context calls, so that when we do it from the userauth * stuff life is a little easier @@ -615,12 +618,12 @@ ssh_gssapi_build_ctx(Gssctxt **ctx, int client, gss_OID mech) newctx = (Gssctxt*)xmalloc(sizeof (Gssctxt)); - memset(newctx, 0, sizeof(Gssctxt)); + memset(newctx, 0, sizeof (Gssctxt)); newctx->local = client; newctx->desired_mech = ssh_gssapi_dup_oid(mech); - + /* This happens to be redundant given the memset() above */ newctx->major = GSS_S_COMPLETE; newctx->context = GSS_C_NO_CONTEXT; @@ -643,7 +646,7 @@ ssh_gssapi_dup_oid(gss_OID oid) { gss_OID new_oid; - new_oid = xmalloc(sizeof(gss_OID_desc)); + new_oid = xmalloc(sizeof (gss_OID_desc)); new_oid->elements = xmalloc(oid->length); new_oid->length = oid->length; @@ -681,10 +684,10 @@ ssh_gssapi_release_oid(gss_OID *oid) } struct gss_name { - gss_OID name_type; - gss_buffer_t external_name; - gss_OID mech_type; - void *mech_name; + gss_OID name_type; + gss_buffer_t external_name; + gss_OID mech_type; + void *mech_name; }; /* Delete our context, providing it has been built correctly */ @@ -697,24 +700,29 @@ ssh_gssapi_delete_ctx(Gssctxt **ctx) return; if ((*ctx)->context != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&ms,&(*ctx)->context,GSS_C_NO_BUFFER); - /* XXX if ((*ctx)->desired_mech != GSS_C_NULL_OID) - ssh_gssapi_release_oid(&(*ctx)->desired_mech);*/ + gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); +#if 0 + /* XXX */ + if ((*ctx)->desired_mech != GSS_C_NULL_OID) + ssh_gssapi_release_oid(&(*ctx)->desired_mech); +#endif if ((*ctx)->actual_mech != GSS_C_NULL_OID) (void) ssh_gssapi_release_oid(&(*ctx)->actual_mech); if ((*ctx)->desired_name != GSS_C_NO_NAME) - gss_release_name(&ms,&(*ctx)->desired_name); - /* if ((*ctx)->src_name != GSS_C_NO_NAME) - gss_release_name(&ms,&(*ctx)->src_name); */ + gss_release_name(&ms, &(*ctx)->desired_name); +#if 0 + if ((*ctx)->src_name != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->src_name); +#endif if ((*ctx)->dst_name != GSS_C_NO_NAME) - gss_release_name(&ms,&(*ctx)->dst_name); + gss_release_name(&ms, &(*ctx)->dst_name); if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms,&(*ctx)->creds); + gss_release_cred(&ms, &(*ctx)->creds); if ((*ctx)->deleg_creds != GSS_C_NO_CREDENTIAL) - gss_release_cred(&ms,&(*ctx)->deleg_creds); + gss_release_cred(&ms, &(*ctx)->deleg_creds); xfree(*ctx); - *ctx=NULL; + *ctx = NULL; } /* Create a GSS hostbased service principal name for a given server hostname */ @@ -725,50 +733,49 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *server_host) int ret; /* Build target principal */ - - /* Non-portable but very neat code relying on SUSv3: - name_buf.length = snprintf(NULL, 0, "%s@%S", - SSH_GSS_HOSTBASED_SERVICE, server_host); - */ - name_buf.length = strlen(SSH_GSS_HOSTBASED_SERVICE) + - strlen(server_host) + 1; /* +1 for '@' */ + strlen(server_host) + 1; /* +1 for '@' */ name_buf.value = xmalloc(name_buf.length + 1); /* +1 for NUL */ ret = snprintf(name_buf.value, name_buf.length + 1, "%s@%s", - SSH_GSS_HOSTBASED_SERVICE, server_host); + SSH_GSS_HOSTBASED_SERVICE, server_host); - debug3("%s: snprintf() returned %d, expected %d", __func__, ret, name_buf.length + 1); + debug3("%s: snprintf() returned %d, expected %d", __func__, ret, + name_buf.length + 1); ctx->major = gss_import_name(&ctx->minor, &name_buf, - GSS_C_NT_HOSTBASED_SERVICE, &ctx->desired_name); + GSS_C_NT_HOSTBASED_SERVICE, &ctx->desired_name); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx, "calling GSS_Import_name()"); - return 0; + return (0); } xfree(name_buf.value); - return 1; + return (1); } OM_uint32 -ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) { +ssh_gssapi_get_mic(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) +{ - ctx->major=gss_get_mic(&ctx->minor,ctx->context, - GSS_C_QOP_DEFAULT, buffer, hash); + ctx->major = gss_get_mic(&ctx->minor, ctx->context, + GSS_C_QOP_DEFAULT, buffer, hash); if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx, "while getting MIC"); - return(ctx->major); + return (ctx->major); } OM_uint32 -ssh_gssapi_verify_mic(Gssctxt *ctx, gss_buffer_desc *buffer, gss_buffer_desc *hash) { +ssh_gssapi_verify_mic(Gssctxt *ctx, gss_buffer_desc *buffer, + gss_buffer_desc *hash) +{ gss_qop_t qop; - ctx->major=gss_verify_mic(&ctx->minor,ctx->context, buffer, hash, &qop); + ctx->major = gss_verify_mic(&ctx->minor, ctx->context, buffer, + hash, &qop); if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx, "while verifying MIC"); - return(ctx->major); + return (ctx->major); } #endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/ssh/gss-clnt.c b/usr/src/cmd/ssh/ssh/gss-clnt.c index 3d536da7a6..05cd358217 100644 --- a/usr/src/cmd/ssh/ssh/gss-clnt.c +++ b/usr/src/cmd/ssh/ssh/gss-clnt.c @@ -21,7 +21,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -92,12 +92,12 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs) return; } maj = gss_acquire_cred(&min, GSS_C_NO_NAME, 0, indicated, - GSS_C_INITIATE, &creds, &acquired, NULL); + GSS_C_INITIATE, &creds, &acquired, NULL); if (GSS_ERROR(maj)) { errmsg = ssh_gssapi_last_error(NULL, &maj, &min); debug("Failed to acquire GSS-API credentials for any " - "mechanisms (%s)", errmsg); + "mechanisms (%s)", errmsg); xfree(errmsg); (void) gss_release_oid_set(&min, &indicated); (void) gss_release_oid_set(&min, &supported); @@ -105,7 +105,7 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs) } (void) gss_release_cred(&min, &creds); - for (i = 0 ; i < acquired->count ; i++) { + for (i = 0; i < acquired->count; i++) { mech = &acquired->elements[i]; if (ssh_gssapi_is_spnego(mech)) @@ -124,8 +124,7 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs) * 'Twould be useful to have a test that could save us * the bother of trying this for SPKM and the such... */ - maj = ssh_gssapi_init_ctx(ctxt, server_host, 0, - NULL, &tok); + maj = ssh_gssapi_init_ctx(ctxt, server_host, 0, NULL, &tok); if (GSS_ERROR(maj)) { errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL); debug("Skipping GSS-API mechanism %s (%s)", @@ -149,8 +148,9 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs) } -/* Wrapper to init_sec_context - * Requires that the context contains: +/* + * Wrapper to init_sec_context. Requires that the context contains: + * * oid * server name (from ssh_gssapi_import_name) */ @@ -161,7 +161,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, int deleg_creds, int flags = GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG; debug("%s(%p, %s, %d, %p, %p)", __func__, ctx, server_host, - deleg_creds, recv_tok, send_tok); + deleg_creds, recv_tok, send_tok); if (deleg_creds) { flags |= GSS_C_DELEG_FLAG; @@ -170,26 +170,22 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, const char *server_host, int deleg_creds, /* Build target principal */ if (ctx->desired_name == GSS_C_NO_NAME && - !ssh_gssapi_import_name(ctx, server_host)) - return ctx->major; - - ctx->major=gss_init_sec_context(&ctx->minor, - GSS_C_NO_CREDENTIAL, - &ctx->context, - ctx->desired_name, - ctx->desired_mech, - flags, - 0, /* default lifetime */ - NULL, /* no channel bindings */ - recv_tok, - NULL, /* actual mech type */ - send_tok, - &ctx->flags, - NULL); /* actual lifetime */ - - if (GSS_ERROR(ctx->major)) + !ssh_gssapi_import_name(ctx, server_host)) { + return (ctx->major); + } + + ctx->major = gss_init_sec_context(&ctx->minor, GSS_C_NO_CREDENTIAL, + &ctx->context, ctx->desired_name, ctx->desired_mech, flags, + 0, /* default lifetime */ + NULL, /* no channel bindings */ + recv_tok, + NULL, /* actual mech type */ + send_tok, &ctx->flags, + NULL); /* actual lifetime */ + + if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx, "calling GSS_Init_sec_context()"); - return(ctx->major); + return (ctx->major); } #endif /* GSSAPI */ diff --git a/usr/src/cmd/ssh/sshd/auth2-gss.c b/usr/src/cmd/ssh/sshd/auth2-gss.c index 70560dad3a..d43d78d021 100644 --- a/usr/src/cmd/ssh/sshd/auth2-gss.c +++ b/usr/src/cmd/ssh/sshd/auth2-gss.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,7 +46,7 @@ #include "ssh-gss.h" extern ServerOptions options; -extern u_char *session_id2; +extern uchar_t *session_id2; extern int session_id2_len; extern Gssctxt *xxx_gssctxt; @@ -55,9 +55,9 @@ static void userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt); static void userauth_gssapi_keyex(Authctxt *authctxt) { - gss_buffer_desc g_mic_data, mic_tok; + gss_buffer_desc g_mic_data, mic_tok; Buffer mic_data; - OM_uint32 maj_status, min_status; + OM_uint32 maj_status, min_status; if (authctxt == NULL || authctxt->method == NULL) fatal("No authentication context during gssapi-keyex userauth"); @@ -67,7 +67,7 @@ userauth_gssapi_keyex(Authctxt *authctxt) debug("No GSS-API context during gssapi-keyex userauth"); return; } - + /* Make data buffer to verify MIC with */ buffer_init(&mic_data); buffer_put_string(&mic_data, session_id2, session_id2_len); @@ -79,12 +79,12 @@ userauth_gssapi_keyex(Authctxt *authctxt) g_mic_data.value = buffer_ptr(&mic_data); g_mic_data.length = buffer_len(&mic_data); - mic_tok.value=packet_get_string(&mic_tok.length); + mic_tok.value = packet_get_string(&mic_tok.length); maj_status = gss_verify_mic(&min_status, xxx_gssctxt->context, - &g_mic_data, &mic_tok, NULL); + &g_mic_data, &mic_tok, NULL); - packet_check_eom(); + packet_check_eom(); buffer_clear(&mic_data); if (maj_status != GSS_S_COMPLETE) @@ -95,15 +95,14 @@ userauth_gssapi_keyex(Authctxt *authctxt) /* Leave Gssctxt around for ssh_gssapi_cleanup/storecreds() */ if (xxx_gssctxt->deleg_creds == GSS_C_NO_CREDENTIAL) ssh_gssapi_delete_ctx(&xxx_gssctxt); - - return; } static void ssh_gssapi_userauth_error(Gssctxt *ctxt); static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); static void input_gssapi_errtok(int, u_int32_t, void *); -static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_exchange_complete(int type, u_int32_t plen, + void *ctxt); static void userauth_gssapi_abandon(Authctxt *authctxt, Authmethod *method) @@ -113,158 +112,163 @@ userauth_gssapi_abandon(Authctxt *authctxt, Authmethod *method) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); } static void userauth_gssapi(Authctxt *authctxt) { - gss_OID_set supported_mechs; - int mechs; - int present = 0; - OM_uint32 min_status; - u_int len; - char *doid = NULL; - gss_OID oid = GSS_C_NULL_OID; - - if (datafellows & SSH_OLD_GSSAPI) { - debug("Early drafts of GSSAPI userauth not supported"); - return; - } - - mechs=packet_get_int(); - if (mechs==0) { + gss_OID_set supported_mechs; + int mechs, present = 0; + OM_uint32 min_status; + uint_t len; + char *doid = NULL; + gss_OID oid = GSS_C_NULL_OID; + + if (datafellows & SSH_OLD_GSSAPI) { + debug("Early drafts of GSSAPI userauth not supported"); + return; + } + + mechs = packet_get_int(); + if (mechs == 0) { packet_check_eom(); - debug("Mechanism negotiation is not supported"); - return; - } + debug("Mechanism negotiation is not supported"); + return; + } ssh_gssapi_server_mechs(&supported_mechs); - do { - mechs--; + do { + mechs--; if (oid != GSS_C_NULL_OID) ssh_gssapi_release_oid(&oid); - doid = packet_get_string(&len); + doid = packet_get_string(&len); /* ick */ - if (doid[0]!=0x06 || (len > 2 && doid[1]!=len-2)) { - log("Mechanism OID received using the old encoding form"); + if (doid[0] != 0x06 || (len > 2 && doid[1] != len - 2)) { + log("Mechanism OID received using the old " + "encoding form"); oid = ssh_gssapi_make_oid(len, doid); - } else { + } else { oid = ssh_gssapi_make_oid(len - 2, doid + 2); - } - (void) gss_test_oid_set_member(&min_status, oid, - supported_mechs, &present); - debug("Client offered gssapi userauth with %s (%s)", - ssh_gssapi_oid_to_str(oid), - present ? "supported" : "unsupported"); - } while (!present && (mechs > 0)); - - if (!present) { + } + + (void) gss_test_oid_set_member(&min_status, oid, + supported_mechs, &present); + + debug("Client offered gssapi userauth with %s (%s)", + ssh_gssapi_oid_to_str(oid), + present ? "supported" : "unsupported"); + } while (!present && (mechs > 0)); + + if (!present) { /* userauth_finish() will send SSH2_MSG_USERAUTH_FAILURE */ debug2("No mechanism offered by the client is available"); - ssh_gssapi_release_oid(&oid); - return; - } + ssh_gssapi_release_oid(&oid); + return; + } - ssh_gssapi_build_ctx((Gssctxt **)&authctxt->method->method_data, 0, oid); - ssh_gssapi_release_oid(&oid); - /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */ + ssh_gssapi_build_ctx((Gssctxt **)&authctxt->method->method_data, + 0, oid); + ssh_gssapi_release_oid(&oid); + /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */ - packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); + packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); /* Just return whatever we found -- the matched mech does us no good */ packet_put_string(doid, len); xfree(doid); - packet_send(); - packet_write_wait(); + packet_send(); + packet_write_wait(); /* Setup rest of gssapi userauth conversation */ - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); - authctxt->method->postponed = 1; - - return; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + authctxt->method->postponed = 1; } static void input_gssapi_token(int type, u_int32_t plen, void *ctxt) { - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok,recv_tok; - OM_uint32 maj_status, min_status; - u_int len; + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok, recv_tok; + OM_uint32 maj_status, min_status; + uint_t len; - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) - fatal("No authentication or GSSAPI context during gssapi-with-mic userauth"); + if (authctxt == NULL || authctxt->method == NULL || + (authctxt->method->method_data == NULL)) { + fatal("No authentication or GSSAPI context during " + "gssapi-with-mic userauth"); + } - gssctxt=authctxt->method->method_data; - recv_tok.value=packet_get_string(&len); - recv_tok.length=len; /* u_int vs. size_t */ + gssctxt = authctxt->method->method_data; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; /* u_int vs. size_t */ - maj_status = ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); - packet_check_eom(); + maj_status = ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); + packet_check_eom(); - if (GSS_ERROR(maj_status)) { - ssh_gssapi_userauth_error(gssctxt); + if (GSS_ERROR(maj_status)) { + ssh_gssapi_userauth_error(gssctxt); if (send_tok.length != 0) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - } - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - userauth_finish(authctxt, authctxt->method->name); - } else { - if (send_tok.length != 0) { - packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); - packet_put_string(send_tok.value,send_tok.length); - packet_send(); - packet_write_wait(); - } - if (maj_status == GSS_S_COMPLETE) { - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, - &input_gssapi_mic); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, - &input_gssapi_exchange_complete); - } - } - - gss_release_buffer(&min_status, &send_tok); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + packet_write_wait(); + } + authctxt->method->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + userauth_finish(authctxt, authctxt->method->name); + } else { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + packet_write_wait(); + } + if (maj_status == GSS_S_COMPLETE) { + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, + &input_gssapi_mic); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, + &input_gssapi_exchange_complete); + } + } + + gss_release_buffer(&min_status, &send_tok); } static void input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) { - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; - gss_buffer_desc send_tok,recv_tok; + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok, recv_tok; - if (authctxt == NULL || authctxt->method == NULL || - (authctxt->method->method_data == NULL)) - fatal("No authentication or GSSAPI context during gssapi-with-mic userauth"); + if (authctxt == NULL || authctxt->method == NULL || + (authctxt->method->method_data == NULL)) { + fatal("No authentication or GSSAPI context during " + "gssapi-with-mic userauth"); + } - gssctxt=authctxt->method->method_data; - recv_tok.value=packet_get_string(&recv_tok.length); - packet_check_eom(); + gssctxt = authctxt->method->method_data; + recv_tok.value = packet_get_string(&recv_tok.length); + packet_check_eom(); - /* Push the error token into GSSAPI to see what it says */ - (void) ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); + /* Push the error token into GSSAPI to see what it says */ + (void) ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok); debug("Client sent GSS-API error token during GSS userauth-- %s", - ssh_gssapi_last_error(gssctxt, NULL, NULL)); + ssh_gssapi_last_error(gssctxt, NULL, NULL)); /* We can't return anything to the client, even if we wanted to */ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); /* @@ -284,17 +288,18 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; Gssctxt *gssctxt; - gss_buffer_desc g_mic_data, mic_tok; + gss_buffer_desc g_mic_data, mic_tok; Buffer mic_data; - OM_uint32 maj_status, min_status; + OM_uint32 maj_status, min_status; if (authctxt == NULL || authctxt->method == NULL || (authctxt->method->method_data == NULL)) { - debug3("No authentication or GSSAPI context during gssapi-with-mic userauth"); + debug3("No authentication or GSSAPI context during " + "gssapi-with-mic userauth"); return; } - gssctxt=authctxt->method->method_data; + gssctxt = authctxt->method->method_data; /* Make data buffer to verify MIC with */ buffer_init(&mic_data); @@ -307,12 +312,12 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) g_mic_data.value = buffer_ptr(&mic_data); g_mic_data.length = buffer_len(&mic_data); - mic_tok.value=packet_get_string(&mic_tok.length); + mic_tok.value = packet_get_string(&mic_tok.length); maj_status = gss_verify_mic(&min_status, gssctxt->context, - &g_mic_data, &mic_tok, NULL); + &g_mic_data, &mic_tok, NULL); - packet_check_eom(); + packet_check_eom(); buffer_free(&mic_data); if (maj_status != GSS_S_COMPLETE) @@ -330,30 +335,31 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) xxx_gssctxt = gssctxt; - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - userauth_finish(authctxt, authctxt->method->name); + authctxt->method->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); + userauth_finish(authctxt, authctxt->method->name); } -/* This is called when the client thinks we've completed authentication. +/* + * This is called when the client thinks we've completed authentication. * It should only be enabled in the dispatch handler by the function above, * which only enables it once the GSSAPI exchange is complete. */ static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) { - Authctxt *authctxt = ctxt; - Gssctxt *gssctxt; + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; packet_check_eom(); if (authctxt == NULL || authctxt->method == NULL || (authctxt->method->method_data == NULL)) - fatal("No authentication or GSSAPI context"); + fatal("No authentication or GSSAPI context"); - gssctxt=authctxt->method->method_data; + gssctxt = authctxt->method->method_data; /* * SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE -> gssapi userauth @@ -378,25 +384,28 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) * this will do for now. */ #if 0 - authctxt->method->authenticated = ssh_gssapi_userok(gssctxt, authctxt->user); + authctxt->method->authenticated = ssh_gssapi_userok(gssctxt, + authctxt->user); #endif if (xxx_gssctxt != gssctxt) ssh_gssapi_delete_ctx(&gssctxt); ssh_gssapi_delete_ctx(&gssctxt); - authctxt->method->postponed = 0; - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); - dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); - userauth_finish(authctxt, authctxt->method->name); + authctxt->method->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); + userauth_finish(authctxt, authctxt->method->name); } -static void ssh_gssapi_userauth_error(Gssctxt *ctxt) { +static void +ssh_gssapi_userauth_error(Gssctxt *ctxt) +{ char *errstr; - OM_uint32 maj,min; + OM_uint32 maj, min; - errstr=ssh_gssapi_last_error(ctxt,&maj,&min); + errstr = ssh_gssapi_last_error(ctxt, &maj, &min); if (errstr) { packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERROR); packet_put_int(maj); @@ -414,8 +423,7 @@ static void ssh_gssapi_userauth_error(Gssctxt *ctxt) { * * Does authorization, figures out how to store delegated creds. */ -static -void +static void userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt) { char *local_user = NULL; @@ -435,8 +443,8 @@ userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt) strcmp(local_user, authctxt->user) == 0) gssctxt->default_creds = 1; /* store creds as default */ - authctxt->method->authenticated = - do_pam_non_initial_userauth(authctxt); + authctxt->method->authenticated = + do_pam_non_initial_userauth(authctxt); } else if (*authctxt->user == '\0') { /* Requested username == ""; derive username from princ name */ @@ -449,7 +457,7 @@ userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt) gssctxt->default_creds = 1; /* store creds as default */ authctxt->method->authenticated = - do_pam_non_initial_userauth(authctxt); + do_pam_non_initial_userauth(authctxt); } if (local_user != NULL) @@ -457,13 +465,13 @@ userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt) if (*authctxt->user != '\0' && authctxt->method->authenticated != 0) { major = gss_display_name(&gssctxt->minor, gssctxt->src_name, - &dispname, NULL); + &dispname, NULL); if (major == GSS_S_COMPLETE) { log("Authorized principal %.*s, authenticated with " "GSS mechanism %s, to: %s", - dispname.length, (char *)dispname.value, - ssh_gssapi_oid_to_name(gssctxt->actual_mech), - authctxt->user); + dispname.length, (char *)dispname.value, + ssh_gssapi_oid_to_name(gssctxt->actual_mech), + authctxt->user); } (void) gss_release_buffer(&gssctxt->minor, &dispname); } @@ -485,9 +493,9 @@ Authmethod method_external = { }; Authmethod method_gssapi = { - "gssapi", - &options.gss_authentication, - userauth_gssapi, + "gssapi", + &options.gss_authentication, + userauth_gssapi, userauth_gssapi_abandon, NULL, NULL, @@ -512,9 +520,9 @@ Authmethod method_external = { }; Authmethod method_gssapi = { - "gssapi-with-mic", - &options.gss_authentication, - userauth_gssapi, + "gssapi-with-mic", + &options.gss_authentication, + userauth_gssapi, userauth_gssapi_abandon, NULL, NULL, diff --git a/usr/src/cmd/ssh/sshd/gss-serv.c b/usr/src/cmd/ssh/sshd/gss-serv.c index 98b962b3d0..7ff525c306 100644 --- a/usr/src/cmd/ssh/sshd/gss-serv.c +++ b/usr/src/cmd/ssh/sshd/gss-serv.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,7 +58,7 @@ extern char **environ; extern ServerOptions options; -extern u_char *session_id2; +extern uchar_t *session_id2; extern int session_id2_len; Gssctxt *xxx_gssctxt; @@ -99,7 +99,7 @@ ssh_gssapi_server_mechs(gss_OID_set *mechs) maj = gss_create_empty_oid_set(&min, &s); if (GSS_ERROR(maj)) { debug("Could not allocate GSS-API resources (%s)", - ssh_gssapi_last_error(NULL, &maj, &min)); + ssh_gssapi_last_error(NULL, &maj, &min)); return; } @@ -110,12 +110,11 @@ ssh_gssapi_server_mechs(gss_OID_set *mechs) } maj = gss_acquire_cred(&min, GSS_C_NO_NAME, 0, indicated, - GSS_C_ACCEPT, &creds, &acquired, NULL); + GSS_C_ACCEPT, &creds, &acquired, NULL); if (GSS_ERROR(maj)) debug("Failed to acquire GSS-API credentials for any " - "mechanisms (%s)", - ssh_gssapi_last_error(NULL, &maj, &min)); + "mechanisms (%s)", ssh_gssapi_last_error(NULL, &maj, &min)); (void) gss_release_oid_set(&min, &indicated); (void) gss_release_cred(&min, &creds); @@ -123,14 +122,14 @@ ssh_gssapi_server_mechs(gss_OID_set *mechs) if (acquired == GSS_C_NULL_OID_SET || acquired->count == 0) return; - for (i = 0 ; i < acquired->count ; i++ ) { + for (i = 0; i < acquired->count; i++) { if (ssh_gssapi_is_spnego(&acquired->elements[i])) continue; maj = gss_add_oid_set_member(&min, &acquired->elements[i], &s); if (GSS_ERROR(maj)) { debug("Could not allocate GSS-API resources (%s)", - ssh_gssapi_last_error(NULL, &maj, &min)); + ssh_gssapi_last_error(NULL, &maj, &min)); return; } } @@ -142,14 +141,16 @@ ssh_gssapi_server_mechs(gss_OID_set *mechs) } } -/* Wrapper around accept_sec_context - * Requires that the context contains: +/* + * Wrapper around accept_sec_context. Requires that the context contains: + * * oid * credentials (from ssh_gssapi_acquire_cred) */ /* Priviledged */ -OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, - gss_buffer_t send_tok) +OM_uint32 +ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, + gss_buffer_t send_tok) { /* * Acquiring a cred for the ctx->desired_mech for GSS_C_NO_NAME @@ -157,43 +158,39 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, * and then checking that ctx->desired_mech agrees with * ctx->actual_mech... */ - ctx->major=gss_accept_sec_context(&ctx->minor, - &ctx->context, - GSS_C_NO_CREDENTIAL, - recv_tok, - GSS_C_NO_CHANNEL_BINDINGS, - &ctx->src_name, - &ctx->actual_mech, - send_tok, - &ctx->flags, - NULL, - &ctx->deleg_creds); + ctx->major = gss_accept_sec_context(&ctx->minor, &ctx->context, + GSS_C_NO_CREDENTIAL, recv_tok, GSS_C_NO_CHANNEL_BINDINGS, + &ctx->src_name, &ctx->actual_mech, send_tok, &ctx->flags, + NULL, &ctx->deleg_creds); + if (GSS_ERROR(ctx->major)) ssh_gssapi_error(ctx, "accepting security context"); if (ctx->major == GSS_S_CONTINUE_NEEDED && send_tok->length == 0) - fatal("Zero length GSS context token output when continue needed"); + fatal("Zero length GSS context token output when " + "continue needed"); else if (GSS_ERROR(ctx->major) && send_tok->length == 0) debug2("Zero length GSS context error token output"); if (ctx->major == GSS_S_COMPLETE && ctx->desired_mech != GSS_C_NULL_OID && (ctx->desired_mech->length != ctx->actual_mech->length || - memcmp(ctx->desired_mech->elements, - ctx->actual_mech->elements, - ctx->desired_mech->length) != 0)) { + memcmp(ctx->desired_mech->elements, ctx->actual_mech->elements, + ctx->desired_mech->length) != 0)) { + gss_OID_set supported; - OM_uint32 min; - int present = 0; + OM_uint32 min; + int present = 0; - debug("The client did not use the GSS-API mechanism it asked for"); + debug("The client did not use the GSS-API mechanism it " + "asked for"); /* Let it slide as long as the mech is supported */ ssh_gssapi_server_mechs(&supported); - if (supported != GSS_C_NULL_OID_SET) - (void) gss_test_oid_set_member(&min, - ctx->actual_mech, - supported, &present); + if (supported != GSS_C_NULL_OID_SET) { + (void) gss_test_oid_set_member(&min, ctx->actual_mech, + supported, &present); + } if (!present) ctx->major = GSS_S_BAD_MECH; } @@ -203,11 +200,12 @@ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t recv_tok, if (ctx->major == GSS_S_COMPLETE) { ctx->major = gss_inquire_context(&ctx->minor, ctx->context, - NULL, &ctx->dst_name, NULL, NULL, - NULL, NULL, &ctx->established); + NULL, &ctx->dst_name, NULL, NULL, NULL, NULL, + &ctx->established); if (GSS_ERROR(ctx->major)) { - ssh_gssapi_error(ctx, "inquiring established sec context"); + ssh_gssapi_error(ctx, + "inquiring established sec context"); return (ctx->major); } @@ -227,7 +225,7 @@ ssh_gssapi_cleanup_creds(Gssctxt *ctx) return; #else return; -/*#error "Portability broken in cleanup of stored creds"*/ +/* #error "Portability broken in cleanup of stored creds" */ #endif /* HAVE_GSS_STORE_CRED */ } @@ -237,7 +235,7 @@ ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt) #ifdef USE_PAM char **penv, **tmp_env; #endif /* USE_PAM */ - + if (authctxt == NULL) { error("Missing context while storing GSS-API credentials"); return; @@ -249,16 +247,16 @@ ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt) if (ctx == NULL) ctx = xxx_gssctxt; - if (!options.gss_cleanup_creds || + if (!options.gss_cleanup_creds || ctx->deleg_creds == GSS_C_NO_CREDENTIAL) { debug3("Not storing delegated GSS credentials" - " (none delegated)"); + " (none delegated)"); return; } if (!authctxt->valid || authctxt->pw == NULL) { debug3("Not storing delegated GSS credentials" - " for invalid user"); + " for invalid user"); return; } @@ -298,14 +296,14 @@ ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt) if (authctxt->pw->pw_uid != geteuid()) { temporarily_use_uid(authctxt->pw); ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds, - GSS_C_INITIATE, GSS_C_NULL_OID, 0, - ctx->default_creds, NULL, NULL); + GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds, + NULL, NULL); restore_uid(); } else { /* only when logging in as the privileged user used by sshd */ ctx->major = gss_store_cred(&ctx->minor, ctx->deleg_creds, - GSS_C_INITIATE, GSS_C_NULL_OID, 0, - ctx->default_creds, NULL, NULL); + GSS_C_INITIATE, GSS_C_NULL_OID, 0, ctx->default_creds, + NULL, NULL); } #ifdef USE_PAM environ = tmp_env; @@ -325,13 +323,13 @@ ssh_gssapi_storecreds(Gssctxt *ctx, Authctxt *authctxt) if (ssh_gssapi_is_gsi(ctx->mech)) ssh_gssapi_krb5_storecreds(ctx); #endif /* GSI_GSS */ -/*#error "Mechanism-specific code missing in ssh_gssapi_storecreds()"*/ +/* #error "Mechanism-specific code missing in ssh_gssapi_storecreds()" */ return; #endif /* HAVE_GSS_STORE_CRED */ } void -ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, u_int *envsizep) +ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, uint_t *envsizep) { /* * MIT/Heimdal/GSI specific code goes here. @@ -347,7 +345,6 @@ ssh_gssapi_do_child(Gssctxt *ctx, char ***envp, u_int *envsizep) #ifdef GSI_GSS #error "GSI krb5-specific code missing in ssh_gssapi_storecreds()" #endif /* GSI_GSS */ - return; } int @@ -366,7 +363,7 @@ ssh_gssapi_userok(Gssctxt *ctx, char *user) int user_ok = 0; ctx->major = __gss_userok(&ctx->minor, ctx->src_name, user, - &user_ok); + &user_ok); if (GSS_ERROR(ctx->major)) { debug2("__GSS_userok() failed"); return (0); @@ -389,15 +386,15 @@ ssh_gssapi_userok(Gssctxt *ctx, char *user) buf.value = user; buf.length = strlen(user); ctx->major = gss_import_name(&ctx->minor, &buf, - GSS_C_NULL_OID, &iname); + GSS_C_NULL_OID, &iname); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx, - "importing name for authorizing initiator"); + "importing name for authorizing initiator"); goto failed_simple_userok; } ctx->major = gss_canonicalize_name(&ctx->minor, iname, - ctx->actual_mech, &cname); + ctx->actual_mech, &cname); (void) gss_release_name(&min, &iname); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx, "canonicalizing name"); @@ -412,16 +409,16 @@ ssh_gssapi_userok(Gssctxt *ctx, char *user) } ctx->major = gss_export_name(&ctx->minor, ctx->src_name, - &ename2); + &ename2); if (GSS_ERROR(ctx->major)) { ssh_gssapi_error(ctx, - "exporting client principal name"); + "exporting client principal name"); (void) gss_release_buffer(&min, &ename1); goto failed_simple_userok; } eql = (ename1.length == ename2.length && - memcmp(ename1.value, ename2.value, ename1.length) == 0); + memcmp(ename1.value, ename2.value, ename1.length) == 0); (void) gss_release_buffer(&min, &ename1); (void) gss_release_buffer(&min, &ename2); @@ -440,7 +437,7 @@ failed_simple_userok: struct passwd *pw; maj = gsscred_name_to_unix_cred(ctx->src_name, - ctx->actual_mech, &uid, NULL, NULL, NULL); + ctx->actual_mech, &uid, NULL, NULL, NULL); if (GSS_ERROR(maj)) goto failed_simple_gsscred_userok; @@ -452,6 +449,7 @@ failed_simple_userok: return (1); /* fall through */ } + failed_simple_gsscred_userok: #endif /* HAVE_GSSCRED_API */ #ifdef KRB5_GSS @@ -490,7 +488,7 @@ ssh_gssapi_localname(Gssctxt *ctx) goto failed_gsscred_localname; maj = gsscred_name_to_unix_cred(ctx->src_name, - ctx->actual_mech, &uid, NULL, NULL, NULL); + ctx->actual_mech, &uid, NULL, NULL, NULL); if (GSS_ERROR(maj)) goto failed_gsscred_localname; @@ -515,4 +513,4 @@ failed_gsscred_localname: #endif /* GSI_GSS */ return (NULL); } -#endif /*GSSAPI */ +#endif /* GSSAPI */ |