ref: 7a5848e93ff47ccd5a750c2fa13480a5c343b03b
parent: 6ece1185b548d01c3617bf372ed47e4fe2a82333
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Apr 2 07:18:50 EDT 2019
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.
--- a/sys/src/cmd/ssh.c
+++ b/sys/src/cmd/ssh.c
@@ -80,7 +80,7 @@
uchar sid[256];
char thumb[2*SHA2_256dlen+1], *thumbfile;
-int fd, intr, raw, port, debug;
+int fd, intr, raw, port, mux, debug;
char *user, *service, *status, *host, *remote, *cmd;
Oneway recv, send;
@@ -987,6 +987,19 @@
break;
if(raw) write(2, s, n);
return;
+ case MSG_KEXINIT:
+ kex(1);
+ return;
+ }
+
+ if(mux){+ n = recv.w - recv.r;
+ if(write(1, recv.r, n) != n)
+ sysfatal("write out: %r");+ return;
+ }
+
+ switch(recv.r[0]){case MSG_CHANNEL_DATA:
if(unpack(recv.r, recv.w-recv.r, "_us", &c, &s, &n) < 0)
break;
@@ -1051,9 +1064,6 @@
case MSG_CHANNEL_CLOSE:
shutdown();
return;
- case MSG_KEXINIT:
- kex(1);
- return;
}
sysfatal("got: %.*H", (int)(recv.w - recv.r), recv.r);}
@@ -1147,7 +1157,7 @@
void
usage(void)
{- fprint(2, "usage: %s [-dR] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [-W remote!port] [cmd args...]\n", argv0);
+ fprint(2, "usage: %s [-dRX] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [-W remote!port] [cmd args...]\n", argv0);
exits("usage");}
@@ -1203,6 +1213,10 @@
MaxPwTries = strtol(EARGF(usage()), &s, 0);
if(*s != 0) usage();
break;
+ case 'X':
+ mux = 1;
+ raw = 0;
+ break;
} ARGEND;
if(host == nil){@@ -1269,50 +1283,51 @@
if(noneauth() < 0 && pubkeyauth() < 0 && passauth() < 0 && kbintauth() < 0)
sysfatal("auth: %r");- recv.pkt = MaxPacket;
- recv.win = WinPackets*recv.pkt;
- recv.chan = 0;
+ recv.pkt = send.pkt = MaxPacket;
+ recv.win = send.win = WinPackets*recv.pkt;
+ recv.chan = send.win = 0;
- /* open hailing frequencies */
- if(remote != nil){- NetConnInfo *nci = getnetconninfo(nil, fd);
- if(nci == nil)
- sysfatal("can't get netconninfo: %r");- sendpkt("bsuuususu", MSG_CHANNEL_OPEN,- "direct-tcpip", 12,
- recv.chan,
- recv.win,
- recv.pkt,
- remote, strlen(remote),
- port,
- nci->laddr, strlen(nci->laddr),
- atoi(nci->lserv));
- free(nci);
- } else {- sendpkt("bsuuu", MSG_CHANNEL_OPEN,- "session", 7,
- recv.chan,
- recv.win,
- recv.pkt);
- }
+ if(!mux){+ /* open hailing frequencies */
+ if(remote != nil){+ NetConnInfo *nci = getnetconninfo(nil, fd);
+ if(nci == nil)
+ sysfatal("can't get netconninfo: %r");+ sendpkt("bsuuususu", MSG_CHANNEL_OPEN,+ "direct-tcpip", 12,
+ recv.chan,
+ recv.win,
+ recv.pkt,
+ remote, strlen(remote),
+ port,
+ nci->laddr, strlen(nci->laddr),
+ atoi(nci->lserv));
+ free(nci);
+ } else {+ sendpkt("bsuuu", MSG_CHANNEL_OPEN,+ "session", 7,
+ recv.chan,
+ recv.win,
+ recv.pkt);
+ }
+Next1: switch(recvpkt()){+ default:
+ dispatch();
+ goto Next1;
+ case MSG_CHANNEL_OPEN_FAILURE:
+ if(unpack(recv.r, recv.w-recv.r, "_uus", &c, &b, &s, &n) < 0)
+ n = strlen(s = "???");
+ sysfatal("channel open failure: (%d) %.*s", b, utfnlen(s, n), s);+ case MSG_CHANNEL_OPEN_CONFIRMATION:
+ break;
+ }
-Next1: switch(recvpkt()){- default:
- dispatch();
- goto Next1;
- case MSG_CHANNEL_OPEN_FAILURE:
- if(unpack(recv.r, recv.w-recv.r, "_uus", &c, &b, &s, &n) < 0)
- n = strlen(s = "???");
- sysfatal("channel open failure: (%d) %.*s", b, utfnlen(s, n), s);- case MSG_CHANNEL_OPEN_CONFIRMATION:
- break;
+ if(unpack(recv.r, recv.w-recv.r, "_uuuu", &recv.chan, &send.chan, &send.win, &send.pkt) < 0)
+ sysfatal("bad channel open confirmation");+ if(send.pkt <= 0 || send.pkt > MaxPacket)
+ send.pkt = MaxPacket;
}
- if(unpack(recv.r, recv.w-recv.r, "_uuuu", &recv.chan, &send.chan, &send.win, &send.pkt) < 0)
- sysfatal("bad channel open confirmation");- if(send.pkt <= 0 || send.pkt > MaxPacket)
- send.pkt = MaxPacket;
-
notify(catch);
atexit(shutdown);
@@ -1337,7 +1352,7 @@
/* child reads input and sends packets */
qlock(&sl);
- if(remote == nil){+ if(remote == nil && !mux){ if(raw) {rawon();
sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,@@ -1400,6 +1415,10 @@
}
if(n <= 0)
break;
+ if(mux){+ sendpkt("[", buf, n);+ continue;
+ }
send.win -= n;
while(send.win < 0)
rsleep(&send);
@@ -1407,8 +1426,10 @@
send.chan,
buf, n);
}
- if(send.eof++ == 0)
+ if(send.eof++ == 0 && !mux)
sendpkt("bu", raw ? MSG_CHANNEL_CLOSE : MSG_CHANNEL_EOF, send.chan);+ else if(recv.pid > 0 && mux)
+ postnote(PNPROC, recv.pid, "shutdown");
qunlock(&sl);
exits(nil);
--
⑨