]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ssh.c
merge
[plan9front.git] / sys / src / cmd / ssh.c
index 29d6e2de3e181488b27db8241fb48401266b6fca..239a4f542c2e5d914b5086346311f3029cabaed3 100644 (file)
@@ -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;
@@ -489,7 +489,7 @@ kex(int gotkexinit)
        static char kexalgs[] = "curve25519-sha256,curve25519-sha256@libssh.org";
        static char cipheralgs[] = "chacha20-poly1305@openssh.com";
        static char zipalgs[] = "none";
-       static char macalgs[] = "";
+       static char macalgs[] = "hmac-sha1";    /* work around for github.com */
        static char langs[] = "";
 
        uchar cookie[16], x[32], yc[32], z[32], k[32+1], h[SHA2_256dlen], *ys, *ks, *sig;
@@ -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);
 }
@@ -1203,6 +1213,12 @@ main(int argc, char *argv[])
                MaxPwTries = strtol(EARGF(usage()), &s, 0);
                if(*s != 0) usage();
                break;
+       case 'X':
+               mux = 1;
+               raw = 0;
+               break;
+       default:
+               usage();
        } ARGEND;
 
        if(host == nil){
@@ -1269,9 +1285,12 @@ 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)
+               goto Mux;
 
        /* open hailing frequencies */
        if(remote != nil){
@@ -1295,7 +1314,6 @@ Next0:    switch(recvpkt()){
                        recv.win,
                        recv.pkt);
        }
-
 Next1: switch(recvpkt()){
        default:
                dispatch();
@@ -1313,6 +1331,42 @@ Next1:   switch(recvpkt()){
        if(send.pkt <= 0 || send.pkt > MaxPacket)
                send.pkt = MaxPacket;
 
+       if(remote != nil)
+               goto Mux;
+
+       if(raw) {
+               rawon();
+               sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,
+                       send.chan,
+                       "pty-req", 7,
+                       0,
+                       tty.term, strlen(tty.term),
+                       tty.cols,
+                       tty.lines,
+                       tty.xpixels,
+                       tty.ypixels,
+                       "", 0);
+       }
+       if(cmd == nil){
+               sendpkt("busb", MSG_CHANNEL_REQUEST,
+                       send.chan,
+                       "shell", 5,
+                       0);
+       } else if(*cmd == '#') {
+               sendpkt("busbs", MSG_CHANNEL_REQUEST,
+                       send.chan,
+                       "subsystem", 9,
+                       0,
+                       cmd+1, strlen(cmd)-1);
+       } else {
+               sendpkt("busbs", MSG_CHANNEL_REQUEST,
+                       send.chan,
+                       "exec", 4,
+                       0,
+                       cmd, strlen(cmd));
+       }
+
+Mux:
        notify(catch);
        atexit(shutdown);
 
@@ -1337,39 +1391,6 @@ Next1:   switch(recvpkt()){
 
        /* child reads input and sends packets */
        qlock(&sl);
-       if(remote == nil){
-               if(raw) {
-                       rawon();
-                       sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,
-                               send.chan,
-                               "pty-req", 7,
-                               0,
-                               tty.term, strlen(tty.term),
-                               tty.cols,
-                               tty.lines,
-                               tty.xpixels,
-                               tty.ypixels,
-                               "", 0);
-               }
-               if(cmd == nil){
-                       sendpkt("busb", MSG_CHANNEL_REQUEST,
-                               send.chan,
-                               "shell", 5,
-                               0);
-               } else if(*cmd == '#') {
-                       sendpkt("busbs", MSG_CHANNEL_REQUEST,
-                               send.chan,
-                               "subsystem", 9,
-                               0,
-                               cmd+1, strlen(cmd)-1);
-               } else {
-                       sendpkt("busbs", MSG_CHANNEL_REQUEST,
-                               send.chan,
-                               "exec", 4,
-                               0,
-                               cmd, strlen(cmd));
-               }
-       }
        for(;;){
                static uchar buf[MaxPacket];
                qunlock(&sl);
@@ -1400,6 +1421,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 +1432,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);