summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ssh/ssh.c
diff options
context:
space:
mode:
authorkhm <devnull@localhost>2017-01-12 16:36:38 -0800
committerkhm <devnull@localhost>2017-01-12 16:36:38 -0800
commitdc8c7bf2b73d608ac2483aee303a51a3507b4c5a (patch)
treef8c69dbf5f36de6f9acea724f2068054b5b8e7a6 /sys/src/cmd/ssh/ssh.c
parentcb1555c7d741fa482c339aa9ac8a44753e2ad296 (diff)
ssh: R.I.P.
Diffstat (limited to 'sys/src/cmd/ssh/ssh.c')
-rw-r--r--sys/src/cmd/ssh/ssh.c592
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);
-}