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/cmsg.c | |
parent | cb1555c7d741fa482c339aa9ac8a44753e2ad296 (diff) |
ssh: R.I.P.
Diffstat (limited to 'sys/src/cmd/ssh/cmsg.c')
-rw-r--r-- | sys/src/cmd/ssh/cmsg.c | 376 |
1 files changed, 0 insertions, 376 deletions
diff --git a/sys/src/cmd/ssh/cmsg.c b/sys/src/cmd/ssh/cmsg.c deleted file mode 100644 index f72f2f33b..000000000 --- a/sys/src/cmd/ssh/cmsg.c +++ /dev/null @@ -1,376 +0,0 @@ -#include "ssh.h" - -static void -recv_ssh_smsg_public_key(Conn *c) -{ - Msg *m; - - m = recvmsg(c, SSH_SMSG_PUBLIC_KEY); - memmove(c->cookie, getbytes(m, COOKIELEN), COOKIELEN); - c->serverkey = getRSApub(m); - c->hostkey = getRSApub(m); - c->flags = getlong(m); - c->ciphermask = getlong(m); - c->authmask = getlong(m); - free(m); -} - -static void -send_ssh_cmsg_session_key(Conn *c) -{ - int i, n, buflen, serverkeylen, hostkeylen; - mpint *b; - uchar *buf; - Msg *m; - RSApub *ksmall, *kbig; - - m = allocmsg(c, SSH_CMSG_SESSION_KEY, 2048); - putbyte(m, c->cipher->id); - putbytes(m, c->cookie, COOKIELEN); - - serverkeylen = mpsignif(c->serverkey->n); - hostkeylen = mpsignif(c->hostkey->n); - ksmall = kbig = nil; - if(serverkeylen+128 <= hostkeylen){ - ksmall = c->serverkey; - kbig = c->hostkey; - }else if(hostkeylen+128 <= serverkeylen){ - ksmall = c->hostkey; - kbig = c->serverkey; - }else - error("server session and host keys do not differ by at least 128 bits"); - - buflen = (mpsignif(kbig->n)+7)/8; - buf = emalloc(buflen); - - debug(DBG_CRYPTO, "session key is %.*H\n", SESSKEYLEN, c->sesskey); - memmove(buf, c->sesskey, SESSKEYLEN); - for(i = 0; i < SESSIDLEN; i++) - buf[i] ^= c->sessid[i]; - debug(DBG_CRYPTO, "munged session key is %.*H\n", SESSKEYLEN, buf); - - b = rsaencryptbuf(ksmall, buf, SESSKEYLEN); - n = (mpsignif(ksmall->n)+7) / 8; - mptoberjust(b, buf, n); - mpfree(b); - debug(DBG_CRYPTO, "encrypted with ksmall is %.*H\n", n, buf); - - b = rsaencryptbuf(kbig, buf, n); - putmpint(m, b); - debug(DBG_CRYPTO, "encrypted with kbig is %B\n", b); - mpfree(b); - - memset(buf, 0, buflen); - free(buf); - - putlong(m, c->flags); - sendmsg(m); -} - -static int -authuser(Conn *c) -{ - int i; - Msg *m; - - m = allocmsg(c, SSH_CMSG_USER, 4+strlen(c->user)); - putstring(m, c->user); - sendmsg(m); - - m = recvmsg(c, -1); - switch(m->type){ - case SSH_SMSG_SUCCESS: - free(m); - return 0; - case SSH_SMSG_FAILURE: - free(m); - break; - default: - badmsg(m, 0); - } - - for(i=0; i<c->nokauth; i++){ - debug(DBG_AUTH, "authmask %#lux, consider %s (%#x)\n", - c->authmask, c->okauth[i]->name, 1<<c->okauth[i]->id); - if(c->authmask & (1<<c->okauth[i]->id)) - if((*c->okauth[i]->fn)(c) == 0) - return 0; - } - - debug(DBG_AUTH, "no auth methods worked; (authmask=%#lux)\n", c->authmask); - return -1; -} - -static char -ask(Conn *c, char *answers, char *question) -{ - int fd; - char buf[256]; - - if(!c->interactive) - return answers[0]; - - if((fd = open("/dev/cons", ORDWR)) < 0) - return answers[0]; - - fprint(fd, "%s", question); - if(read(fd, buf, 256) <= 0 || buf[0]=='\n'){ - close(fd); - return answers[0]; - } - close(fd); - return buf[0]; -} -static void -checkkey(Conn *c) -{ - char *home, *keyfile; - - debug(DBG_CRYPTO, "checking key %B %B\n", c->hostkey->n, c->hostkey->ek); - switch(findkey("/sys/lib/ssh/keyring", c->aliases, c->hostkey)){ - default: - abort(); - case KeyOk: - return; - case KeyWrong: - fprint(2, "server presented public key different than expected\n"); - fprint(2, "(expected key in /sys/lib/ssh/keyring). will not continue.\n"); - error("bad server key"); - - case NoKey: - case NoKeyFile: - break; - } - - home = getenv("home"); - if(home == nil){ - fprint(2, "server %s not on keyring; will not continue.\n", c->host); - error("bad server key"); - } - - keyfile = smprint("%s/lib/keyring", home); - if(keyfile == nil) - error("out of memory"); - - switch(findkey(keyfile, c->aliases, c->hostkey)){ - default: - abort(); - case KeyOk: - return; - case KeyWrong: - fprint(2, "server %s presented public key different than expected\n", c->host); - fprint(2, "(expected key in %s). will not continue.\n", keyfile); - fprint(2, "this could be a man-in-the-middle attack.\n"); - switch(ask(c, "eri", "replace key in keyfile (r), continue without replacing key (c), or exit (e) [e]")){ - case 'e': - error("bad key"); - case 'r': - if(replacekey(keyfile, c->aliases, c->hostkey) < 0) - error("replacekey: %r"); - break; - case 'c': - break; - } - return; - case NoKey: - case NoKeyFile: - fprint(2, "server %s not on keyring.\n", c->host); - switch(ask(c, "eac", "add key to keyfile (a), continue without adding key (c), or exit (e) [e]")){ - case 'e': - error("bad key"); - case 'a': - if(appendkey(keyfile, c->aliases, c->hostkey) < 0) - error("appendkey: %r"); - break; - case 'c': - break; - } - return; - } -} - -void -sshclienthandshake(Conn *c) -{ - char buf[128], *p; - int i; - Msg *m; - - /* receive id string */ - if(readstrnl(c->fd[0], buf, sizeof buf) < 0) - error("reading server version: %r"); - - /* id string is "SSH-m.n-comment". We need m=1, n>=5. */ - if(strncmp(buf, "SSH-", 4) != 0 - || strtol(buf+4, &p, 10) != 1 - || *p != '.' - || strtol(p+1, &p, 10) < 5 - || *p != '-') - error("protocol mismatch; got %s, need SSH-1.x for x>=5", buf); - - /* send id string */ - fprint(c->fd[1], "SSH-1.5-Plan 9\n"); - - recv_ssh_smsg_public_key(c); - checkkey(c); - - for(i=0; i<SESSKEYLEN; i++) - c->sesskey[i] = fastrand(); - c->cipher = nil; - for(i=0; i<c->nokcipher; i++) - if((1<<c->okcipher[i]->id) & c->ciphermask){ - c->cipher = c->okcipher[i]; - break; - } - if(c->cipher == nil) - error("can't agree on ciphers: remote side supports %#lux", c->ciphermask); - - calcsessid(c); - - send_ssh_cmsg_session_key(c); - - c->cstate = (*c->cipher->init)(c, 0); /* turns on encryption */ - m = recvmsg(c, SSH_SMSG_SUCCESS); - free(m); - - if(authuser(c) < 0) - error("client authentication failed"); -} - -static int -intgetenv(char *name, int def) -{ - char *s; - int n, val; - - val = def; - if((s = getenv(name))!=nil){ - if((n=atoi(s)) > 0) - val = n; - free(s); - } - return val; -} - -/* - * assumes that if you care, you're running under vt - * and therefore these are set. - */ -int -readgeom(int *nrow, int *ncol, int *width, int *height) -{ - static int fd = -1; - char buf[64]; - - if(fd < 0 && (fd = open("/dev/wctl", OREAD)) < 0) - return -1; - /* wait for event, but don't care what it says */ - if(read(fd, buf, sizeof buf) < 0) - return -1; - *nrow = intgetenv("LINES", 24); - *ncol = intgetenv("COLS", 80); - *width = intgetenv("XPIXELS", 640); - *height = intgetenv("YPIXELS", 480); - return 0; -} - -void -sendwindowsize(Conn *c, int nrow, int ncol, int width, int height) -{ - Msg *m; - - m = allocmsg(c, SSH_CMSG_WINDOW_SIZE, 4*4); - putlong(m, nrow); - putlong(m, ncol); - putlong(m, width); - putlong(m, height); - sendmsg(m); -} - -/* - * In each option line, the first byte is the option number - * and the second is either a boolean bit or actually an - * ASCII code. - */ -static uchar ptyopt[] = -{ - 0x01, 0x7F, /* interrupt = DEL */ - 0x02, 0x11, /* quit = ^Q */ - 0x03, 0x08, /* backspace = ^H */ - 0x04, 0x15, /* line kill = ^U */ - 0x05, 0x04, /* EOF = ^D */ - 0x20, 0x00, /* don't strip high bit */ - 0x48, 0x01, /* give us CRs */ - - 0x00, /* end options */ -}; - -static uchar rawptyopt[] = -{ - 30, 0, /* ignpar */ - 31, 0, /* parmrk */ - 32, 0, /* inpck */ - 33, 0, /* istrip */ - 34, 0, /* inlcr */ - 35, 0, /* igncr */ - 36, 0, /* icnrl */ - 37, 0, /* iuclc */ - 38, 0, /* ixon */ - 39, 1, /* ixany */ - 40, 0, /* ixoff */ - 41, 0, /* imaxbel */ - - 50, 0, /* isig: intr, quit, susp processing */ - 51, 0, /* icanon: erase and kill processing */ - 52, 0, /* xcase */ - - 53, 0, /* echo */ - - 57, 0, /* noflsh */ - 58, 0, /* tostop */ - 59, 0, /* iexten: impl defined control chars */ - - 70, 0, /* opost */ - - 0x00, -}; - -void -requestpty(Conn *c) -{ - char *term; - int nrow, ncol, width, height; - Msg *m; - - m = allocmsg(c, SSH_CMSG_REQUEST_PTY, 1024); - if((term = getenv("TERM")) == nil) - term = "9term"; - putstring(m, term); - - readgeom(&nrow, &ncol, &width, &height); - putlong(m, nrow); /* characters */ - putlong(m, ncol); - putlong(m, width); /* pixels */ - putlong(m, height); - - if(rawhack) - putbytes(m, rawptyopt, sizeof rawptyopt); - else - putbytes(m, ptyopt, sizeof ptyopt); - - sendmsg(m); - - m = recvmsg(c, 0); - switch(m->type){ - case SSH_SMSG_SUCCESS: - debug(DBG_IO, "PTY allocated\n"); - break; - case SSH_SMSG_FAILURE: - debug(DBG_IO, "PTY allocation failed\n"); - break; - default: - badmsg(m, 0); - } - free(m); -} - |