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 
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/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
+};
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, "!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;
 }
 
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
+};