This commit is contained in:
rsc 2005-02-13 22:09:47 +00:00
parent 45993349d8
commit 1757e76a73
9 changed files with 264 additions and 37 deletions

View file

@ -16,6 +16,8 @@ adict
aescbc aescbc
ajuke ajuke
ascii ascii
asn12dsa
asn12rsa
astro astro
auxclog auxclog
auxstats auxstats
@ -41,6 +43,8 @@ deroff
dial dial
dict dict
diff diff
dsa2ssh
dsagen
dump9660 dump9660
echo echo
ed ed
@ -92,6 +96,7 @@ mp3info
mtime mtime
namespace namespace
ndbipquery ndbipquery
ndbmkdb
ndbmkhash ndbmkhash
ndbmkhosts ndbmkhosts
ndbquery ndbquery
@ -99,7 +104,10 @@ netkey
news news
notes notes
p p
passwd
pbd pbd
pemdecode
pemencode
pic pic
plot plot
plumb plumb
@ -113,8 +121,15 @@ psdownload
ramfs ramfs
rc rc
read read
readcons
rio rio
rm rm
rsa2csr
rsa2pub
rsa2ssh
rsa2x509
rsafill
rsagen
sam sam
samterm samterm
scat scat
@ -128,10 +143,12 @@ sleep
sort sort
split split
sprog sprog
ssh-agent
stats stats
strings strings
sum sum
tail tail
tar
tbl tbl
tcolors tcolors
tcs tcs

View file

@ -6,7 +6,7 @@
* Protocol: * Protocol:
* *
* S -> C: random@domain * S -> C: random@domain
* C -> S: hex-response * C -> S: user hex-response
* S -> C: ok * S -> C: ok
* *
* Note that this is the protocol between factotum and the local * Note that this is the protocol between factotum and the local
@ -15,7 +15,7 @@
* programs. * programs.
* *
* If S sends "bad [msg]" instead of "ok", that is a hint that the key is bad. * 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" #include "std.h"
@ -240,7 +240,7 @@ out:
keyclose(s.k); keyclose(s.k);
free(user); free(user);
free(resp); free(resp);
// xioclose(s.asfd); xioclose(s.asfd);
return ret; return ret;
} }
@ -336,15 +336,18 @@ apoproles[] =
}; };
Proto apop = { Proto apop = {
.name= "apop", "apop",
.roles= apoproles, apoproles,
.checkkey= apopcheck, "user? !password?",
.keyprompt= "user? !password?", apopcheck,
nil
}; };
Proto cram = { Proto cram = {
.name= "cram", "cram",
.roles= apoproles, apoproles,
.checkkey= apopcheck, "user? !password?",
.keyprompt= "user? !password?", apopcheck,
nil
}; };

View file

@ -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
};

View file

@ -48,6 +48,9 @@ threadmain(int argc, char *argv[])
case 'a': case 'a':
authaddr = EARGF(usage()); authaddr = EARGF(usage());
break; break;
case 'd':
debug = 1;
break;
case 'g': case 'g':
usage(); usage();
case 'm': case 'm':

View file

@ -5,10 +5,12 @@ PROTO=\
apop.$O\ apop.$O\
chap.$O\ chap.$O\
dsa.$O\ dsa.$O\
httpdigest.$O\
p9any.$O\ p9any.$O\
p9sk1.$O\ p9sk1.$O\
pass.$O\ pass.$O\
rsa.$O\ rsa.$O\
wep.$O\
OFILES=\ OFILES=\
$PROTO\ $PROTO\
@ -24,9 +26,9 @@ OFILES=\
pkcs1.$O\ pkcs1.$O\
proto.$O\ proto.$O\
rpc.$O\ rpc.$O\
secstore.$O\
util.$O\ util.$O\
xio.$O\ xio.$O\
secstore.$O\
HFILES=dat.h HFILES=dat.h

View file

@ -17,16 +17,6 @@
#include "std.h" #include "std.h"
#include "dat.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 static int
p9crclient(Conv *c) p9crclient(Conv *c)
{ {
@ -113,10 +103,11 @@ out:
static int static int
p9crserver(Conv *c) p9crserver(Conv *c)
{ {
char chal[APOPCHALLEN], *user, *resp; char chal[MAXCHAL], *user, *resp;
ServerState s; int astype, challen, asfd, fd, ret;
int astype, ret;
Attr *a; Attr *a;
Key *k;
char *hostid, *dom;
ret = -1; ret = -1;
user = nil; user = nil;
@ -124,28 +115,32 @@ p9crserver(Conv *c)
memset(&s, 0, sizeof s); memset(&s, 0, sizeof s);
s.asfd = -1; s.asfd = -1;
if(c->proto == &apop) if(c->proto == &p9cr){
astype = AuthApop; astype = AuthChal;
else if(c->proto == &cram) challen = NETCHLEN;
astype = AuthCram; }else if(c->proto == &vnc){
else{ astype = AuthVnc;
challen = MAXCHAL;
}else{
werrstr("bad proto"); werrstr("bad proto");
goto out; goto out;
} }
c->state = "find key"; c->state = "find key";
if((s.k = plan9authkey(c->attr)) == nil) if((k = plan9authkey(c->attr)) == nil)
goto out; goto out;
a = copyattr(s.k->attr); /*
a = copyattr(k->attr);
a = delattr(a, "proto"); a = delattr(a, "proto");
c->attr = addattrs(c->attr, a); c->attr = addattrs(c->attr, a);
freeattr(a); freeattr(a);
*/
c->state = "authdial"; c->state = "authdial";
s.hostid = strfindattr(s.k->attr, "user"); hostid = strfindattr(s.k->attr, "user");
s.dom = strfindattr(s.k->attr, "dom"); dom = strfindattr(s.k->attr, "dom");
if((s.asfd = xioauthdial(nil, s.dom)) < 0){ if((asfd = xioauthdial(nil, s.dom)) < 0){
werrstr("authdial %s: %r", s.dom); werrstr("authdial %s: %r", s.dom);
goto out; goto out;
} }
@ -196,7 +191,7 @@ out:
keyclose(s.k); keyclose(s.k);
free(user); free(user);
free(resp); free(resp);
// xioclose(s.asfd); xioclose(s.asfd);
return ret; return ret;
} }

View file

@ -5,6 +5,7 @@ extern Proto apop; /* apop.c */
extern Proto chap; /* chap.c */ extern Proto chap; /* chap.c */
extern Proto cram; /* apop.c */ extern Proto cram; /* apop.c */
extern Proto dsa; /* dsa.c */ extern Proto dsa; /* dsa.c */
extern Proto httpdigest; /* httpdigest.c */
extern Proto mschap; /* chap.c */ extern Proto mschap; /* chap.c */
extern Proto p9any; /* p9any.c */ extern Proto p9any; /* p9any.c */
extern Proto p9sk1; /* p9sk1.c */ extern Proto p9sk1; /* p9sk1.c */
@ -16,6 +17,7 @@ Proto *prototab[] = {
&apop, &apop,
&cram, &cram,
&dsa, &dsa,
&httpdigest,
&p9any, &p9any,
&p9sk1, &p9sk1,
&p9sk2, &p9sk2,

View file

@ -45,8 +45,11 @@ havesecstore(void)
hnputs(buf, 0x8000+n-2); hnputs(buf, 0x8000+n-2);
fd = secdial(); fd = secdial();
if(fd < 0) if(fd < 0){
if(debug)
fprint(2, "secdial: %r\n");
return 0; return 0;
}
if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){ if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){
close(fd); close(fd);
return 0; return 0;

View file

@ -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
};