From 1757e76a73818470d0d8d062ca2d05e3fc7c9524 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 13 Feb 2005 22:09:47 +0000 Subject: new --- src/cmd/auth/factotum/apop.c | 25 ++++---- src/cmd/auth/factotum/httpdigest.c | 119 +++++++++++++++++++++++++++++++++++++ src/cmd/auth/factotum/main.c | 3 + src/cmd/auth/factotum/mkfile | 4 +- src/cmd/auth/factotum/p9cr.c | 43 ++++++-------- src/cmd/auth/factotum/proto.c | 2 + src/cmd/auth/factotum/secstore.c | 5 +- src/cmd/auth/factotum/wep.c | 83 ++++++++++++++++++++++++++ 8 files changed, 247 insertions(+), 37 deletions(-) create mode 100644 src/cmd/auth/factotum/httpdigest.c create mode 100644 src/cmd/auth/factotum/wep.c (limited to 'src/cmd/auth/factotum') diff --git a/src/cmd/auth/factotum/apop.c b/src/cmd/auth/factotum/apop.c index 8e340d47..5703571d 100644 --- a/src/cmd/auth/factotum/apop.c +++ b/src/cmd/auth/factotum/apop.c @@ -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 @@ -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" @@ -240,7 +240,7 @@ out: keyclose(s.k); free(user); free(resp); -// xioclose(s.asfd); + xioclose(s.asfd); return ret; } @@ -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/httpdigest.c new file mode 100644 index 00000000..70815a56 --- /dev/null +++ b/src/cmd/auth/factotum/httpdigest.c @@ -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 index 1a8c4ffc..f1e64774 100644 --- a/src/cmd/auth/factotum/main.c +++ b/src/cmd/auth/factotum/main.c @@ -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 index d6d58af9..e5475f81 100644 --- a/src/cmd/auth/factotum/mkfile +++ b/src/cmd/auth/factotum/mkfile @@ -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\ @@ -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 index 7f53e447..abbad4c4 100644 --- a/src/cmd/auth/factotum/p9cr.c +++ b/src/cmd/auth/factotum/p9cr.c @@ -17,16 +17,6 @@ #include "std.h" #include "dat.h" -static int -p9crcheck(Key *k) -{ - if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){ - werrstr("need user and !password attributes"); - return -1; - } - return 0; -} - static int p9crclient(Conv *c) { @@ -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; @@ -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; } @@ -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 index 5a65e5cd..97da15ec 100644 --- a/src/cmd/auth/factotum/proto.c +++ b/src/cmd/auth/factotum/proto.c @@ -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 */ @@ -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 index d82d7862..0156e170 100644 --- a/src/cmd/auth/factotum/secstore.c +++ b/src/cmd/auth/factotum/secstore.c @@ -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 new file mode 100644 index 00000000..1d516db2 --- /dev/null +++ b/src/cmd/auth/factotum/wep.c @@ -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 +}; -- cgit v1.2.3