From 7cd991eddcc06c102af939c4ea8a057ad9118530 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 31 May 1996 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1996-05-31 --- port/devssl.c | 207 ++++++++++++++++---------------- port/net.c | 320 -------------------------------------------------- 2 files changed, 105 insertions(+), 422 deletions(-) delete mode 100644 port/net.c diff --git a/port/devssl.c b/port/devssl.c index b62a4c9ad3b7dd17d4877ed78cb930c0fb0e2aa3..18d6472130b28989858ebb2de84afceb31178634 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -1,25 +1,25 @@ /* - * template for making a new device + * devssl - secure sockets layer emulation */ +#include "u.h" +#include "../port/lib.h" +#include "../port/error.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include +#include typedef struct OneWay OneWay; struct OneWay { - QLock; + QLock q; - void *state; /* encryption state */ - int slen; /* hash data length */ - uchar *secret; /* secret */ - ulong mid; /* message id */ + void *state; /* encryption state */ + int slen; /* hash data length */ + uchar *secret; /* secret */ + ulong mid; /* message id */ }; enum @@ -35,7 +35,7 @@ enum /* encryption algorithms */ Noencryption= 0, DESCBC= 1, - DESECB= 2, + DESECB= 2 }; typedef struct Dstate Dstate; @@ -64,12 +64,12 @@ struct Dstate enum { - Maxdmsg= 1<<16, + Maxdmsg= 1<<16 }; enum{ Qdir, - Qclone, + Qclone }; Dirtab digesttab[]={ "ssl", {Qclone, 0}, 0, 0666, @@ -98,21 +98,20 @@ static void checkdigestb(Dstate*, Block*); static Chan* buftochan(char*, long); static void dighangup(Dstate*); - void sslreset(void) { - randq.ep = randq.buf + sizeof(randq.buf); - randq.rp = randq.wp = randq.buf; } void sslinit(void) { + randq.ep = randq.buf + sizeof(randq.buf); + randq.rp = randq.wp = randq.buf; } Chan * -sslattach(char *spec) +sslattach(void *spec) { return devattach('D', spec); } @@ -142,7 +141,7 @@ sslopen(Chan *c, int omode) switch(c->qid.path & ~CHDIR){ case Qclone: - s = smalloc(sizeof(Dstate)); + s = malloc(sizeof(Dstate)); memset(s, 0, sizeof(*s)); s->state = Algwait; c->aux = s; @@ -154,7 +153,10 @@ sslopen(Chan *c, int omode) void sslcreate(Chan *c, char *name, int omode, ulong perm) { - USED(c, name, omode, perm); + USED(c); + USED(name); + USED(omode); + USED(perm); error(Eperm); } @@ -168,7 +170,8 @@ sslremove(Chan *c) void sslwstat(Chan *c, char *dp) { - USED(c, dp); + USED(c); + USED(dp); error(Eperm); } @@ -181,7 +184,7 @@ sslclose(Chan *c) s = c->aux; dighangup(s); if(s->c) - close(s->c); + cclose(s->c); if(s->in.secret) free(s->in.secret); if(s->out.secret) @@ -193,81 +196,81 @@ sslclose(Chan *c) Block* sslbread(Chan *c, long n, ulong offset) { - Dstate *s; + volatile struct { Dstate *s; } s; Block *b; uchar count[2]; int i, len, pad; USED(offset); - s = c->aux; - if(s == 0 || s->state != Established) + s.s = c->aux; + if(s.s == 0 || s.s->state != Established) error(Ebadusefd); if(waserror()){ - qunlock(&s->in); - dighangup(s); + qunlock(&s.s->in.q); + dighangup(s.s); nexterror(); } - qlock(&s->in); + qlock(&s.s->in.q); - b = s->processed; + b = s.s->processed; if(b == 0){ /* read in the whole message */ - s->processed = s->unprocessed; - s->unprocessed = 0; - ensure(s, &s->processed, 2); - consume(&s->processed, count, 2); + s.s->processed = s.s->unprocessed; + s.s->unprocessed = 0; + ensure(s.s, &s.s->processed, 2); + consume(&s.s->processed, count, 2); if(count[0] & 0x80){ len = ((count[0] & 0x7f)<<8) | count[1]; - ensure(s, &s->processed, len); + ensure(s.s, &s.s->processed, len); pad = 0; } else { len = ((count[0] & 0x3f)<<8) | count[1]; - ensure(s, &s->processed, len+1); - consume(&s->processed, count, 1); + ensure(s.s, &s.s->processed, len+1); + consume(&s.s->processed, count, 1); pad = count[0]; } /* trade memory bandwidth for less processing complexity */ - b = s->processed = pullupblock(s->processed, len); + b = s.s->processed = pullupblock(s.s->processed, len); /* put remainder on unprocessed queue */ i = BLEN(b); if(i > len){ i -= len; - s->unprocessed = allocb(i); - memmove(s->unprocessed->wp, b->rp+len, i); - s->unprocessed->wp += i; + s.s->unprocessed = allocb(i); + memmove(s.s->unprocessed->wp, b->rp+len, i); + s.s->unprocessed->wp += i; b->wp -= i; } - if(s->encryptalg) - b = decryptb(s, b); + if(s.s->encryptalg) + b = decryptb(s.s, b); else { - if(BLEN(b) < s->diglen) + if(BLEN(b) < s.s->diglen) error("baddigest"); - checkdigestb(s, b); - b->rp += s->diglen; + checkdigestb(s.s, b); + b->rp += s.s->diglen; } /* remove pad */ if(b->wp - b->rp < pad) panic("sslbread"); b->wp -= pad; - s->processed = b; + s.s->processed = b; } if(BLEN(b) > n){ b = allocb(n); - memmove(b->wp, s->processed->rp, n); + memmove(b->wp, s.s->processed->rp, n); b->wp += n; - s->processed->rp += n; + s.s->processed->rp += n; } else - s->processed = b->next; + s.s->processed = b->next; - qunlock(&s->in); + qunlock(&s.s->in.q); poperror(); return b; @@ -276,23 +279,23 @@ sslbread(Chan *c, long n, ulong offset) long sslread(Chan *c, void *a, long n, ulong offset) { - Block *b; + volatile struct { Block *b; } b; switch(c->qid.path & ~CHDIR){ case Qdir: return devdirread(c, a, n, digesttab, Ndigesttab, devgen); } - b = sslbread(c, n, offset); + b.b = sslbread(c, n, offset); if(waserror()){ - freeb(b); + freeb(b.b); nexterror(); } - n = BLEN(b); - memmove(a, b->rp, n); - freeb(b); + n = BLEN(b.b); + memmove(a, b.b->rp, n); + freeb(b.b); poperror(); @@ -305,41 +308,43 @@ sslread(Chan *c, void *a, long n, ulong offset) long sslbwrite(Chan *c, Block *b, ulong offset) { - Dstate *s; + volatile struct { Dstate *s; } s; + volatile struct { Block *b; } bb; Block *nb; int h, n, m, pad, rv; uchar *p; - s = c->aux; - if(s == 0 || s->state != Established) + bb.b = b; + s.s = c->aux; + if(s.s == 0 || s.s->state != Established) error(Ebadusefd); if(waserror()){ - qunlock(&s->out); - if(b) - freeb(b); - dighangup(s); + qunlock(&s.s->out.q); + if(bb.b) + freeb(bb.b); + dighangup(s.s); nexterror(); } - qlock(&s->out); + qlock(&s.s->out.q); rv = 0; - while(b){ - m = n = BLEN(b); - h = s->diglen + 2; + while(bb.b){ + m = n = BLEN(bb.b); + h = s.s->diglen + 2; /* trim to maximum block size */ pad = 0; - if(m > s->max){ - m = s->max; - } else if(s->blocklen != 1){ - pad = m%s->blocklen; + if(m > s.s->max){ + m = s.s->max; + } else if(s.s->blocklen != 1){ + pad = m%s.s->blocklen; if(pad){ - if(m > s->maxpad){ + if(m > s.s->maxpad){ pad = 0; - m = s->maxpad; + m = s.s->maxpad; } else { - pad = s->blocklen - pad; + pad = s.s->blocklen - pad; h++; } } @@ -348,16 +353,15 @@ sslbwrite(Chan *c, Block *b, ulong offset) rv += m; if(m != n){ nb = allocb(m + h + pad); - memmove(nb->wp + h, b->rp, m); + memmove(nb->wp + h, bb.b->rp, m); nb->wp += m + h; - b->rp += m; + bb.b->rp += m; } else { /* add header space */ - nb = padblock(b, h); - nb->rp -= h; - b = 0; + nb = padblock(bb.b, h); + bb.b = 0; } - m += s->diglen; + m += s.s->diglen; /* SSL style count */ if(pad){ @@ -378,15 +382,15 @@ sslbwrite(Chan *c, Block *b, ulong offset) offset = 2; } - if(s->encryptalg) - nb = encryptb(s, nb, offset); + if(s.s->encryptalg) + nb = encryptb(s.s, nb, offset); else - nb = digestb(s, nb, offset); + nb = digestb(s.s, nb, offset); - (*devtab[s->c->type].bwrite)(s->c, nb, offset); + (*devtab[s.s->c->type].bwrite)(s.s->c, nb, offset); } - qunlock(&s->out); + qunlock(&s.s->out.q); poperror(); return rv; @@ -396,7 +400,7 @@ long sslwrite(Chan *c, void *a, long n, ulong offset) { Dstate *s; - Block *b; + volatile struct { Block *b; } b; int m; char *p, *e, buf[32]; @@ -465,16 +469,16 @@ sslwrite(Chan *c, void *a, long n, ulong offset) if(m > s->max) m = s->max; - b = allocb(m); + b.b = allocb(m); if(waserror()){ - freeb(b); + freeb(b.b); nexterror(); } - memmove(b->wp, p, m); + memmove(b.b->wp, p, m); poperror(); - b->wp += m; + b.b->wp += m; - sslbwrite(c, b, offset); + sslbwrite(c, b.b, offset); } break; default: @@ -544,7 +548,7 @@ consume(Block **l, uchar *p, int n) static void setsecret(Dstate *s, OneWay *w, uchar *secret, int n) { - w->secret = smalloc(n); + w->secret = malloc(n); memmove(w->secret, secret, n); w->slen = n; w->mid = 0; @@ -553,13 +557,13 @@ setsecret(Dstate *s, OneWay *w, uchar *secret, int n) case DESECB: if(n < 8) error("secret too small"); - w->state = smalloc(sizeof(DESstate)); + w->state = malloc(sizeof(DESstate)); setupDESstate(w->state, secret, 0); break; case DESCBC: if(n < 16) error("secret too small"); - w->state = smalloc(sizeof(DESstate)); + w->state = malloc(sizeof(DESstate)); setupDESstate(w->state, secret, secret+8); break; } @@ -714,7 +718,7 @@ dighangup(Dstate *s) { Block *b; - qlock(&s->in); + qlock(&s->in.q); for(b = s->processed; b; b = s->processed){ s->processed = b->next; freeb(b); @@ -724,7 +728,7 @@ dighangup(Dstate *s) s->unprocessed = 0; } s->state = Closed; - qunlock(&s->in); + qunlock(&s->in.q); } /* @@ -735,9 +739,9 @@ void handle_exception(int type, char *exception) { if(type == CRITICAL) - panic("kernel ssl: %s", exception); + panic("crypt library (devssl): %s", exception); else - print("kernel ssl: %s\n", exception); + print("crypt library (devssl): %s\n", exception); } void* @@ -745,7 +749,7 @@ crypt_malloc(int size) { void *x; - x = smalloc(size); + x = malloc(size); if(x == 0) handle_exception(CRITICAL, "out of memory"); return x; @@ -758,4 +762,3 @@ crypt_free(void *x) handle_exception(CRITICAL, "freeing null pointer"); free(x); } - diff --git a/port/net.c b/port/net.c deleted file mode 100644 index 43ee1a20a6dc73847eac279970b781887601ee76..0000000000000000000000000000000000000000 --- a/port/net.c +++ /dev/null @@ -1,320 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -enum -{ - Qlisten = 1, - Qclone = 2, - Q2nd = 3, - Q3rd = 4, - Qinf = 5, -}; - -/* - * find protection structure - */ -static Netprot* -findprot(Network *np, int id) -{ - Netprot *p; - - for(p = np->prot; p; p = p->next) - if(p->id == id) - break; - return p; -} - -/* - * generate a 3 level directory - */ -int -netgen(Chan *c, void *vp, int, int i, Dir *dp) -{ - Qid q; - char buf[32]; - Network *np = vp; - int t; - Netprot *p; - int perm; - char *o; - - q.vers = 0; - - /* top level directory contains the name of the network */ - if(c->qid.path == CHDIR){ - switch(i){ - case 0: - q.path = CHDIR | Q2nd; - strcpy(buf, np->name); - devdir(c, q, buf, 0, eve, 0555, dp); - break; - default: - return -1; - } - return 1; - } - - /* second level contains clone plus all the conversations */ - t = NETTYPE(c->qid.path); - if(t == Q2nd || t == Qclone){ - if(i == 0){ - q.path = Qclone; - devdir(c, q, "clone", 0, eve, 0666, dp); - }else if(i <= np->nconv){ - if(findprot(np, i-1) == 0) - return 0; - q.path = CHDIR|NETQID(i-1, Q3rd); - sprint(buf, "%d", i-1); - devdir(c, q, buf, 0, eve, 0555, dp); - }else - return -1; - return 1; - } - - /* third level depends on the number of info files */ - p = findprot(np, NETID(c->qid.path)); - if(p == 0) - return 0; - if(*p->owner){ - o = p->owner; - perm = p->mode; - } else { - o = eve; - perm = 0666; - } - switch(i){ - case 0: - q.path = NETQID(NETID(c->qid.path), Ndataqid); - devdir(c, q, "data", 0, o, perm, dp); - break; - case 1: - q.path = NETQID(NETID(c->qid.path), Nctlqid); - devdir(c, q, "ctl", 0, o, perm, dp); - break; - case 2: - if(np->listen == 0) - return 0; - q.path = NETQID(NETID(c->qid.path), Qlisten); - devdir(c, q, "listen", 0, o, perm, dp); - break; - default: - i -= 3; - if(i >= np->ninfo) - return -1; - q.path = NETQID(NETID(c->qid.path), Qinf+i); - devdir(c, q, np->info[i].name, 0, eve, 0444, dp); - break; - } - return 1; -} - -int -netwalk(Chan *c, char *name, Network *np) -{ - if(strcmp(name, "..") == 0) { - switch(NETTYPE(c->qid.path)){ - case Q2nd: - c->qid.path = CHDIR; - break; - case Q3rd: - c->qid.path = CHDIR|Q2nd; - break; - default: - panic("netwalk %lux", c->qid.path); - } - return 1; - } - - return devwalk(c, name, (Dirtab*)np, 0, netgen); -} - -void -netstat(Chan *c, char *db, Network *np) -{ - int i; - Dir dir; - - for(i=0;; i++) - switch(netgen(c, (Dirtab*)np, 0, i, &dir)){ - case -1: - /* - * devices with interesting directories usually don't get - * here, which is good because we've lost the name by now. - */ - if(c->qid.path & CHDIR){ - devdir(c, c->qid, c->path->elem, 0L, eve, CHDIR|0555, &dir); - convD2M(&dir, db); - return; - } - print("netstat %C %lux\n", devchar[c->type], c->qid.path); - error(Enonexist); - case 0: - break; - case 1: - if(eqqid(c->qid, dir.qid)){ - if(c->flag&CMSG) - dir.mode |= CHMOUNT; - convD2M(&dir, db); - return; - } - break; - } -} - -Chan * -netopen(Chan *c, int omode, Network *np) -{ - int id = 0; - Netprot *p; - - if(c->qid.path & CHDIR){ - if(omode != OREAD) - error(Eperm); - } else { - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - case Nctlqid: - id = NETID(c->qid.path); - id = (*np->open)(c, id); - break; - case Qlisten: - id = (*np->listen)(c); - c->qid.path = NETQID(id, Nctlqid); - ptclone(c, 1, id); - break; - case Qclone: - id = (*np->open)(c, -1); - c->qid.path = NETQID(id, Nctlqid); - ptclone(c, 0, id); - break; - default: - if(omode != OREAD) - error(Ebadarg); - } - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - case Nctlqid: - p = findprot(np, id); - if(netown(p, up->user, omode&7) < 0) - error(Eperm); - break; - } - } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -long -netread(Chan *c, void *a, long n, ulong offset, Network *np) -{ - int t; - char buf[256]; - - if(c->qid.path&CHDIR) - return devdirread(c, a, n, (Dirtab*)np, 0, netgen); - - t = NETTYPE(c->qid.path); - if(t == Nctlqid) - readnum(offset, a, n, NETID(c->qid.path), NUMSIZE); - - if(t < Qinf || t >= Qinf + np->ninfo) - error(Ebadusefd); - - (*np->info[t-Qinf].fill)(c, buf, sizeof(buf)); - return readstr(offset, a, n, buf); -} - -void -netadd(Network *np, Netprot *p, int id) -{ - Netprot **l, *pp; - - memset(p, 0, sizeof(Netprot)); - p->id = id; - p->net = np; - - l = &np->prot; - for(pp = np->prot; pp; pp = pp->next){ - if(pp->id == id) - panic("netadd"); - l = &pp->next; - } - *l = p; -} - -Lock netlock; - -int -netown(Netprot *p, char *o, int omode) -{ - static int access[] = { 0400, 0200, 0600, 0100 }; - int mode; - int t; - - lock(&netlock); - if(*p->owner){ - if(strncmp(o, p->owner, NAMELEN) == 0) /* User */ - mode = p->mode; - else if(strncmp(o, eve, NAMELEN) == 0) /* Bootes is group */ - mode = p->mode<<3; - else - mode = p->mode<<6; /* Other */ - - t = access[omode&3]; - if((t & mode) == t){ - unlock(&netlock); - return 0; - } else { - unlock(&netlock); - return -1; - } - } - strncpy(p->owner, o, NAMELEN); - p->mode = 0660; - unlock(&netlock); - return 0; -} - -void -netdisown(Netprot *p) -{ - p->owner[0] = 0; -} - -#undef CHDIR /* BUG */ -#include "/sys/src/libc/9syscall/sys.h" - -void -netwstat(Chan *c, char *db, Network *np) -{ - Dir dir; - Netprot *p; - - p = findprot(np, NETID(c->qid.path)); - if(p == 0) - error(Enonexist); - lock(np); - - /* - * A network channel's ownership/permissions can be changed only if the - * wstat is by the owner or (HACK!) if it is performed using an fwstat. - * The latter allows processes started by a network listener to gain - * ownership of the connection. The open file descriptor is used as - * a capability for the connection. - */ - if(strncmp(p->owner, up->user, NAMELEN) != 0 && up->scallnr != FWSTAT){ - unlock(np); - error(Eperm); - } - convM2D(db, &dir); - strncpy(p->owner, dir.uid, NAMELEN); - p->mode = dir.mode; - - unlock(np); -}