URI: 
       tnew - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 1757e76a73818470d0d8d062ca2d05e3fc7c9524
   DIR parent 45993349d8414bdf7eb24d8996e02aa4d53951ad
  HTML 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(-)
       ---
   DIR 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
   DIR 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
        };
       +
   DIR diff --git a/src/cmd/auth/factotum/httpdigest.c b/src/cmd/auth/factotum/httpdigest.c
       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
       +};
   DIR 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':
   DIR 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
        
   DIR 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, "!password")){
       -                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;
        }
        
   DIR 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,
   DIR 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;
   DIR 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
       +};