version 1.49, 2003/08/28 12:54:34 |
version 1.49.2.2, 2004/08/19 22:37:31 |
|
|
#include "bufaux.h" |
#include "bufaux.h" |
#include "compat.h" |
#include "compat.h" |
#include "ssh2.h" |
#include "ssh2.h" |
#include "mpaux.h" |
|
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
#include "ssh-gss.h" |
#include "ssh-gss.h" |
|
|
extern Buffer input, output; |
extern Buffer input, output; |
extern Buffer auth_debug; |
extern Buffer auth_debug; |
extern int auth_debug_init; |
extern int auth_debug_init; |
|
extern Buffer loginmsg; |
|
|
/* State exported from the child */ |
/* State exported from the child */ |
|
|
|
|
int mm_answer_gss_setup_ctx(int, Buffer *); |
int mm_answer_gss_setup_ctx(int, Buffer *); |
int mm_answer_gss_accept_ctx(int, Buffer *); |
int mm_answer_gss_accept_ctx(int, Buffer *); |
int mm_answer_gss_userok(int, Buffer *); |
int mm_answer_gss_userok(int, Buffer *); |
|
int mm_answer_gss_checkmic(int, Buffer *); |
#endif |
#endif |
|
|
static Authctxt *authctxt; |
static Authctxt *authctxt; |
|
|
{MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, |
{MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, |
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, |
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, |
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
|
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
#endif |
#endif |
{0, 0, NULL} |
{0, 0, NULL} |
}; |
}; |
|
|
} |
} |
} |
} |
|
|
Authctxt * |
void |
monitor_child_preauth(struct monitor *pmonitor) |
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) |
{ |
{ |
struct mon_table *ent; |
struct mon_table *ent; |
int authenticated = 0; |
int authenticated = 0; |
|
|
debug3("preauth child monitor started"); |
debug3("preauth child monitor started"); |
|
|
|
authctxt = _authctxt; |
|
memset(authctxt, 0, sizeof(*authctxt)); |
|
|
if (compat20) { |
if (compat20) { |
mon_dispatch = mon_dispatch_proto20; |
mon_dispatch = mon_dispatch_proto20; |
|
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); |
} |
} |
|
|
authctxt = authctxt_new(); |
|
|
|
/* The first few requests do not require asynchronous access */ |
/* The first few requests do not require asynchronous access */ |
while (!authenticated) { |
while (!authenticated) { |
authenticated = monitor_read(pmonitor, mon_dispatch, &ent); |
authenticated = monitor_read(pmonitor, mon_dispatch, &ent); |
|
|
__func__, authctxt->user); |
__func__, authctxt->user); |
|
|
mm_get_keystate(pmonitor); |
mm_get_keystate(pmonitor); |
|
|
return (authctxt); |
|
} |
} |
|
|
static void |
static void |
|
|
} |
} |
|
|
static void |
static void |
monitor_child_handler(int signal) |
monitor_child_handler(int sig) |
{ |
{ |
kill(monitor_child_pid, signal); |
kill(monitor_child_pid, sig); |
} |
} |
|
|
void |
void |
|
|
} |
} |
|
|
int |
int |
mm_answer_moduli(int socket, Buffer *m) |
mm_answer_moduli(int sock, Buffer *m) |
{ |
{ |
DH *dh; |
DH *dh; |
int min, want, max; |
int min, want, max; |
|
|
|
|
DH_free(dh); |
DH_free(dh); |
} |
} |
mm_request_send(socket, MONITOR_ANS_MODULI, m); |
mm_request_send(sock, MONITOR_ANS_MODULI, m); |
return (0); |
return (0); |
} |
} |
|
|
int |
int |
mm_answer_sign(int socket, Buffer *m) |
mm_answer_sign(int sock, Buffer *m) |
{ |
{ |
Key *key; |
Key *key; |
u_char *p; |
u_char *p; |
|
|
xfree(p); |
xfree(p); |
xfree(signature); |
xfree(signature); |
|
|
mm_request_send(socket, MONITOR_ANS_SIGN, m); |
mm_request_send(sock, MONITOR_ANS_SIGN, m); |
|
|
/* Turn on permissions for getpwnam */ |
/* Turn on permissions for getpwnam */ |
monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); |
|
|
/* Retrieves the password entry and also checks if the user is permitted */ |
/* Retrieves the password entry and also checks if the user is permitted */ |
|
|
int |
int |
mm_answer_pwnamallow(int socket, Buffer *m) |
mm_answer_pwnamallow(int sock, Buffer *m) |
{ |
{ |
char *login; |
char *username; |
struct passwd *pwent; |
struct passwd *pwent; |
int allowed = 0; |
int allowed = 0; |
|
|
|
|
if (authctxt->attempt++ != 0) |
if (authctxt->attempt++ != 0) |
fatal("%s: multiple attempts for getpwnam", __func__); |
fatal("%s: multiple attempts for getpwnam", __func__); |
|
|
login = buffer_get_string(m, NULL); |
username = buffer_get_string(m, NULL); |
|
|
pwent = getpwnamallow(login); |
pwent = getpwnamallow(username); |
|
|
authctxt->user = xstrdup(login); |
authctxt->user = xstrdup(username); |
setproctitle("%s [priv]", pwent ? login : "unknown"); |
setproctitle("%s [priv]", pwent ? username : "unknown"); |
xfree(login); |
xfree(username); |
|
|
buffer_clear(m); |
buffer_clear(m); |
|
|
if (pwent == NULL) { |
if (pwent == NULL) { |
buffer_put_char(m, 0); |
buffer_put_char(m, 0); |
|
authctxt->pw = fakepw(); |
goto out; |
goto out; |
} |
} |
|
|
|
|
|
|
out: |
out: |
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
mm_request_send(socket, MONITOR_ANS_PWNAM, m); |
mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
|
|
/* For SSHv1 allow authentication now */ |
/* For SSHv1 allow authentication now */ |
if (!compat20) |
if (!compat20) |
|
|
return (0); |
return (0); |
} |
} |
|
|
int mm_answer_auth2_read_banner(int socket, Buffer *m) |
int mm_answer_auth2_read_banner(int sock, Buffer *m) |
{ |
{ |
char *banner; |
char *banner; |
|
|
buffer_clear(m); |
buffer_clear(m); |
banner = auth2_read_banner(); |
banner = auth2_read_banner(); |
buffer_put_cstring(m, banner != NULL ? banner : ""); |
buffer_put_cstring(m, banner != NULL ? banner : ""); |
mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); |
mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); |
|
|
if (banner != NULL) |
if (banner != NULL) |
xfree(banner); |
xfree(banner); |
|
|
} |
} |
|
|
int |
int |
mm_answer_authserv(int socket, Buffer *m) |
mm_answer_authserv(int sock, Buffer *m) |
{ |
{ |
monitor_permit_authentications(1); |
monitor_permit_authentications(1); |
|
|
|
|
} |
} |
|
|
int |
int |
mm_answer_authpassword(int socket, Buffer *m) |
mm_answer_authpassword(int sock, Buffer *m) |
{ |
{ |
static int call_count; |
static int call_count; |
char *passwd; |
char *passwd; |
|
|
buffer_put_int(m, authenticated); |
buffer_put_int(m, authenticated); |
|
|
debug3("%s: sending result %d", __func__, authenticated); |
debug3("%s: sending result %d", __func__, authenticated); |
mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m); |
mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); |
|
|
call_count++; |
call_count++; |
if (plen == 0 && call_count == 1) |
if (plen == 0 && call_count == 1) |
|
|
|
|
#ifdef BSD_AUTH |
#ifdef BSD_AUTH |
int |
int |
mm_answer_bsdauthquery(int socket, Buffer *m) |
mm_answer_bsdauthquery(int sock, Buffer *m) |
{ |
{ |
char *name, *infotxt; |
char *name, *infotxt; |
u_int numprompts; |
u_int numprompts; |
|
|
buffer_put_cstring(m, prompts[0]); |
buffer_put_cstring(m, prompts[0]); |
|
|
debug3("%s: sending challenge success: %u", __func__, success); |
debug3("%s: sending challenge success: %u", __func__, success); |
mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m); |
mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); |
|
|
if (success) { |
if (success) { |
xfree(name); |
xfree(name); |
|
|
} |
} |
|
|
int |
int |
mm_answer_bsdauthrespond(int socket, Buffer *m) |
mm_answer_bsdauthrespond(int sock, Buffer *m) |
{ |
{ |
char *response; |
char *response; |
int authok; |
int authok; |
|
|
buffer_put_int(m, authok); |
buffer_put_int(m, authok); |
|
|
debug3("%s: sending authenticated: %d", __func__, authok); |
debug3("%s: sending authenticated: %d", __func__, authok); |
mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m); |
mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); |
|
|
auth_method = "bsdauth"; |
auth_method = "bsdauth"; |
|
|
|
|
|
|
#ifdef SKEY |
#ifdef SKEY |
int |
int |
mm_answer_skeyquery(int socket, Buffer *m) |
mm_answer_skeyquery(int sock, Buffer *m) |
{ |
{ |
struct skey skey; |
struct skey skey; |
char challenge[1024]; |
char challenge[1024]; |
|
|
buffer_put_cstring(m, challenge); |
buffer_put_cstring(m, challenge); |
|
|
debug3("%s: sending challenge success: %u", __func__, success); |
debug3("%s: sending challenge success: %u", __func__, success); |
mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); |
mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); |
|
|
return (0); |
return (0); |
} |
} |
|
|
int |
int |
mm_answer_skeyrespond(int socket, Buffer *m) |
mm_answer_skeyrespond(int sock, Buffer *m) |
{ |
{ |
char *response; |
char *response; |
int authok; |
int authok; |
|
|
buffer_put_int(m, authok); |
buffer_put_int(m, authok); |
|
|
debug3("%s: sending authenticated: %d", __func__, authok); |
debug3("%s: sending authenticated: %d", __func__, authok); |
mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m); |
mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); |
|
|
auth_method = "skey"; |
auth_method = "skey"; |
|
|
|
|
} |
} |
|
|
int |
int |
mm_answer_keyallowed(int socket, Buffer *m) |
mm_answer_keyallowed(int sock, Buffer *m) |
{ |
{ |
Key *key; |
Key *key; |
char *cuser, *chost; |
char *cuser, *chost; |
|
|
|
|
debug3("%s: key_from_blob: %p", __func__, key); |
debug3("%s: key_from_blob: %p", __func__, key); |
|
|
if (key != NULL && authctxt->pw != NULL) { |
if (key != NULL && authctxt->valid) { |
switch(type) { |
switch(type) { |
case MM_USERKEY: |
case MM_USERKEY: |
allowed = options.pubkey_authentication && |
allowed = options.pubkey_authentication && |
|
|
|
|
mm_append_debug(m); |
mm_append_debug(m); |
|
|
mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m); |
mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
|
|
if (type == MM_RSAHOSTKEY) |
if (type == MM_RSAHOSTKEY) |
monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); |
monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); |
|
|
} |
} |
|
|
int |
int |
mm_answer_keyverify(int socket, Buffer *m) |
mm_answer_keyverify(int sock, Buffer *m) |
{ |
{ |
Key *key; |
Key *key; |
u_char *signature, *data, *blob; |
u_char *signature, *data, *blob; |
|
|
|
|
buffer_clear(m); |
buffer_clear(m); |
buffer_put_int(m, verified); |
buffer_put_int(m, verified); |
mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m); |
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); |
|
|
return (verified); |
return (verified); |
} |
} |
|
|
if (getpeername(packet_get_connection_in(), |
if (getpeername(packet_get_connection_in(), |
(struct sockaddr *) & from, &fromlen) < 0) { |
(struct sockaddr *) & from, &fromlen) < 0) { |
debug("getpeername: %.100s", strerror(errno)); |
debug("getpeername: %.100s", strerror(errno)); |
fatal_cleanup(); |
cleanup_exit(255); |
} |
} |
} |
} |
/* Record that there was a login on that tty from the remote host. */ |
/* Record that there was a login on that tty from the remote host. */ |
|
|
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); |
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); |
if (s->ttyfd != -1) { |
if (s->ttyfd != -1) { |
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); |
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); |
fatal_remove_cleanup(session_pty_cleanup2, (void *)s); |
|
session_pty_cleanup2(s); |
session_pty_cleanup2(s); |
} |
} |
s->used = 0; |
s->used = 0; |
} |
} |
|
|
int |
int |
mm_answer_pty(int socket, Buffer *m) |
mm_answer_pty(int sock, Buffer *m) |
{ |
{ |
extern struct monitor *pmonitor; |
extern struct monitor *pmonitor; |
Session *s; |
Session *s; |
|
|
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); |
if (res == 0) |
if (res == 0) |
goto error; |
goto error; |
fatal_add_cleanup(session_pty_cleanup2, (void *)s); |
|
pty_setowner(authctxt->pw, s->tty); |
pty_setowner(authctxt->pw, s->tty); |
|
|
buffer_put_int(m, 1); |
buffer_put_int(m, 1); |
buffer_put_cstring(m, s->tty); |
buffer_put_cstring(m, s->tty); |
mm_request_send(socket, MONITOR_ANS_PTY, m); |
|
|
|
mm_send_fd(socket, s->ptyfd); |
|
mm_send_fd(socket, s->ttyfd); |
|
|
|
/* We need to trick ttyslot */ |
/* We need to trick ttyslot */ |
if (dup2(s->ttyfd, 0) == -1) |
if (dup2(s->ttyfd, 0) == -1) |
fatal("%s: dup2", __func__); |
fatal("%s: dup2", __func__); |
|
|
/* Now we can close the file descriptor again */ |
/* Now we can close the file descriptor again */ |
close(0); |
close(0); |
|
|
|
/* send messages generated by record_login */ |
|
buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); |
|
buffer_clear(&loginmsg); |
|
|
|
mm_request_send(sock, MONITOR_ANS_PTY, m); |
|
|
|
mm_send_fd(sock, s->ptyfd); |
|
mm_send_fd(sock, s->ttyfd); |
|
|
/* make sure nothing uses fd 0 */ |
/* make sure nothing uses fd 0 */ |
if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) |
if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) |
fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); |
fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); |
|
|
if (s != NULL) |
if (s != NULL) |
mm_session_close(s); |
mm_session_close(s); |
buffer_put_int(m, 0); |
buffer_put_int(m, 0); |
mm_request_send(socket, MONITOR_ANS_PTY, m); |
mm_request_send(sock, MONITOR_ANS_PTY, m); |
return (0); |
return (0); |
} |
} |
|
|
int |
int |
mm_answer_pty_cleanup(int socket, Buffer *m) |
mm_answer_pty_cleanup(int sock, Buffer *m) |
{ |
{ |
Session *s; |
Session *s; |
char *tty; |
char *tty; |
|
|
} |
} |
|
|
int |
int |
mm_answer_sesskey(int socket, Buffer *m) |
mm_answer_sesskey(int sock, Buffer *m) |
{ |
{ |
BIGNUM *p; |
BIGNUM *p; |
int rsafail; |
int rsafail; |
|
|
|
|
BN_clear_free(p); |
BN_clear_free(p); |
|
|
mm_request_send(socket, MONITOR_ANS_SESSKEY, m); |
mm_request_send(sock, MONITOR_ANS_SESSKEY, m); |
|
|
/* Turn on permissions for sessid passing */ |
/* Turn on permissions for sessid passing */ |
monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); |
|
|
} |
} |
|
|
int |
int |
mm_answer_sessid(int socket, Buffer *m) |
mm_answer_sessid(int sock, Buffer *m) |
{ |
{ |
int i; |
int i; |
|
|
|
|
} |
} |
|
|
int |
int |
mm_answer_rsa_keyallowed(int socket, Buffer *m) |
mm_answer_rsa_keyallowed(int sock, Buffer *m) |
{ |
{ |
BIGNUM *client_n; |
BIGNUM *client_n; |
Key *key = NULL; |
Key *key = NULL; |
|
|
|
|
mm_append_debug(m); |
mm_append_debug(m); |
|
|
mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m); |
mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); |
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); |
monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); |
monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); |
monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); |
|
|
} |
} |
|
|
int |
int |
mm_answer_rsa_challenge(int socket, Buffer *m) |
mm_answer_rsa_challenge(int sock, Buffer *m) |
{ |
{ |
Key *key = NULL; |
Key *key = NULL; |
u_char *blob; |
u_char *blob; |
|
|
buffer_put_bignum2(m, ssh1_challenge); |
buffer_put_bignum2(m, ssh1_challenge); |
|
|
debug3("%s sending reply", __func__); |
debug3("%s sending reply", __func__); |
mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m); |
mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); |
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); |
|
|
|
|
} |
} |
|
|
int |
int |
mm_answer_rsa_response(int socket, Buffer *m) |
mm_answer_rsa_response(int sock, Buffer *m) |
{ |
{ |
Key *key = NULL; |
Key *key = NULL; |
u_char *blob, *response; |
u_char *blob, *response; |
|
|
|
|
buffer_clear(m); |
buffer_clear(m); |
buffer_put_int(m, success); |
buffer_put_int(m, success); |
mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m); |
mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); |
|
|
return (success); |
return (success); |
} |
} |
|
|
int |
int |
mm_answer_term(int socket, Buffer *req) |
mm_answer_term(int sock, Buffer *req) |
{ |
{ |
extern struct monitor *pmonitor; |
extern struct monitor *pmonitor; |
int res, status; |
int res, status; |
|
|
res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; |
res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; |
|
|
/* Terminate process */ |
/* Terminate process */ |
exit (res); |
exit(res); |
} |
} |
|
|
void |
void |
|
|
fatal("mm_get_get: internal error: bad session id"); |
fatal("mm_get_get: internal error: bad session id"); |
kex->we_need = buffer_get_int(m); |
kex->we_need = buffer_get_int(m); |
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; |
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; |
|
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; |
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
kex->server = 1; |
kex->server = 1; |
kex->hostkey_type = buffer_get_int(m); |
kex->hostkey_type = buffer_get_int(m); |
|
|
|
|
mon = xmalloc(sizeof(*mon)); |
mon = xmalloc(sizeof(*mon)); |
|
|
|
mon->m_pid = 0; |
monitor_socketpair(pair); |
monitor_socketpair(pair); |
|
|
mon->m_recvfd = pair[0]; |
mon->m_recvfd = pair[0]; |
|
|
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int |
int |
mm_answer_gss_setup_ctx(int socket, Buffer *m) |
mm_answer_gss_setup_ctx(int sock, Buffer *m) |
{ |
{ |
gss_OID_desc oid; |
gss_OID_desc goid; |
OM_uint32 major; |
OM_uint32 major; |
u_int len; |
u_int len; |
|
|
oid.elements = buffer_get_string(m, &len); |
goid.elements = buffer_get_string(m, &len); |
oid.length = len; |
goid.length = len; |
|
|
major = ssh_gssapi_server_ctx(&gsscontext, &oid); |
major = ssh_gssapi_server_ctx(&gsscontext, &goid); |
|
|
xfree(oid.elements); |
xfree(goid.elements); |
|
|
buffer_clear(m); |
buffer_clear(m); |
buffer_put_int(m, major); |
buffer_put_int(m, major); |
|
|
mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); |
mm_request_send(sock,MONITOR_ANS_GSSSETUP, m); |
|
|
/* Now we have a context, enable the step */ |
/* Now we have a context, enable the step */ |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); |
|
|
} |
} |
|
|
int |
int |
mm_answer_gss_accept_ctx(int socket, Buffer *m) |
mm_answer_gss_accept_ctx(int sock, Buffer *m) |
{ |
{ |
gss_buffer_desc in; |
gss_buffer_desc in; |
gss_buffer_desc out = GSS_C_EMPTY_BUFFER; |
gss_buffer_desc out = GSS_C_EMPTY_BUFFER; |
|
|
buffer_put_int(m, major); |
buffer_put_int(m, major); |
buffer_put_string(m, out.value, out.length); |
buffer_put_string(m, out.value, out.length); |
buffer_put_int(m, flags); |
buffer_put_int(m, flags); |
mm_request_send(socket, MONITOR_ANS_GSSSTEP, m); |
mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); |
|
|
gss_release_buffer(&minor, &out); |
gss_release_buffer(&minor, &out); |
|
|
/* Complete - now we can do signing */ |
|
if (major==GSS_S_COMPLETE) { |
if (major==GSS_S_COMPLETE) { |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
|
monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); |
} |
} |
return (0); |
return (0); |
} |
} |
|
|
int |
int |
mm_answer_gss_userok(int socket, Buffer *m) |
mm_answer_gss_checkmic(int sock, Buffer *m) |
{ |
{ |
|
gss_buffer_desc gssbuf, mic; |
|
OM_uint32 ret; |
|
u_int len; |
|
|
|
gssbuf.value = buffer_get_string(m, &len); |
|
gssbuf.length = len; |
|
mic.value = buffer_get_string(m, &len); |
|
mic.length = len; |
|
|
|
ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); |
|
|
|
xfree(gssbuf.value); |
|
xfree(mic.value); |
|
|
|
buffer_clear(m); |
|
buffer_put_int(m, ret); |
|
|
|
mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); |
|
|
|
if (!GSS_ERROR(ret)) |
|
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
|
|
|
return (0); |
|
} |
|
|
|
int |
|
mm_answer_gss_userok(int sock, Buffer *m) |
|
{ |
int authenticated; |
int authenticated; |
|
|
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); |
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); |
|
|
buffer_put_int(m, authenticated); |
buffer_put_int(m, authenticated); |
|
|
debug3("%s: sending result %d", __func__, authenticated); |
debug3("%s: sending result %d", __func__, authenticated); |
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); |
mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); |
|
|
auth_method="gssapi"; |
auth_method="gssapi-with-mic"; |
|
|
/* Monitor loop will terminate if authenticated */ |
/* Monitor loop will terminate if authenticated */ |
return (authenticated); |
return (authenticated); |