Module Name:    src
Committed By:   pooka
Date:           Thu Dec 16 17:05:45 UTC 2010

Modified Files:
        src/lib/librumpclient: rumpclient.c
        src/lib/librumpuser: rumpuser_sp.c sp_common.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.26 -r1.27 src/lib/librumpuser/rumpuser_sp.c
cvs rdiff -u -r1.16 -r1.17 src/lib/librumpuser/sp_common.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpclient/rumpclient.c
diff -u src/lib/librumpclient/rumpclient.c:1.9 src/lib/librumpclient/rumpclient.c:1.10
--- src/lib/librumpclient/rumpclient.c:1.9	Thu Dec 16 12:38:21 2010
+++ src/lib/librumpclient/rumpclient.c	Thu Dec 16 17:05:44 2010
@@ -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,19 +265,10 @@
 		return -1;
 	}
 
-	if ((error = parsetab[idx].connhook(s)) != 0) {
-		error = errno;
-		fprintf(stderr, "rump_sp: connect hook failed\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) {
+		error = errno;
 		fprintf(stderr, "rump_sp: failed to read banner\n");
+		errno = error;
 		return -1;
 	}
 
@@ -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;
 }

Index: src/lib/librumpuser/rumpuser_sp.c
diff -u src/lib/librumpuser/rumpuser_sp.c:1.26 src/lib/librumpuser/rumpuser_sp.c:1.27
--- src/lib/librumpuser/rumpuser_sp.c:1.26	Thu Dec 16 12:38:20 2010
+++ src/lib/librumpuser/rumpuser_sp.c	Thu Dec 16 17:05:44 2010
@@ -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);

Index: src/lib/librumpuser/sp_common.c
diff -u src/lib/librumpuser/sp_common.c:1.16 src/lib/librumpuser/sp_common.c:1.17
--- src/lib/librumpuser/sp_common.c:1.16	Thu Dec 16 12:38:20 2010
+++ src/lib/librumpuser/sp_common.c	Thu Dec 16 17:05:44 2010
@@ -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;
 }

Reply via email to