changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: ssh: add experimental mux mode

changeset 7115: ff3d2ba9517a
parent 7114: 5502ebdaef11
child 7116: 17daf6d05444
author: cinap_lenrek@felloff.net
date: Tue, 02 Apr 2019 11:18:50 +0200
files: sys/src/cmd/ssh.c
description: ssh: add experimental mux mode

in mux mode, ssh relays raw MSG_CHANNEL_*
messages on standard input and output while
still handling authentication and key exchange
internally.

the intend is to use the mux mode to implement
something like the old sshnet ontop of ssh.
     1.1--- a/sys/src/cmd/ssh.c
     1.2+++ b/sys/src/cmd/ssh.c
     1.3@@ -80,7 +80,7 @@ int nsid;
     1.4 uchar sid[256];
     1.5 char thumb[2*SHA2_256dlen+1], *thumbfile;
     1.6 
     1.7-int fd, intr, raw, port, debug;
     1.8+int fd, intr, raw, port, mux, debug;
     1.9 char *user, *service, *status, *host, *remote, *cmd;
    1.10 
    1.11 Oneway recv, send;
    1.12@@ -987,6 +987,19 @@ dispatch(void)
    1.13 			break;
    1.14 		if(raw) write(2, s, n);
    1.15 		return;
    1.16+	case MSG_KEXINIT:
    1.17+		kex(1);
    1.18+		return;
    1.19+	}
    1.20+
    1.21+	if(mux){
    1.22+		n = recv.w - recv.r;
    1.23+		if(write(1, recv.r, n) != n)
    1.24+			sysfatal("write out: %r");
    1.25+		return;
    1.26+	}
    1.27+
    1.28+	switch(recv.r[0]){
    1.29 	case MSG_CHANNEL_DATA:
    1.30 		if(unpack(recv.r, recv.w-recv.r, "_us", &c, &s, &n) < 0)
    1.31 			break;
    1.32@@ -1051,9 +1064,6 @@ dispatch(void)
    1.33 	case MSG_CHANNEL_CLOSE:
    1.34 		shutdown();
    1.35 		return;
    1.36-	case MSG_KEXINIT:
    1.37-		kex(1);
    1.38-		return;
    1.39 	}
    1.40 	sysfatal("got: %.*H", (int)(recv.w - recv.r), recv.r);
    1.41 }
    1.42@@ -1147,7 +1157,7 @@ kfmt(Fmt *f)
    1.43 void
    1.44 usage(void)
    1.45 {
    1.46-	fprint(2, "usage: %s [-dR] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [-W remote!port] [cmd args...]\n", argv0);
    1.47+	fprint(2, "usage: %s [-dRX] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [-W remote!port] [cmd args...]\n", argv0);
    1.48 	exits("usage");
    1.49 }
    1.50 
    1.51@@ -1203,6 +1213,10 @@ main(int argc, char *argv[])
    1.52 		MaxPwTries = strtol(EARGF(usage()), &s, 0);
    1.53 		if(*s != 0) usage();
    1.54 		break;
    1.55+	case 'X':
    1.56+		mux = 1;
    1.57+		raw = 0;
    1.58+		break;
    1.59 	} ARGEND;
    1.60 
    1.61 	if(host == nil){
    1.62@@ -1269,50 +1283,51 @@ Next0:	switch(recvpkt()){
    1.63 	if(noneauth() < 0 && pubkeyauth() < 0 && passauth() < 0 && kbintauth() < 0)
    1.64 		sysfatal("auth: %r");
    1.65 
    1.66-	recv.pkt = MaxPacket;
    1.67-	recv.win = WinPackets*recv.pkt;
    1.68-	recv.chan = 0;
    1.69+	recv.pkt = send.pkt = MaxPacket;
    1.70+	recv.win = send.win =  WinPackets*recv.pkt;
    1.71+	recv.chan = send.win = 0;
    1.72 
    1.73-	/* open hailing frequencies */
    1.74-	if(remote != nil){
    1.75-		NetConnInfo *nci = getnetconninfo(nil, fd);
    1.76-		if(nci == nil)
    1.77-			sysfatal("can't get netconninfo: %r");
    1.78-		sendpkt("bsuuususu", MSG_CHANNEL_OPEN,
    1.79-			"direct-tcpip", 12,
    1.80-			recv.chan,
    1.81-			recv.win,
    1.82-			recv.pkt,
    1.83-			remote, strlen(remote),
    1.84-			port,
    1.85-			nci->laddr, strlen(nci->laddr),
    1.86-			atoi(nci->lserv));
    1.87-		free(nci);
    1.88-	} else {
    1.89-		sendpkt("bsuuu", MSG_CHANNEL_OPEN,
    1.90-			"session", 7,
    1.91-			recv.chan,
    1.92-			recv.win,
    1.93-			recv.pkt);
    1.94+	if(!mux){
    1.95+		/* open hailing frequencies */
    1.96+		if(remote != nil){
    1.97+			NetConnInfo *nci = getnetconninfo(nil, fd);
    1.98+			if(nci == nil)
    1.99+				sysfatal("can't get netconninfo: %r");
   1.100+			sendpkt("bsuuususu", MSG_CHANNEL_OPEN,
   1.101+				"direct-tcpip", 12,
   1.102+				recv.chan,
   1.103+				recv.win,
   1.104+				recv.pkt,
   1.105+				remote, strlen(remote),
   1.106+				port,
   1.107+				nci->laddr, strlen(nci->laddr),
   1.108+				atoi(nci->lserv));
   1.109+			free(nci);
   1.110+		} else {
   1.111+			sendpkt("bsuuu", MSG_CHANNEL_OPEN,
   1.112+				"session", 7,
   1.113+				recv.chan,
   1.114+				recv.win,
   1.115+				recv.pkt);
   1.116+		}
   1.117+Next1:		switch(recvpkt()){
   1.118+		default:
   1.119+			dispatch();
   1.120+			goto Next1;
   1.121+		case MSG_CHANNEL_OPEN_FAILURE:
   1.122+			if(unpack(recv.r, recv.w-recv.r, "_uus", &c, &b, &s, &n) < 0)
   1.123+				n = strlen(s = "???");
   1.124+			sysfatal("channel open failure: (%d) %.*s", b, utfnlen(s, n), s);
   1.125+		case MSG_CHANNEL_OPEN_CONFIRMATION:
   1.126+			break;
   1.127+		}
   1.128+
   1.129+		if(unpack(recv.r, recv.w-recv.r, "_uuuu", &recv.chan, &send.chan, &send.win, &send.pkt) < 0)
   1.130+			sysfatal("bad channel open confirmation");
   1.131+		if(send.pkt <= 0 || send.pkt > MaxPacket)
   1.132+			send.pkt = MaxPacket;
   1.133 	}
   1.134 
   1.135-Next1:	switch(recvpkt()){
   1.136-	default:
   1.137-		dispatch();
   1.138-		goto Next1;
   1.139-	case MSG_CHANNEL_OPEN_FAILURE:
   1.140-		if(unpack(recv.r, recv.w-recv.r, "_uus", &c, &b, &s, &n) < 0)
   1.141-			n = strlen(s = "???");
   1.142-		sysfatal("channel open failure: (%d) %.*s", b, utfnlen(s, n), s);
   1.143-	case MSG_CHANNEL_OPEN_CONFIRMATION:
   1.144-		break;
   1.145-	}
   1.146-
   1.147-	if(unpack(recv.r, recv.w-recv.r, "_uuuu", &recv.chan, &send.chan, &send.win, &send.pkt) < 0)
   1.148-		sysfatal("bad channel open confirmation");
   1.149-	if(send.pkt <= 0 || send.pkt > MaxPacket)
   1.150-		send.pkt = MaxPacket;
   1.151-
   1.152 	notify(catch);
   1.153 	atexit(shutdown);
   1.154 
   1.155@@ -1337,7 +1352,7 @@ Next1:	switch(recvpkt()){
   1.156 
   1.157 	/* child reads input and sends packets */
   1.158 	qlock(&sl);
   1.159-	if(remote == nil){
   1.160+	if(remote == nil && !mux){
   1.161 		if(raw) {
   1.162 			rawon();
   1.163 			sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,
   1.164@@ -1400,6 +1415,10 @@ Next1:	switch(recvpkt()){
   1.165 		}
   1.166 		if(n <= 0)
   1.167 			break;
   1.168+		if(mux){
   1.169+			sendpkt("[", buf, n);
   1.170+			continue;
   1.171+		}
   1.172 		send.win -= n;
   1.173 		while(send.win < 0)
   1.174 			rsleep(&send);
   1.175@@ -1407,8 +1426,10 @@ Next1:	switch(recvpkt()){
   1.176 			send.chan,
   1.177 			buf, n);
   1.178 	}
   1.179-	if(send.eof++ == 0)
   1.180+	if(send.eof++ == 0 && !mux)
   1.181 		sendpkt("bu", raw ? MSG_CHANNEL_CLOSE : MSG_CHANNEL_EOF, send.chan);
   1.182+	else if(recv.pid > 0 && mux)
   1.183+		postnote(PNPROC, recv.pid, "shutdown");
   1.184 	qunlock(&sl);
   1.185 
   1.186 	exits(nil);