diff --git a/ssh.c b/ssh.c index 9f2d0111..53093de0 100644 --- a/ssh.c +++ b/ssh.c @@ -7805,7 +7805,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, /* GSSAPI Authentication */ - int micoffset; + int micoffset, len; + char *data; Ssh_gss_buf mic; s->type = AUTH_TYPE_GSSAPI; s->tried_gssapi = TRUE; @@ -7825,13 +7826,14 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, ssh2_pkt_adduint32(s->pktout,1); /* length of OID + 2 */ - ssh2_pkt_adduint32(s->pktout, s->gss_buf.len + 2); + ssh2_pkt_adduint32(s->pktout, s->gss_buf.length + 2); ssh2_pkt_addbyte(s->pktout, SSH2_GSS_OIDTYPE); /* length of OID */ - ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.len); + ssh2_pkt_addbyte(s->pktout, (unsigned char) s->gss_buf.length); - ssh_pkt_adddata(s->pktout, s->gss_buf.data, s->gss_buf.len); + ssh_pkt_adddata(s->pktout, s->gss_buf.value, + s->gss_buf.length); ssh2_pkt_send(ssh, s->pktout); crWaitUntilV(pktin); if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) { @@ -7841,11 +7843,14 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, /* check returned packet ... */ - ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len); - if (s->gss_rcvtok.len != s->gss_buf.len + 2 || - s->gss_rcvtok.data[0] != SSH2_GSS_OIDTYPE || - s->gss_rcvtok.data[1] != s->gss_buf.len || - memcmp(s->gss_rcvtok.data+2,s->gss_buf.data,s->gss_buf.len) ) { + ssh_pkt_getstring(pktin, &data, &len); + s->gss_rcvtok.value = data; + s->gss_rcvtok.length = len; + if (s->gss_rcvtok.length != s->gss_buf.length + 2 || + ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE || + ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length || + memcmp((char *)s->gss_rcvtok.value + 2, + s->gss_buf.value,s->gss_buf.length) ) { logevent("GSSAPI authentication - wrong response from server"); continue; } @@ -7871,8 +7876,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, } /* initial tokens are empty */ - s->gss_rcvtok.len = s->gss_sndtok.len = 0; - s->gss_rcvtok.data = s->gss_sndtok.data = NULL; + SSH_GSS_CLEAR_BUF(&s->gss_rcvtok); /* now enter the loop */ do { @@ -7887,8 +7891,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, logevent("GSSAPI authentication initialisation failed"); if (ssh_gss_display_status(s->gss_ctx,&s->gss_buf) == SSH_GSS_OK) { - logevent(s->gss_buf.data); - sfree(s->gss_buf.data); + logevent(s->gss_buf.value); + sfree(s->gss_buf.value); } break; @@ -7898,10 +7902,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, /* Client and server now exchange tokens until GSSAPI * no longer says CONTINUE_NEEDED */ - if (s->gss_sndtok.len != 0) { + if (s->gss_sndtok.length != 0) { s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); ssh_pkt_addstring_start(s->pktout); - ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.data,s->gss_sndtok.len); + ssh_pkt_addstring_data(s->pktout,s->gss_sndtok.value,s->gss_sndtok.length); ssh2_pkt_send(ssh, s->pktout); ssh_gss_free_tok(&s->gss_sndtok); } @@ -7913,7 +7917,9 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, s->gss_stat = SSH_GSS_FAILURE; break; } - ssh_pkt_getstring(pktin,&s->gss_rcvtok.data,&s->gss_rcvtok.len); + ssh_pkt_getstring(pktin, &data, &len); + s->gss_rcvtok.value = data; + s->gss_rcvtok.length = len; } } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED); @@ -7935,13 +7941,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, ssh_pkt_addstring(s->pktout, "ssh-connection"); ssh_pkt_addstring(s->pktout, "gssapi-with-mic"); - s->gss_buf.data = (char *)s->pktout->data + micoffset; - s->gss_buf.len = s->pktout->length - micoffset; + s->gss_buf.value = (char *)s->pktout->data + micoffset; + s->gss_buf.length = s->pktout->length - micoffset; ssh_gss_get_mic(s->gss_ctx, &s->gss_buf, &mic); s->pktout = ssh2_pkt_init(SSH2_MSG_USERAUTH_GSSAPI_MIC); ssh_pkt_addstring_start(s->pktout); - ssh_pkt_addstring_data(s->pktout, mic.data, mic.len); + ssh_pkt_addstring_data(s->pktout, mic.value, mic.length); ssh2_pkt_send(ssh, s->pktout); ssh_gss_free_mic(&mic); diff --git a/sshgss.h b/sshgss.h index dfd5e660..c188464a 100644 --- a/sshgss.h +++ b/sshgss.h @@ -12,16 +12,9 @@ typedef enum Ssh_gss_stat { #define SSH_GSS_S_COMPLETE SSH_GSS_OK -typedef struct Ssh_gss_buf { - int len; - char *data; -} Ssh_gss_buf; - -#define SSH_GSS_EMPTY_BUF (Ssh_gss_buf) {0,NULL} - #define SSH_GSS_CLEAR_BUF(buf) do { \ - (*buf).len = 0; \ - (*buf).data = NULL; \ + (*buf).length = 0; \ + (*buf).value = NULL; \ } while (0) /* Functions, provided by either wingss.c or uxgss.c */ diff --git a/unix/unix.h b/unix/unix.h index 44749b8d..a5bf8dc5 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -60,6 +60,15 @@ extern long tickcount_offset; #define WCHAR wchar_t #define BYTE unsigned char +#ifndef NO_GSSAPI +/* + * GSS-API stuff + */ +#include +typedef gss_buffer_desc Ssh_gss_buf; +#define SSH_GSS_EMPTY_BUF GSS_C_EMPTY_BUFFER +#endif + /* * Unix-specific global flag * diff --git a/unix/uxgss.c b/unix/uxgss.c index 1a6668e9..0a9464de 100644 --- a/unix/uxgss.c +++ b/unix/uxgss.c @@ -6,9 +6,9 @@ #ifndef NO_GSSAPI -static gss_OID_desc gss_mech_krb5_desc = +static gss_OID_desc putty_gss_mech_krb5_desc = { 9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; -static gss_OID const gss_mech_krb5 = &gss_mech_krb5_desc; +static gss_OID const putty_gss_mech_krb5 = &putty_gss_mech_krb5_desc; typedef struct uxSsh_gss_ctx { OM_uint32 maj_stat; @@ -27,8 +27,8 @@ int ssh_gss_init(void) Ssh_gss_stat ssh_gss_indicate_mech(Ssh_gss_buf *mech) { /* Copy constant into mech */ - mech->len = gss_mech_krb5->length; - mech->data = gss_mech_krb5->elements; + mech->length = putty_gss_mech_krb5->length; + mech->value = putty_gss_mech_krb5->elements; return SSH_GSS_OK; } @@ -79,11 +79,11 @@ Ssh_gss_stat ssh_gss_init_sec_context(Ssh_gss_ctx *ctx, GSS_C_NO_CREDENTIAL, &uxctx->ctx, (gss_name_t) srv_name, - (gss_OID) gss_mech_krb5, + (gss_OID) putty_gss_mech_krb5, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | to_deleg, 0, - NULL, /* no channel bindings */ + GSS_C_NO_CHANNEL_BINDINGS, (gss_buffer_desc *)recv_tok, NULL, /* ignore mech type */ (gss_buffer_desc *)send_tok, @@ -108,13 +108,13 @@ Ssh_gss_stat ssh_gss_display_status(Ssh_gss_ctx ctx, Ssh_gss_buf *buf) /* get first mesg from GSS */ ccc=0; - lmax=gss_display_status(&lmin,uxctx->maj_stat,GSS_C_GSS_CODE,(gss_OID) gss_mech_krb5,&ccc,&msg_maj); + lmax=gss_display_status(&lmin,uxctx->maj_stat,GSS_C_GSS_CODE,(gss_OID) putty_gss_mech_krb5,&ccc,&msg_maj); if (lmax != GSS_S_COMPLETE) return SSH_GSS_FAILURE; /* get first mesg from Kerberos */ ccc=0; - lmax=gss_display_status(&lmin,uxctx->min_stat,GSS_C_MECH_CODE,(gss_OID) gss_mech_krb5,&ccc,&msg_min); + lmax=gss_display_status(&lmin,uxctx->min_stat,GSS_C_MECH_CODE,(gss_OID) putty_gss_mech_krb5,&ccc,&msg_min); if (lmax != GSS_S_COMPLETE) { gss_release_buffer(&lmin, &msg_maj); @@ -122,14 +122,14 @@ Ssh_gss_stat ssh_gss_display_status(Ssh_gss_ctx ctx, Ssh_gss_buf *buf) } /* copy data into buffer */ - buf->len = msg_maj.length + msg_min.length + 1; - buf->data = snewn(buf->len + 1, char); + buf->length = msg_maj.length + msg_min.length + 1; + buf->value = snewn(buf->length + 1, char); /* copy mem */ - memcpy(buf->data, msg_maj.value, msg_maj.length); - buf->data[msg_maj.length] = ' '; - memcpy(buf->data + msg_maj.length + 1, msg_min.value, msg_min.length); - buf->data[buf->len] = 0; + memcpy((char *)buf->value, msg_maj.value, msg_maj.length); + ((char *)buf->value)[msg_maj.length] = ' '; + memcpy((char *)buf->value + msg_maj.length + 1, msg_min.value, msg_min.length); + ((char *)buf->value)[buf->length] = 0; /* free mem & exit */ gss_release_buffer(&lmin, &msg_maj); gss_release_buffer(&lmin, &msg_min); diff --git a/windows/wingss.c b/windows/wingss.c index 5cf7e0f9..222b34fa 100644 --- a/windows/wingss.c +++ b/windows/wingss.c @@ -129,8 +129,8 @@ Ssh_gss_stat ssh_gss_init_sec_context(Ssh_gss_ctx *ctx, Ssh_gss_buf *send_tok) { winSsh_gss_ctx *winctx = (winSsh_gss_ctx *) *ctx; - SecBuffer wsend_tok = {send_tok->len,SECBUFFER_TOKEN,send_tok->data}; - SecBuffer wrecv_tok = {recv_tok->len,SECBUFFER_TOKEN,recv_tok->data}; + SecBuffer wsend_tok = {send_tok->length,SECBUFFER_TOKEN,send_tok->value}; + SecBuffer wrecv_tok = {recv_tok->length,SECBUFFER_TOKEN,recv_tok->value}; SecBufferDesc output_desc={SECBUFFER_VERSION,1,&wsend_tok}; SecBufferDesc input_desc ={SECBUFFER_VERSION,1,&wrecv_tok}; unsigned long flags=ISC_REQ_MUTUAL_AUTH|ISC_REQ_REPLAY_DETECT| @@ -154,8 +154,8 @@ Ssh_gss_stat ssh_gss_init_sec_context(Ssh_gss_ctx *ctx, /* prepare for the next round */ winctx->context_handle = &winctx->context; - send_tok->data = (char*) wsend_tok.pvBuffer; - send_tok->len = wsend_tok.cbBuffer; + send_tok->value = wsend_tok.pvBuffer; + send_tok->length = wsend_tok.cbBuffer; /* check & return our status */ if (winctx->maj_stat==SEC_E_OK) return SSH_GSS_S_COMPLETE; @@ -170,8 +170,8 @@ Ssh_gss_stat ssh_gss_free_tok(Ssh_gss_buf *send_tok) if (send_tok == NULL) return SSH_GSS_FAILURE; /* free Windows buffer */ - p_FreeContextBuffer(send_tok->data); - send_tok->len = 0; send_tok->data = NULL; + p_FreeContextBuffer(send_tok->value); + SSH_GSS_CLEAR_BUF(send_tok); return SSH_GSS_OK; } @@ -250,8 +250,8 @@ Ssh_gss_stat ssh_gss_display_status(Ssh_gss_ctx ctx, Ssh_gss_buf *buf) break; } - buf->data = dupstr(msg); - buf->len = strlen(buf->data); + buf->value = dupstr(msg); + buf->length = strlen(buf->length); return SSH_GSS_OK; } @@ -282,8 +282,8 @@ Ssh_gss_stat ssh_gss_get_mic(Ssh_gss_ctx ctx, Ssh_gss_buf *buf, InputBufferDescriptor.pBuffers = InputSecurityToken; InputBufferDescriptor.ulVersion = SECBUFFER_VERSION; InputSecurityToken[0].BufferType = SECBUFFER_DATA; - InputSecurityToken[0].cbBuffer = buf->len; - InputSecurityToken[0].pvBuffer = buf->data; + InputSecurityToken[0].cbBuffer = buf->length; + InputSecurityToken[0].pvBuffer = buf->value; InputSecurityToken[1].BufferType = SECBUFFER_TOKEN; InputSecurityToken[1].cbBuffer = ContextSizes.cbMaxSignature; InputSecurityToken[1].pvBuffer = snewn(ContextSizes.cbMaxSignature, char); @@ -294,8 +294,8 @@ Ssh_gss_stat ssh_gss_get_mic(Ssh_gss_ctx ctx, Ssh_gss_buf *buf, 0); if (winctx->maj_stat == SEC_E_OK) { - hash->len = InputSecurityToken[1].cbBuffer; - hash->data = InputSecurityToken[1].pvBuffer; + hash->length = InputSecurityToken[1].cbBuffer; + hash->value = InputSecurityToken[1].pvBuffer; } return winctx->maj_stat; @@ -303,7 +303,7 @@ Ssh_gss_stat ssh_gss_get_mic(Ssh_gss_ctx ctx, Ssh_gss_buf *buf, Ssh_gss_stat ssh_gss_free_mic(Ssh_gss_buf *hash) { - sfree(hash->data); + sfree(hash->value); return SSH_GSS_OK; } diff --git a/windows/winstuff.h b/windows/winstuff.h index 14e20baa..2846fdf0 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -108,6 +108,18 @@ typedef struct terminal_tag Terminal; typedef HDC Context; +#ifndef NO_GSSAPI +/* + * GSS-API stuff + */ +typedef struct Ssh_gss_buf { + int length; + char *value; +} Ssh_gss_buf; + +#define SSH_GSS_EMPTY_BUF (Ssh_gss_buf) {0,NULL} +#endif + /* * Window handles for the windows that can be running during a * PuTTY session.