version 1.26, 2017/06/24 06:34:38 |
version 1.27, 2018/07/09 21:37:55 |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
|
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "key.h" |
#include "sshkey.h" |
#include "hostfile.h" |
#include "hostfile.h" |
#include "auth.h" |
#include "auth.h" |
#include "ssh2.h" |
#include "ssh2.h" |
#include "log.h" |
#include "log.h" |
#include "dispatch.h" |
#include "dispatch.h" |
#include "buffer.h" |
#include "sshbuf.h" |
|
#include "ssherr.h" |
#include "servconf.h" |
#include "servconf.h" |
#include "packet.h" |
#include "packet.h" |
#include "ssh-gss.h" |
#include "ssh-gss.h" |
|
|
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
gss_OID_desc goid = {0, NULL}; |
gss_OID_desc goid = {0, NULL}; |
Gssctxt *ctxt = NULL; |
Gssctxt *ctxt = NULL; |
int mechs; |
int r, present; |
int present; |
u_int mechs; |
OM_uint32 ms; |
OM_uint32 ms; |
u_int len; |
size_t len; |
u_char *doid = NULL; |
u_char *doid = NULL; |
|
|
if (!authctxt->valid || authctxt->user == NULL) |
if (!authctxt->valid || authctxt->user == NULL) |
return (0); |
return (0); |
|
|
mechs = packet_get_int(); |
if ((r = sshpkt_get_u32(ssh, &mechs)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
if (mechs == 0) { |
if (mechs == 0) { |
debug("Mechanism negotiation is not supported"); |
debug("Mechanism negotiation is not supported"); |
return (0); |
return (0); |
|
|
free(doid); |
free(doid); |
|
|
present = 0; |
present = 0; |
doid = packet_get_string(&len); |
if ((r = sshpkt_get_string(ssh, &doid, &len)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && |
if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && |
doid[1] == len - 2) { |
doid[1] == len - 2) { |
|
|
|
|
authctxt->methoddata = (void *)ctxt; |
authctxt->methoddata = (void *)ctxt; |
|
|
packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); |
|
|
|
/* Return the OID that we received */ |
/* Return the OID that we received */ |
packet_put_string(doid, len); |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE)) != 0 || |
|
(r = sshpkt_put_string(ssh, doid, len)) != 0 || |
|
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
packet_send(); |
|
free(doid); |
free(doid); |
|
|
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); |
|
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
gss_buffer_desc recv_tok; |
gss_buffer_desc recv_tok; |
OM_uint32 maj_status, min_status, flags; |
OM_uint32 maj_status, min_status, flags; |
u_int len; |
u_char *p; |
|
size_t len; |
|
int r; |
|
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
fatal("No authentication or GSSAPI context"); |
fatal("No authentication or GSSAPI context"); |
|
|
gssctxt = authctxt->methoddata; |
gssctxt = authctxt->methoddata; |
recv_tok.value = packet_get_string(&len); |
if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 || |
recv_tok.length = len; /* u_int vs. size_t */ |
(r = sshpkt_get_end(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
packet_check_eom(); |
recv_tok.value = p; |
|
recv_tok.length = len; |
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
&send_tok, &flags)); |
&send_tok, &flags)); |
|
|
free(recv_tok.value); |
free(p); |
|
|
if (GSS_ERROR(maj_status)) { |
if (GSS_ERROR(maj_status)) { |
if (send_tok.length != 0) { |
if (send_tok.length != 0) { |
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); |
if ((r = sshpkt_start(ssh, |
packet_put_string(send_tok.value, send_tok.length); |
SSH2_MSG_USERAUTH_GSSAPI_ERRTOK)) != 0 || |
packet_send(); |
(r = sshpkt_put_string(ssh, send_tok.value, |
|
send_tok.length)) != 0 || |
|
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
} |
} |
authctxt->postponed = 0; |
authctxt->postponed = 0; |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
userauth_finish(ssh, 0, "gssapi-with-mic", NULL); |
userauth_finish(ssh, 0, "gssapi-with-mic", NULL); |
} else { |
} else { |
if (send_tok.length != 0) { |
if (send_tok.length != 0) { |
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); |
if ((r = sshpkt_start(ssh, |
packet_put_string(send_tok.value, send_tok.length); |
SSH2_MSG_USERAUTH_GSSAPI_TOKEN)) != 0 || |
packet_send(); |
(r = sshpkt_put_string(ssh, send_tok.value, |
|
send_tok.length)) != 0 || |
|
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
} |
} |
if (maj_status == GSS_S_COMPLETE) { |
if (maj_status == GSS_S_COMPLETE) { |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); |
|
|
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; |
gss_buffer_desc recv_tok; |
gss_buffer_desc recv_tok; |
OM_uint32 maj_status; |
OM_uint32 maj_status; |
u_int len; |
int r; |
|
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
fatal("No authentication or GSSAPI context"); |
fatal("No authentication or GSSAPI context"); |
|
|
gssctxt = authctxt->methoddata; |
gssctxt = authctxt->methoddata; |
recv_tok.value = packet_get_string(&len); |
if ((r = sshpkt_get_string(ssh, |
recv_tok.length = len; |
&recv_tok.value, &recv_tok.length)) != 0 || |
|
(r = sshpkt_get_end(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
packet_check_eom(); |
|
|
|
/* Push the error token into GSSAPI to see what it says */ |
/* Push the error token into GSSAPI to see what it says */ |
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, |
&send_tok, NULL)); |
&send_tok, NULL)); |
|
|
* the dispatcher once the exchange is complete |
* the dispatcher once the exchange is complete |
*/ |
*/ |
|
|
packet_check_eom(); |
if ((r = sshpkt_get_end(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
|
|
|
|
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
Gssctxt *gssctxt; |
Gssctxt *gssctxt; |
int authenticated = 0; |
int r, authenticated = 0; |
Buffer b; |
struct sshbuf *b; |
gss_buffer_desc mic, gssbuf; |
gss_buffer_desc mic, gssbuf; |
u_int len; |
|
const char *displayname; |
const char *displayname; |
|
|
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) |
|
|
|
|
gssctxt = authctxt->methoddata; |
gssctxt = authctxt->methoddata; |
|
|
mic.value = packet_get_string(&len); |
if ((r = sshpkt_get_string(ssh, &mic.value, &mic.length)) != 0) |
mic.length = len; |
fatal("%s: %s", __func__, ssh_err(r)); |
|
if ((b = sshbuf_new()) == NULL) |
ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, |
fatal("%s: sshbuf_new failed", __func__); |
|
ssh_gssapi_buildmic(b, authctxt->user, authctxt->service, |
"gssapi-with-mic"); |
"gssapi-with-mic"); |
|
|
gssbuf.value = buffer_ptr(&b); |
if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL) |
gssbuf.length = buffer_len(&b); |
fatal("%s: sshbuf_mutable_ptr failed", __func__); |
|
gssbuf.length = sshbuf_len(b); |
|
|
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) |
if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) |
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); |
else |
else |
logit("GSSAPI MIC check failed"); |
logit("GSSAPI MIC check failed"); |
|
|
buffer_free(&b); |
sshbuf_free(b); |
free(mic.value); |
free(mic.value); |
|
|
if ((!use_privsep || mm_is_monitor()) && |
if ((!use_privsep || mm_is_monitor()) && |