diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2013-12-16 10:06:34 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2013-12-16 10:06:34 +0100 |
commit | 6946118644bc1d18e99de13b4a93b2026e3560a4 (patch) | |
tree | 37c9d2587c7c70c772d821f9bd8936035eddf908 /sys/src | |
parent | 35484945e2f782fe312fcae4f0269b80c4184367 (diff) |
devssl: use parsecmd() to process control message to get rid of 128 byte stack buffer limit
(11:02:29 PM) me: why is buf in /sys/src/9/port/devssl.c:/^sslwrite only 128 bytes?
(11:02:58 PM) me: it makes it so you can't use a 128 bytes secret as negotiated by infauth in a secretin or secretout ctl message
(11:03:30 PM) me: which in turn means you can't use such a secret with pushssl(2)
(11:06:15 PM) me: inferno's sslwrite is limited to 32 bytes, but its ssl library writes to the secret files instead of to the ctl file
(11:08:50 PM) mischief: what should it be instead of 128 bytes
(11:08:58 PM) me: larger
(11:09:16 PM) mischief: how about 129 bytes?
(11:09:59 PM) me: also broken in 9front, by the way
(11:15:14 PM) me: i guess it should be replaced with parsecmd
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/9/port/devssl.c | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/sys/src/9/port/devssl.c b/sys/src/9/port/devssl.c index 52c0c2309..7e9133e8e 100644 --- a/sys/src/9/port/devssl.c +++ b/sys/src/9/port/devssl.c @@ -996,6 +996,7 @@ struct Encalg }; #ifdef NOSPOOKS +static Encalg encrypttab[] = { { "descbc", 8, DESCBC, initDESkey, }, /* DEPRECATED -- use des_56_cbc */ @@ -1011,6 +1012,7 @@ Encalg encrypttab[] = { 0 } }; #else +static Encalg encrypttab[] = { { "des_40_cbc", 8, DESCBC, initDESkey_40, }, @@ -1040,14 +1042,31 @@ parseencryptalg(char *p, Dstate *s) return -1; } +enum { + Cfd, + Calg, + Csin, + Csout, +}; + +static +Cmdtab sslcmds[] = { + {Cfd, "fd", 2 }, + {Calg, "alg", 0 }, + {Csin, "secretin", 2 }, + {Csout, "secretout", 2 }, +}; + static long sslwrite(Chan *c, void *a, long n, vlong) { Dstate * volatile s; Block * volatile b; - int m, t; - char *p, *np, *e, buf[128]; + int m, t, i; + char *p, *e; uchar *x; + Cmdbuf *cb; + Cmdtab *ct; s = dstate[CONV(c->qid)]; if(s == 0) @@ -1113,19 +1132,15 @@ sslwrite(Chan *c, void *a, long n, vlong) break; } - if(n >= sizeof(buf)) - error("arg too long"); - strncpy(buf, a, n); - buf[n] = 0; - p = strchr(buf, '\n'); - if(p) - *p = 0; - p = strchr(buf, ' '); - if(p) - *p++ = 0; - - if(strcmp(buf, "fd") == 0){ - s->c = buftochan(p); + cb = parsecmd(a, n); + if(waserror()){ + free(cb); + nexterror(); + } + ct = lookupcmd(cb, sslcmds, nelem(sslcmds)); + switch(ct->index){ + case Cfd: + s->c = buftochan(cb->f[1]); /* default is clear (msg delimiters only) */ s->state = Sclear; @@ -1134,7 +1149,11 @@ sslwrite(Chan *c, void *a, long n, vlong) s->maxpad = s->max = (1<<15) - s->diglen - 1; s->in.mid = 0; s->out.mid = 0; - } else if(strcmp(buf, "alg") == 0 && p != 0){ + break; + case Calg: + if(cb->nf < 2) + cmderror(cb, "no algorithms"); + s->blocklen = 1; s->diglen = 0; @@ -1143,9 +1162,8 @@ sslwrite(Chan *c, void *a, long n, vlong) s->state = Sclear; s->maxpad = s->max = (1<<15) - s->diglen - 1; - if(strcmp(p, "clear") == 0){ - goto out; - } + if(strcmp(cb->f[1], "clear") == 0) + break; if(s->in.secret && s->out.secret == 0) setsecret(&s->out, s->in.secret, s->in.slen); @@ -1158,18 +1176,11 @@ sslwrite(Chan *c, void *a, long n, vlong) s->encryptalg = Noencryption; s->blocklen = 1; - for(;;){ - np = strchr(p, ' '); - if(np) - *np++ = 0; - + for(i=1; i<cb->nf; i++){ + p = cb->f[i]; if(parsehashalg(p, s) < 0) if(parseencryptalg(p, s) < 0) error("bad algorithm"); - - if(np == 0) - break; - p = np; } if(s->hf == 0 && s->encryptalg == Noencryption) @@ -1182,7 +1193,9 @@ sslwrite(Chan *c, void *a, long n, vlong) s->maxpad -= s->maxpad % s->blocklen; } else s->maxpad = s->max = (1<<15) - s->diglen - 1; - } else if(strcmp(buf, "secretin") == 0 && p != 0) { + break; + case Csin: + p = cb->f[1]; m = (strlen(p)*3)/2; x = smalloc(m); t = dec64(x, m, p, strlen(p)); @@ -1192,7 +1205,9 @@ sslwrite(Chan *c, void *a, long n, vlong) } setsecret(&s->in, x, t); free(x); - } else if(strcmp(buf, "secretout") == 0 && p != 0) { + break; + case Csout: + p = cb->f[1]; m = (strlen(p)*3)/2 + 1; x = smalloc(m); t = dec64(x, m, p, strlen(p)); @@ -1202,8 +1217,10 @@ sslwrite(Chan *c, void *a, long n, vlong) } setsecret(&s->out, x, t); free(x); - } else - error(Ebadarg); + break; + } + poperror(); + free(cb); out: qunlock(&s->in.ctlq); |