version 1.22, 2003/02/16 17:30:33 |
version 1.22.2.2, 2004/03/04 18:18:16 |
|
|
#include "channels.h" |
#include "channels.h" |
#include "session.h" |
#include "session.h" |
|
|
|
#ifdef GSSAPI |
|
#include "ssh-gss.h" |
|
#endif |
|
|
/* Imports */ |
/* Imports */ |
extern int compat20; |
extern int compat20; |
extern Newkeys *newkeys[]; |
extern Newkeys *newkeys[]; |
|
|
extern struct monitor *pmonitor; |
extern struct monitor *pmonitor; |
extern Buffer input, output; |
extern Buffer input, output; |
|
|
|
int |
|
mm_is_monitor(void) |
|
{ |
|
/* |
|
* m_pid is only set in the privileged part, and |
|
* points to the unprivileged child. |
|
*/ |
|
return (pmonitor && pmonitor->m_pid > 0); |
|
} |
|
|
void |
void |
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) |
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) |
{ |
{ |
|
|
|
|
PUT_32BIT(buf, mlen + 1); |
PUT_32BIT(buf, mlen + 1); |
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ |
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ |
if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf)) |
if (atomicio(vwrite, socket, buf, sizeof(buf)) != sizeof(buf)) |
fatal("%s: write", __func__); |
fatal("%s: write", __func__); |
if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen) |
if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen) |
fatal("%s: write", __func__); |
fatal("%s: write", __func__); |
} |
} |
|
|
|
|
res = atomicio(read, socket, buf, sizeof(buf)); |
res = atomicio(read, socket, buf, sizeof(buf)); |
if (res != sizeof(buf)) { |
if (res != sizeof(buf)) { |
if (res == 0) |
if (res == 0) |
fatal_cleanup(); |
cleanup_exit(255); |
fatal("%s: read: %ld", __func__, (long)res); |
fatal("%s: read: %ld", __func__, (long)res); |
} |
} |
msg_len = GET_32BIT(buf); |
msg_len = GET_32BIT(buf); |
|
|
return (pw); |
return (pw); |
} |
} |
|
|
char *mm_auth2_read_banner(void) |
char * |
|
mm_auth2_read_banner(void) |
{ |
{ |
Buffer m; |
Buffer m; |
char *banner; |
char *banner; |
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); |
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); |
buffer_clear(&m); |
buffer_clear(&m); |
|
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m); |
mm_request_receive_expect(pmonitor->m_recvfd, |
|
MONITOR_ANS_AUTH2_READ_BANNER, &m); |
banner = buffer_get_string(&m, NULL); |
banner = buffer_get_string(&m, NULL); |
buffer_free(&m); |
buffer_free(&m); |
|
|
|
/* treat empty banner as missing banner */ |
|
if (strlen(banner) == 0) { |
|
xfree(banner); |
|
banner = NULL; |
|
} |
return (banner); |
return (banner); |
} |
} |
|
|
|
|
Buffer m; |
Buffer m; |
u_char *blob, *p; |
u_char *blob, *p; |
u_int bloblen, plen; |
u_int bloblen, plen; |
|
u_int32_t seqnr, packets; |
|
u_int64_t blocks; |
|
|
buffer_init(&m); |
buffer_init(&m); |
|
|
|
|
buffer_put_string(&m, blob, bloblen); |
buffer_put_string(&m, blob, bloblen); |
xfree(blob); |
xfree(blob); |
|
|
buffer_put_int(&m, packet_get_seqnr(MODE_OUT)); |
packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); |
buffer_put_int(&m, packet_get_seqnr(MODE_IN)); |
buffer_put_int(&m, seqnr); |
|
buffer_put_int64(&m, blocks); |
|
buffer_put_int(&m, packets); |
|
packet_get_state(MODE_IN, &seqnr, &blocks, &packets); |
|
buffer_put_int(&m, seqnr); |
|
buffer_put_int64(&m, blocks); |
|
buffer_put_int(&m, packets); |
|
|
debug3("%s: New keys have been sent", __func__); |
debug3("%s: New keys have been sent", __func__); |
skip: |
skip: |
|
|
} |
} |
|
|
void |
void |
mm_session_pty_cleanup2(void *session) |
mm_session_pty_cleanup2(Session *s) |
{ |
{ |
Session *s = session; |
|
Buffer m; |
Buffer m; |
|
|
if (s->ttyfd == -1) |
if (s->ttyfd == -1) |
|
|
return (success); |
return (success); |
} |
} |
|
|
#ifdef KRB4 |
#ifdef GSSAPI |
int |
OM_uint32 |
mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply) |
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) |
{ |
{ |
KTEXT auth, reply; |
Buffer m; |
Buffer m; |
OM_uint32 major; |
u_int rlen; |
|
int success = 0; |
|
char *p; |
|
|
|
debug3("%s entering", __func__); |
/* Client doesn't get to see the context */ |
auth = _auth; |
*ctx = NULL; |
reply = _reply; |
|
|
|
buffer_init(&m); |
buffer_init(&m); |
buffer_put_string(&m, auth->dat, auth->length); |
buffer_put_string(&m, oid->elements, oid->length); |
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m); |
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); |
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m); |
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); |
|
|
success = buffer_get_int(&m); |
major = buffer_get_int(&m); |
if (success) { |
|
*client = buffer_get_string(&m, NULL); |
|
p = buffer_get_string(&m, &rlen); |
|
if (rlen >= MAX_KTXT_LEN) |
|
fatal("%s: reply from monitor too large", __func__); |
|
reply->length = rlen; |
|
memcpy(reply->dat, p, rlen); |
|
memset(p, 0, rlen); |
|
xfree(p); |
|
} |
|
buffer_free(&m); |
buffer_free(&m); |
return (success); |
return (major); |
} |
} |
#endif |
|
|
|
#ifdef KRB5 |
OM_uint32 |
int |
mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, |
mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) |
gss_buffer_desc *out, OM_uint32 *flags) |
{ |
{ |
krb5_data *tkt, *reply; |
|
Buffer m; |
Buffer m; |
int success; |
OM_uint32 major; |
|
u_int len; |
|
|
debug3("%s entering", __func__); |
buffer_init(&m); |
tkt = (krb5_data *) argp; |
buffer_put_string(&m, in->value, in->length); |
reply = (krb5_data *) resp; |
|
|
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); |
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); |
|
|
|
major = buffer_get_int(&m); |
|
out->value = buffer_get_string(&m, &len); |
|
out->length = len; |
|
if (flags) |
|
*flags = buffer_get_int(&m); |
|
|
|
buffer_free(&m); |
|
|
|
return (major); |
|
} |
|
|
|
OM_uint32 |
|
mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) |
|
{ |
|
Buffer m; |
|
OM_uint32 major; |
|
|
buffer_init(&m); |
buffer_init(&m); |
buffer_put_string(&m, tkt->data, tkt->length); |
buffer_put_string(&m, gssbuf->value, gssbuf->length); |
|
buffer_put_string(&m, gssmic->value, gssmic->length); |
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); |
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); |
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); |
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, |
|
&m); |
|
|
success = buffer_get_int(&m); |
major = buffer_get_int(&m); |
if (success) { |
buffer_free(&m); |
u_int len; |
return(major); |
|
} |
|
|
*userp = buffer_get_string(&m, NULL); |
int |
reply->data = buffer_get_string(&m, &len); |
mm_ssh_gssapi_userok(char *user) |
reply->length = len; |
{ |
} else { |
Buffer m; |
memset(reply, 0, sizeof(*reply)); |
int authenticated = 0; |
*userp = NULL; |
|
} |
|
|
|
|
buffer_init(&m); |
|
|
|
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); |
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, |
|
&m); |
|
|
|
authenticated = buffer_get_int(&m); |
|
|
buffer_free(&m); |
buffer_free(&m); |
return (success); |
debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); |
|
return (authenticated); |
} |
} |
#endif |
#endif /* GSSAPI */ |