X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/30460aeb3d3c027b85eba1e4d45de75fb4b9d356..737cfc81cdff227e301e5415be53a22426f1bf31:/openssh/monitor_wrap.c diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index 6366075..368738f 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.54 2006/08/12 20:46:46 miod Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -40,7 +40,9 @@ #include #include +#include +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "dh.h" @@ -69,10 +71,11 @@ #include "atomicio.h" #include "monitor_fdpass.h" #include "misc.h" -#include "servconf.h" +#include "jpake.h" #include "channels.h" #include "session.h" +#include "servconf.h" /* Imports */ extern int compat20; @@ -207,7 +210,8 @@ mm_getpwnamallow(const char *username) { Buffer m; struct passwd *pw; - u_int pwlen; + u_int len; + ServerOptions *newopts; debug3("%s entering", __func__); @@ -220,11 +224,11 @@ mm_getpwnamallow(const char *username) mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); if (buffer_get_char(&m) == 0) { - buffer_free(&m); - return (NULL); + pw = NULL; + goto out; } - pw = buffer_get_string(&m, &pwlen); - if (pwlen != sizeof(struct passwd)) + pw = buffer_get_string(&m, &len); + if (len != sizeof(struct passwd)) fatal("%s: struct passwd size mismatch", __func__); pw->pw_name = buffer_get_string(&m, NULL); pw->pw_passwd = buffer_get_string(&m, NULL); @@ -234,6 +238,17 @@ mm_getpwnamallow(const char *username) #endif pw->pw_dir = buffer_get_string(&m, NULL); pw->pw_shell = buffer_get_string(&m, NULL); + +out: + /* copy options block as a Match directive may have changed some */ + newopts = buffer_get_string(&m, &len); + if (len != sizeof(*newopts)) + fatal("%s: option block size mismatch", __func__); + if (newopts->banner != NULL) + newopts->banner = buffer_get_string(&m, NULL); + copy_set_server_options(&options, newopts, 1); + xfree(newopts); + buffer_free(&m); return (pw); @@ -464,8 +479,8 @@ mm_newkeys_from_blob(u_char *blob, int blen) /* Mac structure */ mac->name = buffer_get_string(&b, NULL); - if (mac->name == NULL || mac_init(mac, mac->name) == -1) - fatal("%s: can not init mac %s", __func__, mac->name); + if (mac->name == NULL || mac_setup(mac, mac->name) == -1) + fatal("%s: can not setup mac %s", __func__, mac->name); mac->enabled = buffer_get_int(&b); mac->key = buffer_get_string(&b, &len); if (len > mac->key_len) @@ -559,7 +574,7 @@ mm_send_keystate(struct monitor *monitor) u_char *blob, *p; u_int bloblen, plen; u_int32_t seqnr, packets; - u_int64_t blocks; + u_int64_t blocks, bytes; buffer_init(&m); @@ -608,14 +623,16 @@ mm_send_keystate(struct monitor *monitor) buffer_put_string(&m, blob, bloblen); xfree(blob); - packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); + packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); 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_int64(&m, bytes); + packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes); buffer_put_int(&m, seqnr); buffer_put_int64(&m, blocks); buffer_put_int(&m, packets); + buffer_put_int64(&m, bytes); debug3("%s: New keys have been sent", __func__); skip: @@ -652,7 +669,20 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) { Buffer m; char *p, *msg; - int success = 0; + int success = 0, tmp1 = -1, tmp2 = -1; + + /* Kludge: ensure there are fds free to receive the pty/tty */ + if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || + (tmp2 = dup(pmonitor->m_recvfd)) == -1) { + error("%s: cannot allocate fds for pty", __func__); + if (tmp1 > 0) + close(tmp1); + if (tmp2 > 0) + close(tmp2); + return 0; + } + close(tmp1); + close(tmp2); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); @@ -676,8 +706,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) buffer_append(&loginmsg, msg, strlen(msg)); xfree(msg); - *ptyfd = mm_receive_fd(pmonitor->m_recvfd); - *ttyfd = mm_receive_fd(pmonitor->m_recvfd); + if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || + (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) + fatal("%s: receive fds failed", __func__); /* Success */ return (1); @@ -696,8 +727,9 @@ mm_session_pty_cleanup2(Session *s) buffer_free(&m); /* closed dup'ed master */ - if (close(s->ptymaster) < 0) - error("close(s->ptymaster): %s", strerror(errno)); + if (s->ptymaster != -1 && close(s->ptymaster) < 0) + error("close(s->ptymaster/%d): %s", + s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; @@ -1325,3 +1357,165 @@ mm_ssh_gssapi_localname(char **lname) } #endif /* GSSAPI */ + +#ifdef JPAKE +void +mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, + char **hash_scheme, char **salt) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_GET_PWDATA, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_GET_PWDATA, &m); + + *hash_scheme = buffer_get_string(&m, NULL); + *salt = buffer_get_string(&m, NULL); + + buffer_free(&m); +} + +void +mm_jpake_step1(struct jpake_group *grp, + u_char **id, u_int *id_len, + BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, + u_char **priv1_proof, u_int *priv1_proof_len, + u_char **priv2_proof, u_int *priv2_proof_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_STEP1, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_STEP1, &m); + + if ((*priv1 = BN_new()) == NULL || + (*priv2 = BN_new()) == NULL || + (*g_priv1 = BN_new()) == NULL || + (*g_priv2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + *id = buffer_get_string(&m, id_len); + /* priv1 and priv2 are, well, private */ + buffer_get_bignum2(&m, *g_priv1); + buffer_get_bignum2(&m, *g_priv2); + *priv1_proof = buffer_get_string(&m, priv1_proof_len); + *priv2_proof = buffer_get_string(&m, priv2_proof_len); + + buffer_free(&m); +} + +void +mm_jpake_step2(struct jpake_group *grp, BIGNUM *s, + BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, + const u_char *theirid, u_int theirid_len, + const u_char *myid, u_int myid_len, + const u_char *theirpub1_proof, u_int theirpub1_proof_len, + const u_char *theirpub2_proof, u_int theirpub2_proof_len, + BIGNUM **newpub, + u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* monitor already has all bignums except theirpub1, theirpub2 */ + buffer_put_bignum2(&m, theirpub1); + buffer_put_bignum2(&m, theirpub2); + /* monitor already knows our id */ + buffer_put_string(&m, theirid, theirid_len); + buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len); + buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len); + + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_STEP2, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_STEP2, &m); + + if ((*newpub = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + buffer_get_bignum2(&m, *newpub); + *newpub_exponent_proof = buffer_get_string(&m, + newpub_exponent_proof_len); + + buffer_free(&m); +} + +void +mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val, + BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, + BIGNUM *theirpub1, BIGNUM *theirpub2, + const u_char *my_id, u_int my_id_len, + const u_char *their_id, u_int their_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, + BIGNUM **k, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* monitor already has all bignums except step2_val */ + buffer_put_bignum2(&m, step2_val); + /* monitor already knows all the ids */ + buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len); + + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_KEY_CONFIRM, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_KEY_CONFIRM, &m); + + /* 'k' is sensitive and stays in the monitor */ + *confirm_hash = buffer_get_string(&m, confirm_hash_len); + + buffer_free(&m); +} + +int +mm_jpake_check_confirm(const BIGNUM *k, + const u_char *peer_id, u_int peer_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) +{ + Buffer m; + int success = 0; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* k is dummy in slave, ignored */ + /* monitor knows all the ids */ + buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m); + + success = buffer_get_int(&m); + buffer_free(&m); + + debug3("%s: success = %d", __func__, success); + return success; +} +#endif /* JPAKE */