Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib Have the client and server perform some sort of handshak...



details:   https://anonhg.NetBSD.org/src/rev/45f58de3cdcb
branches:  trunk
changeset: 759782:45f58de3cdcb
user:      pooka <pooka%NetBSD.org@localhost>
date:      Thu Dec 16 17:05:44 2010 +0000

description:
Have the client and server perform some sort of handshake first.
It's pretty much a placeholder for now.  One plan for the future
is to require some sort of authentication for superuser clients.
The code will need a little massage then, though, to prevent DoS
attacks.

diffstat:

 lib/librumpclient/rumpclient.c |  65 +++++++++++++++++++++++++++++++++--------
 lib/librumpuser/rumpuser_sp.c  |  49 +++++++++++++++++++++++++++---
 lib/librumpuser/sp_common.c    |  22 ++++++++++---
 3 files changed, 111 insertions(+), 25 deletions(-)

diffs (280 lines):

diff -r 112059144b1e -r 45f58de3cdcb lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c    Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpclient/rumpclient.c    Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.9 2010/12/16 12:38:21 pooka Exp $    */
+/*      $NetBSD: rumpclient.c,v 1.10 2010/12/16 17:05:44 pooka Exp $   */
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -87,6 +87,36 @@
 }
 
 static int
+handshake_req(struct spclient *spc)
+{
+       struct rsp_hdr rhdr;
+       struct respwait rw;
+       int rv;
+
+       /* performs server handshake */
+       rhdr.rsp_len = sizeof(rhdr);
+       rhdr.rsp_class = RUMPSP_REQ;
+       rhdr.rsp_type = RUMPSP_HANDSHAKE;
+       rhdr.rsp_handshake = HANDSHAKE_GUEST;
+
+       putwait(spc, &rw, &rhdr);
+       rv = dosend(spc, &rhdr, sizeof(rhdr));
+       if (rv != 0) {
+               unputwait(spc, &rw);
+               return rv;
+       }
+
+       rv = waitresp(spc, &rw);
+       if (rv)
+               return rv;
+
+       rv = *(int *)rw.rw_data;
+       free(rw.rw_data);
+
+       return rv;
+}
+
+static int
 send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen,
        int wantstr)
 {
@@ -235,21 +265,12 @@
                return -1;
        }
 
-       if ((error = parsetab[idx].connhook(s)) != 0) {
+       if ((n = read(s, banner, sizeof(banner)-1)) < 0) {
                error = errno;
-               fprintf(stderr, "rump_sp: connect hook failed\n");
+               fprintf(stderr, "rump_sp: failed to read banner\n");
                errno = error;
                return -1;
        }
-       clispc.spc_fd = s;
-       TAILQ_INIT(&clispc.spc_respwait);
-       pthread_mutex_init(&clispc.spc_mtx, NULL);
-       pthread_cond_init(&clispc.spc_cv, NULL);
-
-       if ((n = read(s, banner, sizeof(banner)-1)) < 0) {
-               fprintf(stderr, "rump_sp: failed to read banner\n");
-               return -1;
-       }
 
        if (banner[n-1] != '\n') {
                fprintf(stderr, "rump_sp: invalid banner\n");
@@ -260,5 +281,23 @@
 
        /* parse the banner some day */
 
-       return 0;
+       if ((error = parsetab[idx].connhook(s)) != 0) {
+               error = errno;
+               fprintf(stderr, "rump_sp: connect hook failed\n");
+               errno = error;
+               return -1;
+       }
+
+       pthread_mutex_init(&clispc.spc_mtx, NULL);
+       pthread_cond_init(&clispc.spc_cv, NULL);
+       clispc.spc_fd = s;
+       TAILQ_INIT(&clispc.spc_respwait);
+
+       error = handshake_req(&clispc);
+       if (error) {
+               pthread_mutex_destroy(&clispc.spc_mtx);
+               pthread_cond_destroy(&clispc.spc_cv);
+               close(s);
+       }
+       return error;
 }
diff -r 112059144b1e -r 45f58de3cdcb lib/librumpuser/rumpuser_sp.c
--- a/lib/librumpuser/rumpuser_sp.c     Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpuser/rumpuser_sp.c     Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_sp.c,v 1.26 2010/12/16 12:38:20 pooka Exp $  */
+/*      $NetBSD: rumpuser_sp.c,v 1.27 2010/12/16 17:05:44 pooka Exp $  */
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_sp.c,v 1.26 2010/12/16 12:38:20 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_sp.c,v 1.27 2010/12/16 17:05:44 pooka Exp $");
 
 #include <sys/types.h>
 #include <sys/atomic.h>
@@ -198,6 +198,26 @@
 }
 
 static int
+send_handshake_resp(struct spclient *spc, uint64_t reqno, int error)
+{
+       struct rsp_hdr rhdr;
+       int rv;
+
+       rhdr.rsp_len = sizeof(rhdr) + sizeof(error);
+       rhdr.rsp_reqno = reqno;
+       rhdr.rsp_class = RUMPSP_RESP;
+       rhdr.rsp_type = RUMPSP_HANDSHAKE;
+       rhdr.rsp_error = 0;
+
+       sendlock(spc);
+       rv = dosend(spc, &rhdr, sizeof(rhdr));
+       rv = dosend(spc, &error, sizeof(error));
+       sendunlock(spc);
+
+       return rv;
+}
+
+static int
 send_syscall_resp(struct spclient *spc, uint64_t reqno, int error,
        register_t *retval)
 {
@@ -355,7 +375,7 @@
 
        close(spc->spc_fd);
        spc->spc_fd = -1;
-       spc->spc_dying = 0;
+       spc->spc_state = SPCSTATE_NEW;
 
        atomic_inc_uint(&disco);
 }
@@ -370,7 +390,7 @@
        pfdlist[idx].fd = -1;
        pfdlist[idx].revents = 0;
        pthread_mutex_lock(&spc->spc_mtx);
-       spc->spc_dying = 1;
+       spc->spc_state = SPCSTATE_DYING;
        kickall(spc);
        pthread_mutex_unlock(&spc->spc_mtx);
 
@@ -439,7 +459,7 @@
 
        /* find empty slot the simple way */
        for (i = 0; i < MAXCLI; i++) {
-               if (pfdlist[i].fd == -1 && spclist[i].spc_dying == 0)
+               if (pfdlist[i].fd == -1 && spclist[i].spc_state == SPCSTATE_NEW)
                        break;
        }
 
@@ -647,7 +667,24 @@
 {
        struct sysbouncearg *sba;
        pthread_t pt;
-       int retries;
+       int retries, rv;
+
+       if (__predict_false(spc->spc_state == SPCSTATE_NEW)) {
+               if (spc->spc_hdr.rsp_type != RUMPSP_HANDSHAKE) {
+                       send_error_resp(spc, spc->spc_hdr.rsp_reqno, EAUTH);
+                       spcfreebuf(spc);
+                       return;
+               }
+
+               rv = send_handshake_resp(spc, spc->spc_hdr.rsp_reqno, 0);
+               spcfreebuf(spc);
+               if (rv) {
+                       shutdown(spc->spc_fd, SHUT_RDWR);
+                       return;
+               }
+               spc->spc_state = SPCSTATE_RUNNING;
+               return;
+       }
 
        if (__predict_false(spc->spc_hdr.rsp_type != RUMPSP_SYSCALL)) {
                send_error_resp(spc, spc->spc_hdr.rsp_reqno, EINVAL);
diff -r 112059144b1e -r 45f58de3cdcb lib/librumpuser/sp_common.c
--- a/lib/librumpuser/sp_common.c       Thu Dec 16 16:59:05 2010 +0000
+++ b/lib/librumpuser/sp_common.c       Thu Dec 16 17:05:44 2010 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: sp_common.c,v 1.16 2010/12/16 12:38:20 pooka Exp $    */
+/*      $NetBSD: sp_common.c,v 1.17 2010/12/16 17:05:44 pooka Exp $    */
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -76,11 +76,14 @@
  */
 
 enum { RUMPSP_REQ, RUMPSP_RESP, RUMPSP_ERROR };
-enum { RUMPSP_SYSCALL,
+enum { RUMPSP_HANDSHAKE,
+       RUMPSP_SYSCALL,
        RUMPSP_COPYIN, RUMPSP_COPYINSTR,
        RUMPSP_COPYOUT, RUMPSP_COPYOUTSTR,
        RUMPSP_ANONMMAP };
 
+enum { HANDSHAKE_GUEST, HANDSHAKE_AUTH }; /* more to come */
+
 struct rsp_hdr {
        uint64_t rsp_len;
        uint64_t rsp_reqno;
@@ -93,11 +96,13 @@
        union {
                uint32_t sysnum;
                uint32_t error;
+               uint32_t handshake;
        } u;
 };
 #define HDRSZ sizeof(struct rsp_hdr)
 #define rsp_sysnum u.sysnum
 #define rsp_error u.error
+#define rsp_handshake u.handshake
 
 #define MAXBANNER 96
 
@@ -132,7 +137,7 @@
 struct spclient {
        int spc_fd;
        int spc_refcnt;
-       int spc_dying;
+       int spc_state;
 
        pthread_mutex_t spc_mtx;
        pthread_cond_t spc_cv;
@@ -157,6 +162,10 @@
 #define SPCSTATUS_BUSY 1
 #define SPCSTATUS_WANTED 2
 
+#define SPCSTATE_NEW     0
+#define SPCSTATE_RUNNING 1
+#define SPCSTATE_DYING   2
+
 typedef int (*addrparse_fn)(const char *, struct sockaddr **, int);
 typedef int (*connecthook_fn)(int);
 typedef void (*cleanup_fn)(struct sockaddr *);
@@ -334,7 +343,8 @@
        sendunlockl(spc);
 
        rw->rw_error = 0;
-       while (rw->rw_data == NULL && rw->rw_error == 0 && spc->spc_dying == 0){
+       while (rw->rw_data == NULL && rw->rw_error == 0
+           && spc->spc_state != SPCSTATE_DYING){
                /* are we free to receive? */
                if (spc->spc_istatus == SPCSTATUS_FREE) {
                        int gotresp;
@@ -352,7 +362,7 @@
                                        continue;
                                case -1:
                                        rv = errno;
-                                       spc->spc_dying = 1;
+                                       spc->spc_state = SPCSTATE_DYING;
                                        goto cleanup;
                                default:
                                        break;
@@ -391,7 +401,7 @@
 
        if (rv)
                return rv;
-       if (spc->spc_dying)
+       if (spc->spc_state == SPCSTATE_DYING)
                return ENOTCONN;
        return rw->rw_error;
 }



Home | Main Index | Thread Index | Old Index