]> andersk Git - openssh.git/blobdiff - monitor_wrap.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / monitor_wrap.c
index edf2814e5c04cddc63fd6fc25d635fd8ccf29a55..b8e8710f71f11d9221f78c0a144f36a4f61a007f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.68 2009/06/22 05:39:28 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -40,7 +40,9 @@
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
+#include <openssl/evp.h>
 
+#include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
 #include "ssh.h"
 #include "dh.h"
 #include "atomicio.h"
 #include "monitor_fdpass.h"
 #include "misc.h"
-#include "servconf.h"
+#include "schnorr.h"
+#include "jpake.h"
 
 #include "channels.h"
 #include "session.h"
 #include "servconf.h"
+#include "roaming.h"
 
 /* Imports */
 extern int compat20;
-extern Newkeys *newkeys[];
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern struct monitor *pmonitor;
-extern Buffer input, output;
 extern Buffer loginmsg;
 extern ServerOptions options;
 
@@ -222,8 +224,8 @@ 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, &len);
        if (len != sizeof(struct passwd))
@@ -237,6 +239,7 @@ mm_getpwnamallow(const char *username)
        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))
@@ -505,7 +508,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
        Enc *enc;
        Mac *mac;
        Comp *comp;
-       Newkeys *newkey = newkeys[mode];
+       Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
 
        debug3("%s: converting %p", __func__, newkey);
 
@@ -567,11 +570,11 @@ mm_send_kex(Buffer *m, Kex *kex)
 void
 mm_send_keystate(struct monitor *monitor)
 {
-       Buffer m;
+       Buffer m, *input, *output;
        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);
 
@@ -605,7 +608,8 @@ mm_send_keystate(struct monitor *monitor)
        }
 
        debug3("%s: Sending new keys: %p %p",
-           __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
+           __func__, packet_get_newkeys(MODE_OUT),
+           packet_get_newkeys(MODE_IN));
 
        /* Keys from Kex */
        if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
@@ -620,14 +624,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:
@@ -650,8 +656,16 @@ mm_send_keystate(struct monitor *monitor)
        buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
 
        /* Network I/O buffers */
-       buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
-       buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
+       input = (Buffer *)packet_get_input();
+       output = (Buffer *)packet_get_output();
+       buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
+       buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
+
+       /* Roaming */
+       if (compat20) {
+               buffer_put_int64(&m, get_sent_bytes());
+               buffer_put_int64(&m, get_recv_bytes());
+       }
 
        mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
        debug3("%s: Finished sending state", __func__);
@@ -664,7 +678,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);
@@ -688,8 +715,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);
@@ -708,8 +736,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;
@@ -1237,3 +1266,165 @@ mm_ssh_gssapi_userok(char *user)
        return (authenticated);
 }
 #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 modp_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 modp_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 modp_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 */
This page took 0.056323 seconds and 4 git commands to generate.