diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ssh/util.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ssh/util.c')
-rwxr-xr-x | sys/src/cmd/ssh/util.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/sys/src/cmd/ssh/util.c b/sys/src/cmd/ssh/util.c new file mode 100755 index 000000000..ff737884a --- /dev/null +++ b/sys/src/cmd/ssh/util.c @@ -0,0 +1,269 @@ +#include "ssh.h" +#include <bio.h> +#include <ndb.h> + +char Edecode[] = "error decoding input packet"; +char Eencode[] = "out of space encoding output packet (BUG)"; +char Ehangup[] = "hungup connection"; +char Ememory[] = "out of memory"; + +int debuglevel; +int doabort; + +void +error(char *fmt, ...) +{ + va_list arg; + char buf[2048]; + + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); + fprint(2, "%s: %s\n", argv0, buf); + if(doabort) + abort(); + exits(buf); +} + +void +debug(int level, char *fmt, ...) +{ + va_list arg; + + if((level&debuglevel) == 0) + return; + va_start(arg, fmt); + vfprint(2, fmt, arg); + va_end(arg); +} + +void* +emalloc(long n) +{ + void *a; + + a = mallocz(n, 1); + if(a == nil) + error(Ememory); + setmalloctag(a, getcallerpc(&n)); + return a; +} + +void* +erealloc(void *v, long n) +{ + v = realloc(v, n); + if(v == nil) + error(Ememory); + setrealloctag(v, getcallerpc(&v)); + return v; +} + + +static int killpid[32]; +static int nkillpid; +void +atexitkiller(void) +{ + int i, pid; + + pid = getpid(); + debug(DBG, "atexitkiller: nkillpid=%d mypid=%d\n", nkillpid, pid); + for(i=0; i<nkillpid; i++) + if(pid != killpid[i]){ + debug(DBG, "killing %d\n", killpid[i]); + postnote(PNPROC, killpid[i], "kill"); + } +} +void +atexitkill(int pid) +{ + killpid[nkillpid++] = pid; +} + +int +readstrnl(int fd, char *buf, int nbuf) +{ + int i; + + for(i=0; i<nbuf; i++){ + switch(read(fd, buf+i, 1)){ + case -1: + return -1; + case 0: + werrstr("unexpected EOF"); + return -1; + default: + if(buf[i]=='\n'){ + buf[i] = '\0'; + return 0; + } + break; + } + } + werrstr("line too long"); + return -1; +} + +void +calcsessid(Conn *c) +{ + int n; + uchar buf[1024]; + + n = mptobe(c->hostkey->n, buf, sizeof buf, nil); + n += mptobe(c->serverkey->n, buf+n, sizeof buf-n, nil); + memmove(buf+n, c->cookie, COOKIELEN); + n += COOKIELEN; + md5(buf, n, c->sessid, nil); +} + +void +sshlog(char *f, ...) +{ + char *s; + va_list arg; + Fmt fmt; + static int pid; + + if(pid == 0) + pid = getpid(); + + va_start(arg, f); + va_end(arg); + + if(fmtstrinit(&fmt) < 0) + sysfatal("fmtstrinit: %r"); + + fmtprint(&fmt, "[%d] ", pid); + fmtvprint(&fmt, f, arg); + + s = fmtstrflush(&fmt); + if(s == nil) + sysfatal("fmtstrflush: %r"); + syslog(0, "ssh", "%s", s); + free(s); +} + +/* + * this is far too smart. + */ +static int +pstrcmp(const void *a, const void *b) +{ + return strcmp(*(char**)a, *(char**)b); +} + +static char* +trim(char *s) +{ + char *t; + int i, last, n, nf; + char **f; + char *p; + + t = emalloc(strlen(s)+1); + t[0] = '\0'; + n = 1; + for(p=s; *p; p++) + if(*p == ' ') + n++; + f = emalloc((n+1)*sizeof(f[0])); + nf = tokenize(s, f, n+1); + qsort(f, nf, sizeof(f[0]), pstrcmp); + last=-1; + for(i=0; i<nf; i++){ + if(last==-1 || strcmp(f[last], f[i])!=0){ + if(last >= 0) + strcat(t, ","); + strcat(t, f[i]); + last = i; + } + } + return t; +} + +static void +usetuple(Conn *c, Ndbtuple *t, int scanentries) +{ + int first; + Ndbtuple *l, *e; + char *s; + + first=1; + s = c->host; + for(l=t; first||l!=t; l=l->line, first=0){ + if(scanentries){ + for(e=l; e; e=e->entry){ + if(strcmp(e->val, c->host) != 0 && + (strcmp(e->attr, "ip")==0 || strcmp(e->attr, "dom")==0 || strcmp(e->attr, "sys")==0)){ + s = smprint("%s %s", s, e->val); + if(s == nil) + error("out of memory"); + } + } + } + if(strcmp(l->val, c->host) != 0 && + (strcmp(l->attr, "ip")==0 || strcmp(l->attr, "dom")==0 || strcmp(l->attr, "sys")==0)){ + s = smprint("%s %s", s, l->val); + if(s == nil) + error("out of memory"); + } + } + s = trim(s); + c->aliases = s; +} + +void +setaliases(Conn *c, char *name) +{ + char *p, *net; + char *attr[2]; + Ndbtuple *t; + + net = "/net"; + if(name[0]=='/'){ + p = strchr(name+1, '/'); + if(p){ + net = emalloc(p-name+1); + memmove(net, name, p-name); + } + } + if(p = strchr(name, '!')) + name = p+1; + + c->host = emalloc(strlen(name)+1); + strcpy(c->host, name); + + c->aliases = c->host; + attr[0] = "dom"; + attr[1] = "ip"; + t = csipinfo(nil, ipattr(name), name, attr, 2); + if(t != nil){ + usetuple(c, t, 0); + ndbfree(t); + }else{ + t = dnsquery(net, name, "ip"); + if(t != nil){ + usetuple(c, t, 1); + ndbfree(t); + } + } +} + +void +privatefactotum(void) +{ + char *user; + Dir *d; + + if((user=getuser()) && (d=dirstat("/mnt/factotum/rpc")) && strcmp(user, d->uid)!=0){ + /* grab the terminal's factotum */ + rfork(RFNAMEG); /* was RFNOTEG, which makes little sense */ + if(access("/mnt/term/mnt/factotum", AEXIST) >= 0){ +// fprint(2, "binding terminal's factotum\n"); + if(bind("/mnt/term/mnt/factotum", "/mnt/factotum", MREPL) < 0) + sysfatal("cannot find factotum"); + } + } +} |