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.
This commit is contained in:
parent
ccbffa6731
commit
38c2cdf164
1 changed files with 69 additions and 48 deletions
|
@ -80,7 +80,7 @@ int nsid;
|
|||
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 @@ dispatch(void)
|
|||
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 @@ dispatch(void)
|
|||
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 @@ kfmt(Fmt *f)
|
|||
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 @@ main(int argc, char *argv[])
|
|||
MaxPwTries = strtol(EARGF(usage()), &s, 0);
|
||||
if(*s != 0) usage();
|
||||
break;
|
||||
case 'X':
|
||||
mux = 1;
|
||||
raw = 0;
|
||||
break;
|
||||
} ARGEND;
|
||||
|
||||
if(host == nil){
|
||||
|
@ -1269,10 +1283,11 @@ Next0: switch(recvpkt()){
|
|||
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;
|
||||
|
||||
if(!mux){
|
||||
/* open hailing frequencies */
|
||||
if(remote != nil){
|
||||
NetConnInfo *nci = getnetconninfo(nil, fd);
|
||||
|
@ -1295,7 +1310,6 @@ Next0: switch(recvpkt()){
|
|||
recv.win,
|
||||
recv.pkt);
|
||||
}
|
||||
|
||||
Next1: switch(recvpkt()){
|
||||
default:
|
||||
dispatch();
|
||||
|
@ -1312,6 +1326,7 @@ Next1: switch(recvpkt()){
|
|||
sysfatal("bad channel open confirmation");
|
||||
if(send.pkt <= 0 || send.pkt > MaxPacket)
|
||||
send.pkt = MaxPacket;
|
||||
}
|
||||
|
||||
notify(catch);
|
||||
atexit(shutdown);
|
||||
|
@ -1337,7 +1352,7 @@ Next1: switch(recvpkt()){
|
|||
|
||||
/* 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 @@ Next1: switch(recvpkt()){
|
|||
}
|
||||
if(n <= 0)
|
||||
break;
|
||||
if(mux){
|
||||
sendpkt("[", buf, n);
|
||||
continue;
|
||||
}
|
||||
send.win -= n;
|
||||
while(send.win < 0)
|
||||
rsleep(&send);
|
||||
|
@ -1407,8 +1426,10 @@ Next1: switch(recvpkt()){
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue