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
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

View file

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

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':
authaddr = EARGF(usage());
break;
case 'd':
debug = 1;
break;
case 'g':
usage();
case 'm':

View file

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

View file

@ -17,16 +17,6 @@
#include "std.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
p9crclient(Conv *c)
{
@ -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;
}

View file

@ -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,

View file

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

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