| tnew - plan9port - [fork] Plan 9 from user space | |
| git clone git://src.adamsgaard.dk/plan9port | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit 1757e76a73818470d0d8d062ca2d05e3fc7c9524 | |
| parent 45993349d8414bdf7eb24d8996e02aa4d53951ad | |
| Author: rsc <devnull@localhost> | |
| Date: Sun, 13 Feb 2005 22:09:47 +0000 | |
| new | |
| Diffstat: | |
| M bin/.cvsignore | 17 +++++++++++++++++ | |
| M src/cmd/auth/factotum/apop.c | 25 ++++++++++++++----------- | |
| A src/cmd/auth/factotum/httpdigest.c | 119 +++++++++++++++++++++++++++++… | |
| M src/cmd/auth/factotum/main.c | 3 +++ | |
| M src/cmd/auth/factotum/mkfile | 4 +++- | |
| M src/cmd/auth/factotum/p9cr.c | 43 ++++++++++++++---------------… | |
| M src/cmd/auth/factotum/proto.c | 2 ++ | |
| M src/cmd/auth/factotum/secstore.c | 5 ++++- | |
| A src/cmd/auth/factotum/wep.c | 83 +++++++++++++++++++++++++++++… | |
| 9 files changed, 264 insertions(+), 37 deletions(-) | |
| --- | |
| diff --git a/bin/.cvsignore b/bin/.cvsignore | |
| t@@ -16,6 +16,8 @@ adict | |
| aescbc | |
| ajuke | |
| ascii | |
| +asn12dsa | |
| +asn12rsa | |
| astro | |
| auxclog | |
| auxstats | |
| t@@ -41,6 +43,8 @@ deroff | |
| dial | |
| dict | |
| diff | |
| +dsa2ssh | |
| +dsagen | |
| dump9660 | |
| echo | |
| ed | |
| t@@ -92,6 +96,7 @@ mp3info | |
| mtime | |
| namespace | |
| ndbipquery | |
| +ndbmkdb | |
| ndbmkhash | |
| ndbmkhosts | |
| ndbquery | |
| t@@ -99,7 +104,10 @@ netkey | |
| news | |
| notes | |
| p | |
| +passwd | |
| pbd | |
| +pemdecode | |
| +pemencode | |
| pic | |
| plot | |
| plumb | |
| t@@ -113,8 +121,15 @@ psdownload | |
| ramfs | |
| rc | |
| read | |
| +readcons | |
| rio | |
| rm | |
| +rsa2csr | |
| +rsa2pub | |
| +rsa2ssh | |
| +rsa2x509 | |
| +rsafill | |
| +rsagen | |
| sam | |
| samterm | |
| scat | |
| t@@ -128,10 +143,12 @@ sleep | |
| sort | |
| split | |
| sprog | |
| +ssh-agent | |
| stats | |
| strings | |
| sum | |
| tail | |
| +tar | |
| tbl | |
| tcolors | |
| tcs | |
| diff --git a/src/cmd/auth/factotum/apop.c b/src/cmd/auth/factotum/apop.c | |
| t@@ -6,7 +6,7 @@ | |
| * Protocol: | |
| * | |
| * S -> C: random@domain | |
| - * C -> S: hex-response | |
| + * C -> S: user hex-response | |
| * S -> C: ok | |
| * | |
| * Note that this is the protocol between factotum and the local | |
| t@@ -15,7 +15,7 @@ | |
| * programs. | |
| * | |
| * If S sends "bad [msg]" instead of "ok", that is a hint that the key is bad. | |
| - * The protocol goes back to "C -> S: user". | |
| + * The protocol goes back to "C -> S: user hex-response". | |
| */ | |
| #include "std.h" | |
| t@@ -240,7 +240,7 @@ out: | |
| keyclose(s.k); | |
| free(user); | |
| free(resp); | |
| -// xioclose(s.asfd); | |
| + xioclose(s.asfd); | |
| return ret; | |
| } | |
| t@@ -336,15 +336,18 @@ apoproles[] = | |
| }; | |
| Proto apop = { | |
| -.name= "apop", | |
| -.roles= apoproles, | |
| -.checkkey= apopcheck, | |
| -.keyprompt= "user? !password?", | |
| + "apop", | |
| + apoproles, | |
| + "user? !password?", | |
| + apopcheck, | |
| + nil | |
| }; | |
| Proto cram = { | |
| -.name= "cram", | |
| -.roles= apoproles, | |
| -.checkkey= apopcheck, | |
| -.keyprompt= "user? !password?", | |
| + "cram", | |
| + apoproles, | |
| + "user? !password?", | |
| + apopcheck, | |
| + nil | |
| }; | |
| + | |
| diff --git a/src/cmd/auth/factotum/httpdigest.c b/src/cmd/auth/factotum/httpdig… | |
| t@@ -0,0 +1,119 @@ | |
| +/* | |
| + * HTTPDIGEST - MD5 challenge/response authentication (RFC 2617) | |
| + * | |
| + * Client protocol: | |
| + * write challenge: nonce method uri | |
| + * read response: 2*MD5dlen hex digits | |
| + * | |
| + * Server protocol: | |
| + * unimplemented | |
| + */ | |
| +#include "std.h" | |
| +#include "dat.h" | |
| + | |
| +static void | |
| +digest(char *user, char *realm, char *passwd, | |
| + char *nonce, char *method, char *uri, | |
| + char *dig); | |
| + | |
| +static int | |
| +hdclient(Conv *c) | |
| +{ | |
| + char *realm, *passwd, *user, *f[4], *s, resp[MD5dlen*2+1]; | |
| + int ret; | |
| + Key *k; | |
| + | |
| + ret = -1; | |
| + s = nil; | |
| + | |
| + c->state = "keylookup"; | |
| + k = keyfetch(c, "%A", c->attr); | |
| + if(k == nil) | |
| + goto out; | |
| + | |
| + user = strfindattr(k->attr, "user"); | |
| + realm = strfindattr(k->attr, "realm"); | |
| + passwd = strfindattr(k->attr, "!password"); | |
| + | |
| + if(convreadm(c, &s) < 0) | |
| + goto out; | |
| + if(tokenize(s, f, 4) != 3){ | |
| + werrstr("bad challenge -- want nonce method uri"); | |
| + goto out; | |
| + } | |
| + | |
| + digest(user, realm, passwd, f[0], f[1], f[2], resp); | |
| + convwrite(c, resp, strlen(resp)); | |
| + ret = 0; | |
| + | |
| +out: | |
| + free(s); | |
| + keyclose(k); | |
| + return ret; | |
| +} | |
| + | |
| +static void | |
| +strtolower(char *s) | |
| +{ | |
| + while(*s){ | |
| + *s = tolower(*s); | |
| + s++; | |
| + } | |
| +} | |
| + | |
| +static void | |
| +digest(char *user, char *realm, char *passwd, | |
| + char *nonce, char *method, char *uri, | |
| + char *dig) | |
| +{ | |
| + uchar b[MD5dlen]; | |
| + char ha1[MD5dlen*2+1]; | |
| + char ha2[MD5dlen*2+1]; | |
| + DigestState *s; | |
| + | |
| + /* | |
| + * H(A1) = MD5(uid + ":" + realm ":" + passwd) | |
| + */ | |
| + s = md5((uchar*)user, strlen(user), nil, nil); | |
| + md5((uchar*)":", 1, nil, s); | |
| + md5((uchar*)realm, strlen(realm), nil, s); | |
| + md5((uchar*)":", 1, nil, s); | |
| + md5((uchar*)passwd, strlen(passwd), b, s); | |
| + enc16(ha1, sizeof(ha1), b, MD5dlen); | |
| + strtolower(ha1); | |
| + | |
| + /* | |
| + * H(A2) = MD5(method + ":" + uri) | |
| + */ | |
| + s = md5((uchar*)method, strlen(method), nil, nil); | |
| + md5((uchar*)":", 1, nil, s); | |
| + md5((uchar*)uri, strlen(uri), b, s); | |
| + enc16(ha2, sizeof(ha2), b, MD5dlen); | |
| + strtolower(ha2); | |
| + | |
| + /* | |
| + * digest = MD5(H(A1) + ":" + nonce + ":" + H(A2)) | |
| + */ | |
| + s = md5((uchar*)ha1, MD5dlen*2, nil, nil); | |
| + md5((uchar*)":", 1, nil, s); | |
| + md5((uchar*)nonce, strlen(nonce), nil, s); | |
| + md5((uchar*)":", 1, nil, s); | |
| + md5((uchar*)ha2, MD5dlen*2, b, s); | |
| + enc16(dig, MD5dlen*2+1, b, MD5dlen); | |
| + strtolower(dig); | |
| +} | |
| + | |
| +static Role hdroles[] = | |
| +{ | |
| + "client", hdclient, | |
| + 0 | |
| +}; | |
| + | |
| +Proto httpdigest = | |
| +{ | |
| + "httpdigest", | |
| + hdroles, | |
| + "user? realm? !password?", | |
| + nil, | |
| + nil | |
| +}; | |
| diff --git a/src/cmd/auth/factotum/main.c b/src/cmd/auth/factotum/main.c | |
| t@@ -48,6 +48,9 @@ threadmain(int argc, char *argv[]) | |
| case 'a': | |
| authaddr = EARGF(usage()); | |
| break; | |
| + case 'd': | |
| + debug = 1; | |
| + break; | |
| case 'g': | |
| usage(); | |
| case 'm': | |
| diff --git a/src/cmd/auth/factotum/mkfile b/src/cmd/auth/factotum/mkfile | |
| t@@ -5,10 +5,12 @@ PROTO=\ | |
| apop.$O\ | |
| chap.$O\ | |
| dsa.$O\ | |
| + httpdigest.$O\ | |
| p9any.$O\ | |
| p9sk1.$O\ | |
| pass.$O\ | |
| rsa.$O\ | |
| + wep.$O\ | |
| OFILES=\ | |
| $PROTO\ | |
| t@@ -24,9 +26,9 @@ OFILES=\ | |
| pkcs1.$O\ | |
| proto.$O\ | |
| rpc.$O\ | |
| + secstore.$O\ | |
| util.$O\ | |
| xio.$O\ | |
| - secstore.$O\ | |
| HFILES=dat.h | |
| diff --git a/src/cmd/auth/factotum/p9cr.c b/src/cmd/auth/factotum/p9cr.c | |
| t@@ -18,16 +18,6 @@ | |
| #include "dat.h" | |
| static int | |
| -p9crcheck(Key *k) | |
| -{ | |
| - if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!passwo… | |
| - werrstr("need user and !password attributes"); | |
| - return -1; | |
| - } | |
| - return 0; | |
| -} | |
| - | |
| -static int | |
| p9crclient(Conv *c) | |
| { | |
| char *chal, *pw, *res, *user; | |
| t@@ -113,10 +103,11 @@ out: | |
| static int | |
| p9crserver(Conv *c) | |
| { | |
| - char chal[APOPCHALLEN], *user, *resp; | |
| - ServerState s; | |
| - int astype, ret; | |
| + char chal[MAXCHAL], *user, *resp; | |
| + int astype, challen, asfd, fd, ret; | |
| Attr *a; | |
| + Key *k; | |
| + char *hostid, *dom; | |
| ret = -1; | |
| user = nil; | |
| t@@ -124,28 +115,32 @@ p9crserver(Conv *c) | |
| memset(&s, 0, sizeof s); | |
| s.asfd = -1; | |
| - if(c->proto == &apop) | |
| - astype = AuthApop; | |
| - else if(c->proto == &cram) | |
| - astype = AuthCram; | |
| - else{ | |
| + if(c->proto == &p9cr){ | |
| + astype = AuthChal; | |
| + challen = NETCHLEN; | |
| + }else if(c->proto == &vnc){ | |
| + astype = AuthVnc; | |
| + challen = MAXCHAL; | |
| + }else{ | |
| werrstr("bad proto"); | |
| goto out; | |
| } | |
| c->state = "find key"; | |
| - if((s.k = plan9authkey(c->attr)) == nil) | |
| + if((k = plan9authkey(c->attr)) == nil) | |
| goto out; | |
| - a = copyattr(s.k->attr); | |
| +/* | |
| + a = copyattr(k->attr); | |
| a = delattr(a, "proto"); | |
| c->attr = addattrs(c->attr, a); | |
| freeattr(a); | |
| +*/ | |
| c->state = "authdial"; | |
| - s.hostid = strfindattr(s.k->attr, "user"); | |
| - s.dom = strfindattr(s.k->attr, "dom"); | |
| - if((s.asfd = xioauthdial(nil, s.dom)) < 0){ | |
| + hostid = strfindattr(s.k->attr, "user"); | |
| + dom = strfindattr(s.k->attr, "dom"); | |
| + if((asfd = xioauthdial(nil, s.dom)) < 0){ | |
| werrstr("authdial %s: %r", s.dom); | |
| goto out; | |
| } | |
| t@@ -196,7 +191,7 @@ out: | |
| keyclose(s.k); | |
| free(user); | |
| free(resp); | |
| -// xioclose(s.asfd); | |
| + xioclose(s.asfd); | |
| return ret; | |
| } | |
| diff --git a/src/cmd/auth/factotum/proto.c b/src/cmd/auth/factotum/proto.c | |
| t@@ -5,6 +5,7 @@ extern Proto apop; /* apop.c */ | |
| extern Proto chap; /* chap.c */ | |
| extern Proto cram; /* apop.c */ | |
| extern Proto dsa; /* dsa.c */ | |
| +extern Proto httpdigest; /* httpdigest.c */ | |
| extern Proto mschap; /* chap.c */ | |
| extern Proto p9any; /* p9any.c */ | |
| extern Proto p9sk1; /* p9sk1.c */ | |
| t@@ -16,6 +17,7 @@ Proto *prototab[] = { | |
| &apop, | |
| &cram, | |
| &dsa, | |
| + &httpdigest, | |
| &p9any, | |
| &p9sk1, | |
| &p9sk2, | |
| diff --git a/src/cmd/auth/factotum/secstore.c b/src/cmd/auth/factotum/secstore.c | |
| t@@ -45,8 +45,11 @@ havesecstore(void) | |
| hnputs(buf, 0x8000+n-2); | |
| fd = secdial(); | |
| - if(fd < 0) | |
| + if(fd < 0){ | |
| + if(debug) | |
| + fprint(2, "secdial: %r\n"); | |
| return 0; | |
| + } | |
| if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){ | |
| close(fd); | |
| return 0; | |
| diff --git a/src/cmd/auth/factotum/wep.c b/src/cmd/auth/factotum/wep.c | |
| t@@ -0,0 +1,83 @@ | |
| +/* | |
| + * Copy WEP key to ethernet device. | |
| + */ | |
| + | |
| +#include "std.h" | |
| +#include "dat.h" | |
| + | |
| +static int | |
| +wepclient(Conv *c) | |
| +{ | |
| + char *dev, buf[128], *p, *kp; | |
| + Key *k; | |
| + int ret, fd, cfd; | |
| + | |
| + fd = cfd = -1; | |
| + ret = -1; | |
| + dev = nil; | |
| + | |
| + if((k = keylookup("%A !key1?", c->attr)) == nil | |
| + && (k = keylookup("%A !key2?", c->attr)) == nil | |
| + && (k = keylookup("%A !key3?", c->attr)) == nil){ | |
| + werrstr("cannot find wep keys"); | |
| + goto out; | |
| + } | |
| + if(convreadm(c, &dev) < 0) | |
| + return -1; | |
| + if(dev[0] != '#' || dev[1] != 'l'){ | |
| + werrstr("not an ethernet device: %s", dev); | |
| + goto out; | |
| + } | |
| + snprint(buf, sizeof buf, "%s!0", dev); | |
| + if((fd = dial(buf, 0, 0, &cfd)) < 0) | |
| + goto out; | |
| + if(!(p = strfindattr(k->privattr, kp="!key1")) | |
| + && !(p = strfindattr(k->privattr, kp="key2")) | |
| + && !(p = strfindattr(k->privattr, kp="key3"))){ | |
| + werrstr("lost key"); | |
| + goto out; | |
| + } | |
| + if(fprint(cfd, "%s %q", kp+1, p) < 0) | |
| + goto out; | |
| + if((p = strfindattr(k->attr, "essid")) != nil | |
| + && fprint(cfd, "essid %q", p) < 0) | |
| + goto out; | |
| + if(fprint(cfd, "crypt on") < 0) | |
| + goto out; | |
| + ret = 0; | |
| + | |
| +out: | |
| + free(dev); | |
| + if(cfd >= 0) | |
| + close(cfd); | |
| + if(fd >= 0) | |
| + close(fd); | |
| + keyclose(k); | |
| + return ret; | |
| +} | |
| + | |
| +static int | |
| +wepcheck(Key *k) | |
| +{ | |
| + if(strfindattr(k->privattr, "!key1") == nil | |
| + && strfindattr(k->privattr, "!key2") == nil | |
| + && strfindattr(k->privattr, "!key3") == nil){ | |
| + werrstr("need !key1, !key2, or !key3 attribute"); | |
| + return -1; | |
| + } | |
| + return 0; | |
| +} | |
| + | |
| +static Role weproles[] = { | |
| + "client", wepclient, | |
| + 0 | |
| +}; | |
| + | |
| +Proto wep = | |
| +{ | |
| + "wep", | |
| + weproles, | |
| + nil, | |
| + wepcheck, | |
| + nil | |
| +}; |