diff options
author | khm <devnull@localhost> | 2017-01-12 16:36:38 -0800 |
---|---|---|
committer | khm <devnull@localhost> | 2017-01-12 16:36:38 -0800 |
commit | dc8c7bf2b73d608ac2483aee303a51a3507b4c5a (patch) | |
tree | f8c69dbf5f36de6f9acea724f2068054b5b8e7a6 /sys/src/cmd/ssh/ssh.c | |
parent | cb1555c7d741fa482c339aa9ac8a44753e2ad296 (diff) |
ssh: R.I.P.
Diffstat (limited to 'sys/src/cmd/ssh/ssh.c')
-rw-r--r-- | sys/src/cmd/ssh/ssh.c | 592 |
1 files changed, 0 insertions, 592 deletions
diff --git a/sys/src/cmd/ssh/ssh.c b/sys/src/cmd/ssh/ssh.c deleted file mode 100644 index 83a2751e6..000000000 --- a/sys/src/cmd/ssh/ssh.c +++ /dev/null @@ -1,592 +0,0 @@ -#include "ssh.h" - -int cooked = 0; /* user wants cooked mode */ -int raw = 0; /* console is in raw mode */ -int crstrip; -int interactive = -1; -int usemenu = 1; -int isatty(int); -int rawhack; -int forwardagent = 0; -char *buildcmd(int, char**); -void fromnet(Conn*); -void fromstdin(Conn*); -void winchanges(Conn*); -static void sendwritemsg(Conn *c, char *buf, int n); - -Cipher *allcipher[] = { - &cipherrc4, - &cipherblowfish, - &cipher3des, - &cipherdes, - &ciphernone, - &ciphertwiddle, -}; - -Auth *allauth[] = { - &authpassword, - &authrsa, - &authtis, -}; - -char *cipherlist = "blowfish rc4 3des"; -char *authlist = "rsa password tis"; - -Cipher* -findcipher(char *name, Cipher **list, int nlist) -{ - int i; - - for(i=0; i<nlist; i++) - if(strcmp(name, list[i]->name) == 0) - return list[i]; - error("unknown cipher %s", name); - return nil; -} - -Auth* -findauth(char *name, Auth **list, int nlist) -{ - int i; - - for(i=0; i<nlist; i++) - if(strcmp(name, list[i]->name) == 0) - return list[i]; - error("unknown auth %s", name); - return nil; -} - -void -usage(void) -{ - fprint(2, "usage: ssh [-CiImPpRr] [-A authlist] [-c cipherlist] [user@]hostname [cmd [args]]\n"); - exits("usage"); -} - -void -main(int argc, char **argv) -{ - int i, dowinchange, fd, usepty; - char *host, *cmd, *user, *p; - char *f[16]; - Conn c; - Msg *m; - - fmtinstall('B', mpfmt); - fmtinstall('H', encodefmt); - atexit(atexitkiller); - atexitkill(getpid()); - - dowinchange = 0; - if(getenv("LINES")) - dowinchange = 1; - usepty = -1; - user = nil; - ARGBEGIN{ - case 'B': /* undocumented, debugging */ - doabort = 1; - break; - case 'D': /* undocumented, debugging */ - debuglevel = strtol(EARGF(usage()), nil, 0); - break; - case 'l': /* deprecated */ - case 'u': - user = EARGF(usage()); - break; - case 'a': /* used by Unix scp implementations; we must ignore them. */ - case 'x': - break; - - case 'A': - authlist = EARGF(usage()); - break; - case 'C': - cooked = 1; - break; - case 'c': - cipherlist = EARGF(usage()); - break; - case 'f': - forwardagent = 1; - break; - case 'I': - interactive = 0; - break; - case 'i': - interactive = 1; - break; - case 'm': - usemenu = 0; - break; - case 'P': - usepty = 0; - break; - case 'p': - usepty = 1; - break; - case 'R': - rawhack = 1; - break; - case 'r': - crstrip = 1; - break; - default: - usage(); - }ARGEND - - if(argc < 1) - usage(); - - host = argv[0]; - - cmd = nil; - if(argc > 1) - cmd = buildcmd(argc-1, argv+1); - - if((p = strchr(host, '@')) != nil){ - *p++ = '\0'; - user = host; - host = p; - } - if(user == nil) - user = getenv("user"); - if(user == nil) - sysfatal("cannot find user name"); - - privatefactotum(); - if(interactive==-1) - interactive = isatty(0); - - if((fd = dial(netmkaddr(host, "tcp", "ssh"), nil, nil, nil)) < 0) - sysfatal("dialing %s: %r", host); - - memset(&c, 0, sizeof c); - c.interactive = interactive; - c.fd[0] = c.fd[1] = fd; - c.user = user; - c.host = host; - setaliases(&c, host); - - c.nokcipher = getfields(cipherlist, f, nelem(f), 1, ", "); - c.okcipher = emalloc(sizeof(Cipher*)*c.nokcipher); - for(i=0; i<c.nokcipher; i++) - c.okcipher[i] = findcipher(f[i], allcipher, nelem(allcipher)); - - c.nokauth = getfields(authlist, f, nelem(f), 1, ", "); - c.okauth = emalloc(sizeof(Auth*)*c.nokauth); - for(i=0; i<c.nokauth; i++) - c.okauth[i] = findauth(f[i], allauth, nelem(allauth)); - - sshclienthandshake(&c); - - if(forwardagent){ - if(startagent(&c) < 0) - forwardagent = 0; - } - if(usepty == -1) - usepty = cmd==nil; - if(usepty) - requestpty(&c); - if(cmd){ - m = allocmsg(&c, SSH_CMSG_EXEC_CMD, 4+strlen(cmd)); - putstring(m, cmd); - }else - m = allocmsg(&c, SSH_CMSG_EXEC_SHELL, 0); - sendmsg(m); - - fromstdin(&c); - rfork(RFNOTEG); /* only fromstdin gets notes */ - if(dowinchange) - winchanges(&c); - fromnet(&c); - exits(0); -} - -int -isatty(int fd) -{ - char buf[64]; - - buf[0] = '\0'; - fd2path(fd, buf, sizeof buf); - if(strlen(buf)>=9 && strcmp(buf+strlen(buf)-9, "/dev/cons")==0) - return 1; - return 0; -} - -char* -buildcmd(int argc, char **argv) -{ - int i, len; - char *s, *t; - - len = argc-1; - for(i=0; i<argc; i++) - len += strlen(argv[i]); - s = emalloc(len+1); - t = s; - for(i=0; i<argc; i++){ - if(i) - *t++ = ' '; - strcpy(t, argv[i]); - t += strlen(t); - } - return s; -} - -void -fromnet(Conn *c) -{ - int fd, len; - char *s, *es, *r, *w; - ulong ex; - char buf[64]; - Msg *m; - - for(;;){ - m = recvmsg(c, -1); - if(m == nil) - break; - switch(m->type){ - default: - badmsg(m, 0); - - case SSH_SMSG_EXITSTATUS: - ex = getlong(m); - if(ex==0) - exits(0); - sprint(buf, "%lud", ex); - exits(buf); - - case SSH_MSG_DISCONNECT: - s = getstring(m); - error("disconnect: %s", s); - - /* - * If we ever add reverse port forwarding, we'll have to - * revisit this. It assumes that the agent connections are - * the only ones. - */ - case SSH_SMSG_AGENT_OPEN: - if(!forwardagent) - error("server tried to use agent forwarding"); - handleagentopen(m); - break; - case SSH_MSG_CHANNEL_INPUT_EOF: - if(!forwardagent) - error("server tried to use agent forwarding"); - handleagentieof(m); - break; - case SSH_MSG_CHANNEL_OUTPUT_CLOSED: - if(!forwardagent) - error("server tried to use agent forwarding"); - handleagentoclose(m); - break; - case SSH_MSG_CHANNEL_DATA: - if(!forwardagent) - error("server tried to use agent forwarding"); - handleagentmsg(m); - break; - - case SSH_SMSG_STDOUT_DATA: - fd = 1; - goto Dataout; - case SSH_SMSG_STDERR_DATA: - fd = 2; - goto Dataout; - Dataout: - len = getlong(m); - s = (char*)getbytes(m, len); - if(crstrip){ - es = s+len; - for(r=w=s; r<es; r++) - if(*r != '\r') - *w++ = *r; - len = w-s; - } - write(fd, s, len); - break; - } - free(m); - } -} - -/* - * Lifted from telnet.c, con.c - */ - -static int consctl = -1; -static int outfd1=1, outfd2=2; /* changed during system */ -static void system(Conn*, char*); - -/* - * turn keyboard raw mode on - */ -static void -rawon(void) -{ - if(raw) - return; - if(cooked) - return; - if(consctl < 0) - consctl = open("/dev/consctl", OWRITE); - if(consctl < 0) - return; - if(write(consctl, "rawon", 5) != 5) - return; - raw = 1; -} - -/* - * turn keyboard raw mode off - */ -static void -rawoff(void) -{ - if(raw == 0) - return; - if(consctl < 0) - return; - if(write(consctl, "rawoff", 6) != 6) - return; - close(consctl); - consctl = -1; - raw = 0; -} - -/* - * control menu - */ -#define STDHELP "\t(q)uit, (i)nterrupt, toggle printing (r)eturns, (.)continue, (!cmd)\n" - -static int -menu(Conn *c) -{ - char buf[1024]; - long n; - int done; - int wasraw; - - wasraw = raw; - if(wasraw) - rawoff(); - - buf[0] = '?'; - fprint(2, ">>> "); - for(done = 0; !done; ){ - n = read(0, buf, sizeof(buf)-1); - if(n <= 0) - return -1; - buf[n] = 0; - switch(buf[0]){ - case '!': - print(buf); - system(c, buf+1); - print("!\n"); - done = 1; - break; - case 'i': - buf[0] = 0x1c; - sendwritemsg(c, buf, 1); - done = 1; - break; - case '.': - case 'q': - done = 1; - break; - case 'r': - crstrip = 1-crstrip; - done = 1; - break; - default: - fprint(2, STDHELP); - break; - } - if(!done) - fprint(2, ">>> "); - } - - if(wasraw) - rawon(); - else - rawoff(); - return buf[0]; -} - -static void -sendwritemsg(Conn *c, char *buf, int n) -{ - Msg *m; - - if(n==0) - m = allocmsg(c, SSH_CMSG_EOF, 0); - else{ - m = allocmsg(c, SSH_CMSG_STDIN_DATA, 4+n); - putlong(m, n); - putbytes(m, buf, n); - } - sendmsg(m); -} - -/* - * run a command with the network connection as standard IO - */ -static void -system(Conn *c, char *cmd) -{ - int pid; - int p; - int pfd[2]; - int n; - int wasconsctl; - char buf[4096]; - - if(pipe(pfd) < 0){ - perror("pipe"); - return; - } - outfd1 = outfd2 = pfd[1]; - - wasconsctl = consctl; - close(consctl); - consctl = -1; - switch(pid = fork()){ - case -1: - perror("con"); - return; - case 0: - close(pfd[1]); - dup(pfd[0], 0); - dup(pfd[0], 1); - close(c->fd[0]); /* same as c->fd[1] */ - close(pfd[0]); - if(*cmd) - execl("/bin/rc", "rc", "-c", cmd, nil); - else - execl("/bin/rc", "rc", nil); - perror("con"); - exits("exec"); - break; - default: - close(pfd[0]); - while((n = read(pfd[1], buf, sizeof(buf))) > 0) - sendwritemsg(c, buf, n); - p = waitpid(); - outfd1 = 1; - outfd2 = 2; - close(pfd[1]); - if(p < 0 || p != pid) - return; - break; - } - if(wasconsctl >= 0){ - consctl = open("/dev/consctl", OWRITE); - if(consctl < 0) - error("cannot open consctl"); - } -} - -static void -cookedcatchint(void*, char *msg) -{ - if(strstr(msg, "interrupt")) - noted(NCONT); - else if(strstr(msg, "kill")) - noted(NDFLT); - else - noted(NCONT); -} - -static int -wasintr(void) -{ - char err[64]; - - rerrstr(err, sizeof err); - return strstr(err, "interrupt") != 0; -} - -void -fromstdin(Conn *c) -{ - int n; - char buf[1024]; - int pid; - int eofs; - - switch(pid = rfork(RFMEM|RFPROC|RFNOWAIT)){ - case -1: - error("fork: %r"); - case 0: - break; - default: - atexitkill(pid); - return; - } - - atexit(atexitkiller); - if(interactive) - rawon(); - - notify(cookedcatchint); - - eofs = 0; - for(;;){ - n = read(0, buf, sizeof(buf)); - if(n < 0){ - if(wasintr()){ - if(!raw){ - buf[0] = 0x7f; - n = 1; - }else - continue; - }else - break; - } - if(n == 0){ - if(!c->interactive || ++eofs > 32) - break; - }else - eofs = 0; - if(interactive && usemenu && n && memchr(buf, 0x1c, n)) { - if(menu(c)=='q'){ - sendwritemsg(c, "", 0); - exits("quit"); - } - continue; - } - if(!raw && n==0){ - buf[0] = 0x4; - n = 1; - } - sendwritemsg(c, buf, n); - } - sendwritemsg(c, "", 0); - atexitdont(atexitkiller); - exits(nil); -} - -void -winchanges(Conn *c) -{ - int nrow, ncol, width, height; - int pid; - - switch(pid = rfork(RFMEM|RFPROC|RFNOWAIT)){ - case -1: - error("fork: %r"); - case 0: - break; - default: - atexitkill(pid); - return; - } - - for(;;){ - if(readgeom(&nrow, &ncol, &width, &height) < 0) - break; - sendwindowsize(c, nrow, ncol, width, height); - } - exits(nil); -} |