commit 1757e76a73818470d0d8d062ca2d05e3fc7c9524 from: rsc date: Sun Feb 13 22:09:47 2005 UTC new commit - 45993349d8414bdf7eb24d8996e02aa4d53951ad commit + 1757e76a73818470d0d8d062ca2d05e3fc7c9524 blob - 5a9f6fda2f5c858ce1b204948fa0d0f4d7c692f2 blob + fc6a4a4c7ce47d7a97af2a4efc96b7cbb4301999 --- bin/.cvsignore +++ bin/.cvsignore @@ -16,6 +16,8 @@ adict aescbc ajuke ascii +asn12dsa +asn12rsa astro auxclog auxstats @@ -41,6 +43,8 @@ deroff dial dict diff +dsa2ssh +dsagen dump9660 echo ed @@ -92,6 +96,7 @@ mp3info mtime namespace ndbipquery +ndbmkdb ndbmkhash ndbmkhosts ndbquery @@ -99,7 +104,10 @@ netkey news notes p +passwd pbd +pemdecode +pemencode pic plot plumb @@ -113,8 +121,15 @@ psdownload ramfs rc read +readcons rio rm +rsa2csr +rsa2pub +rsa2ssh +rsa2x509 +rsafill +rsagen sam samterm scat @@ -128,10 +143,12 @@ sleep sort split sprog +ssh-agent stats strings sum tail +tar tbl tcolors tcs blob - 8e340d474a68450d0100bf1e39525098f61ea3b7 blob + 5703571d87111feed48ba2b80ecdea47873320a0 --- src/cmd/auth/factotum/apop.c +++ 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 }; + blob - /dev/null blob + 70815a562ab159fae2f93c576744539f343803a7 (mode 644) --- /dev/null +++ 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 +}; blob - 1a8c4ffc6fabbb0f7178a5fcecc42661f48204bf blob + f1e647745acb08e28cbe7eda75c167fd50076c8e --- src/cmd/auth/factotum/main.c +++ 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': blob - d6d58af97be642cb557767b199ec3d937401371f blob + e5475f81d249de5de8ff79f7f28f9a6596d9d5f0 --- src/cmd/auth/factotum/mkfile +++ 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 blob - 7f53e44782057f8f4aa67ba923ab8530b8490e38 blob + abbad4c4f90fa44641fae1dc2ce03b16b122f40e --- src/cmd/auth/factotum/p9cr.c +++ src/cmd/auth/factotum/p9cr.c @@ -18,16 +18,6 @@ #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) { char *chal, *pw, *res, *user; @@ -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; } blob - 5a65e5cd8ffae1c8575c8aa549616f7c255612af blob + 97da15ec1a51cad14bfbf37ee66a7634edf0bab6 --- src/cmd/auth/factotum/proto.c +++ 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, blob - d82d7862a48e8b2692d1e0572a10e3e30f067594 blob + 0156e170f6859b30bf1943f5b884d2bdcb87b30c --- src/cmd/auth/factotum/secstore.c +++ 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; blob - /dev/null blob + 1d516db288bd3f166fe2a1b15ab520449b501fea (mode 644) --- /dev/null +++ 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 +};