aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/auth/factotum
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/auth/factotum')
-rw-r--r--src/cmd/auth/factotum/apop.c25
-rw-r--r--src/cmd/auth/factotum/httpdigest.c119
-rw-r--r--src/cmd/auth/factotum/main.c3
-rw-r--r--src/cmd/auth/factotum/mkfile4
-rw-r--r--src/cmd/auth/factotum/p9cr.c43
-rw-r--r--src/cmd/auth/factotum/proto.c2
-rw-r--r--src/cmd/auth/factotum/secstore.c5
-rw-r--r--src/cmd/auth/factotum/wep.c83
8 files changed, 247 insertions, 37 deletions
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
@@ -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;
}
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
+};