From fbb116e8ef0206199133589f9e24b005309a82c9 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 18 Apr 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-04-18 --- port/devtls.c | 150 +++++++++++++++++++++++++++++++++++++++----------- port/lib.h | 1 + port/parse.c | 2 +- 3 files changed, 121 insertions(+), 32 deletions(-) diff --git a/port/devtls.c b/port/devtls.c index e3635cbc79d74d3ee791a8f0cbfe2471fed25a30..3aa2c79e35b3fbb70222fff75289323b7f2ba806 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -10,10 +10,13 @@ #include -typedef struct OneWay OneWay; -typedef struct Secret Secret; +typedef struct OneWay OneWay; +typedef struct Secret Secret; +typedef struct TlsRec TlsRec; +typedef struct TlsErrs TlsErrs; enum { + Statlen= 1024, /* max. length of status or stats message */ /* buffer limits */ MaxRecLen = 1<<14, /* max payload length of a record layer message */ MaxCipherRecLen = MaxRecLen + 2048, @@ -73,6 +76,8 @@ enum { struct Secret { + char *encalg; /* name of encryption alg */ + char *hashalg; /* name of hash alg */ int (*enc)(Secret*, uchar*, int); int (*dec)(Secret*, uchar*, int); int (*unpad)(uchar*, int, int); @@ -92,7 +97,6 @@ struct OneWay Secret *new; /* cipher waiting for enable */ }; -typedef struct TlsRec TlsRec; struct TlsRec { Chan *c; /* io channel */ @@ -101,6 +105,10 @@ struct TlsRec char verset; /* version has been set */ char opened; /* opened command every issued? */ char err[ERRLEN]; /* error message to return to handshake requests */ + vlong handin; /* bytes communicated by the record layer */ + vlong handout; + vlong datain; + vlong dataout; Lock statelk; int state; @@ -128,7 +136,6 @@ struct TlsRec int perm; }; -typedef struct TlsErrs TlsErrs; struct TlsErrs{ int err; int sslerr; @@ -205,12 +212,14 @@ enum{ Qtopdir = 1, /* top level directory */ Qprotodir, Qclonus, + Qencalgs, + Qhashalgs, Qconvdir, /* directory for a conversation */ Qdata, Qctl, Qhand, - Qencalgs, - Qhashalgs, + Qstatus, + Qstats, }; #define TYPE(x) ((x).path & 0xf) @@ -248,30 +257,36 @@ static int noenc(Secret *sec, uchar *buf, int n); static int sslunpad(uchar *buf, int n, int block); static int tlsunpad(uchar *buf, int n, int block); static void freeSec(Secret *sec); +static char *tlsstate(int s); #pragma varargck argpos rcvError 3 static char *tlsnames[] = { [Qclonus] "clone", +[Qencalgs] "encalgs", +[Qhashalgs] "hashalgs", [Qdata] "data", [Qctl] "ctl", [Qhand] "hand", -[Qencalgs] "encalgs", -[Qhashalgs] "hashalgs", +[Qstatus] "status", +[Qstats] "stats", }; +static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats }; + static int tlsgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) { Qid q; TlsRec *tr; char name[16], *nm; - int perm; + int perm, t; USED(nd); USED(d); q.vers = 0; - switch(TYPE(c->qid)) { + t = TYPE(c->qid); + switch(t) { case Qtopdir: if(s == DEVDOTDOT){ q.path = QID(0, Qtopdir)|CHDIR; @@ -329,6 +344,8 @@ tlsgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) devdir(c, q, "tls", 0, eve, CHDIR|0555, dp); return 1; } + if(s < 0 || s >= nelem(convdir)) + return -1; lock(&tdlock); tr = tlsdevs[CONV(c->qid)]; if(tr != nil){ @@ -338,35 +355,34 @@ tlsgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) perm = 0; nm = eve; } - switch(s) { - default: - unlock(&tdlock); - return -1; - case 0: - q.path = QID(CONV(c->qid), Qctl); - break; - case 1: - q.path = QID(CONV(c->qid), Qdata); - break; - case 2: - q.path = QID(CONV(c->qid), Qhand); - break; - } - devdir(c, q, tlsnames[TYPE(q)], 0, nm, perm, dp); + t = convdir[s]; + if(t == Qstatus || t == Qstats) + perm &= 0444; + q.path = QID(CONV(c->qid), t); + devdir(c, q, tlsnames[t], 0, nm, perm, dp); unlock(&tdlock); return 1; case Qclonus: case Qencalgs: case Qhashalgs: perm = 0444; - if(TYPE(c->qid) == Qclonus) + if(t == Qclonus) perm = 0555; - devdir(c, c->qid, tlsnames[TYPE(c->qid)], 0, eve, perm, dp); + devdir(c, c->qid, tlsnames[t], 0, eve, perm, dp); return 1; default: lock(&tdlock); tr = tlsdevs[CONV(c->qid)]; - devdir(c, c->qid, tlsnames[TYPE(c->qid)], 0, tr->user, tr->perm, dp); + if(tr != nil){ + nm = tr->user; + perm = tr->perm; + }else{ + perm = 0; + nm = eve; + } + if(t == Qstatus || t == Qstats) + perm &= 0444; + devdir(c, c->qid, tlsnames[t], 0, nm, perm, dp); unlock(&tdlock); return 1; } @@ -434,6 +450,10 @@ tlsopen(Chan *c, int omode) case Qctl: case Qdata: case Qhand: + case Qstatus: + case Qstats: + if((t == Qstatus || t == Qstats) && omode != OREAD) + error(Eperm); if(waserror()) { unlock(&tdlock); nexterror(); @@ -530,6 +550,8 @@ tlsclose(Chan *c) case Qctl: case Qdata: case Qhand: + case Qstatus: + case Qstats: if((c->flag & COPEN) == 0) break; @@ -1012,6 +1034,7 @@ tlsbread(Chan *c, long n, ulong offset) b = qremove(&tr->processed, n, 0); qunlock(&tr->in.io); poperror(); + tr->datain += BLEN(b); }else{ checkstate(tr, 1, SOpen|SHandshake|SLClose); @@ -1044,6 +1067,7 @@ tlsbread(Chan *c, long n, ulong offset) b = qremove(&tr->hprocessed, n, 0); poperror(); qunlock(&tr->hqread); + tr->handin += BLEN(b); } return b; @@ -1056,18 +1080,54 @@ tlsread(Chan *c, void *a, long n, vlong off) Block *nb; uchar *va; int i; - char buf[16]; + char *buf, *s, *e; ulong offset = off; + TlsRec * tr; if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, tlsgen); + tr = tlsdevs[CONV(c->qid)]; switch(TYPE(c->qid)) { default: error(Ebadusefd); + case Qstatus: + buf = smalloc(Statlen); + qlock(&tr->in.seclock); + qlock(&tr->out.seclock); + e = buf + Statlen; + s = seprint(buf, e, "%s version 0x%lux", tlsstate(tr->state), tr->version); + if(tr->in.sec != nil) + s = seprint(s, e, " EncIn %s HashIn %s", tr->in.sec->encalg, tr->in.sec->hashalg); + if(tr->in.new != nil) + s = seprint(s, e, " NewEncIn %s NewHashIn %s", tr->in.new->encalg, tr->in.new->hashalg); + if(tr->out.sec != nil) + s = seprint(s, e, " EncOut %s HashOut %s", tr->out.sec->encalg, tr->out.sec->hashalg); + if(tr->out.new != nil) + s = seprint(s, e, " NewEncOut %s NewHashOut %s", tr->out.new->encalg, tr->out.new->hashalg); + seprint(s, e, "\n"); + qunlock(&tr->in.seclock); + qunlock(&tr->out.seclock); + n = readstr(offset, a, n, buf); + free(buf); + return n; + case Qstats: + buf = smalloc(Statlen); + s = buf; + e = buf + Statlen; + s = seprint(s, e, "DataIn: %d\n", tr->datain); + s = seprint(s, e, "DataOut: %d\n", tr->dataout); + s = seprint(s, e, "HandIn: %d\n", tr->handin); + seprint(s, e, "HandOut: %d\n", tr->handout); + n = readstr(offset, a, n, buf); + free(buf); + return n; case Qctl: - snprint(buf, sizeof(buf), "%lud", CONV(c->qid)); - return readstr(offset, a, n, buf); + buf = smalloc(Statlen); + snprint(buf, Statlen, "%lud", CONV(c->qid)); + n = readstr(offset, a, n, buf); + free(buf); + return n; case Qdata: case Qhand: b = tlsbread(c, n, offset); @@ -1221,10 +1281,12 @@ tlsbwrite(Chan *c, Block *b, ulong offset) return devbwrite(c, b, offset); case Qhand: tlsrecwrite(tr, RHandshake, b); + tr->handout += n; break; case Qdata: checkstate(tr, 0, SOpen); tlsrecwrite(tr, RApplication, b); + tr->dataout += n; break; } @@ -1497,6 +1559,10 @@ tlswrite(Chan *c, void *a, long n, vlong off) toc->unpad = tlsunpad; tos->unpad = tlsunpad; } + toc->encalg = ea->name; + toc->hashalg = ha->name; + tos->encalg = ea->name; + tos->hashalg = ha->name; free(x); poperror(); @@ -1779,6 +1845,28 @@ mktlsrec(void) return tr; } +static char* +tlsstate(int s) +{ + switch(s){ + case SHandshake: + return "Handshaking"; + case SOpen: + return "Established"; + case SRClose: + return "RemoteHangup"; + case SLClose: + return "LocalHangup"; + case SAlert: + return "Alerting"; + case SError: + return "Errored"; + case SClosed: + return "Closed"; + } + return "Unknown"; +} + static void freeSec(Secret *s) { diff --git a/port/lib.h b/port/lib.h index 423330affe2eba58ced07b6366476baceee5875d..e35280bc13d9b7f65bcd7d07952aefe445c0c73a 100644 --- a/port/lib.h +++ b/port/lib.h @@ -25,6 +25,7 @@ extern int strncmp(char*, char*, long); extern long strlen(char*); extern char* strstr(char*, char*); extern int atoi(char*); +extern int tokenize(char*, char**, int); enum { diff --git a/port/parse.c b/port/parse.c index b4e3d2f92368a3e37113fdf0a8b4a8de0a1b3734..47518c0bd4a68d6d4a334b6f82a5a8d866177693 100644 --- a/port/parse.c +++ b/port/parse.c @@ -35,7 +35,7 @@ parsecmd(char *p, int n) if(n > 0 && cb->buf[n-1] == '\n') n--; cb->buf[n] = '\0'; - cb->nf = getfields(cb->buf, cb->f, nelem(cb->f), 1, " "); + cb->nf = tokenize(cb->buf, cb->f, nelem(cb->f)); return cb; }