summaryrefslogtreecommitdiff
path: root/sys/src/cmd
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-01-25 07:49:50 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-01-25 07:49:50 +0100
commit5649042bff26fa0594217432d085b9f96b923298 (patch)
tree83d346c4eef189e315c30590baf34aeb14a03342 /sys/src/cmd
parent91d3af942aeb9f102f3799b848f1798cc23ee002 (diff)
factotum: implement proto=mschapv2 client role
this is used for wpa2 enterprise peap/mschapv2. server role is not implemented as that would require changing the wire format on the auth server. the naming is unfortunate as we already have proto=mschap2 which really refers to ntlmv2.
Diffstat (limited to 'sys/src/cmd')
-rw-r--r--sys/src/cmd/auth/factotum/chap.c47
-rw-r--r--sys/src/cmd/auth/factotum/dat.h2
-rw-r--r--sys/src/cmd/auth/factotum/fs.c1
3 files changed, 46 insertions, 4 deletions
diff --git a/sys/src/cmd/auth/factotum/chap.c b/sys/src/cmd/auth/factotum/chap.c
index 6430dce43..ca6e0f173 100644
--- a/sys/src/cmd/auth/factotum/chap.c
+++ b/sys/src/cmd/auth/factotum/chap.c
@@ -24,6 +24,7 @@ enum {
MShashlen = 16,
MSchallen = 8,
MSresplen = 24,
+ MSchallenv2 = 16,
Chapreplylen = MD5LEN+1,
MSchapreplylen = 24+24,
@@ -86,13 +87,16 @@ chapinit(Proto *p, Fsstate *fss)
if((iscli = isclient(_strfindattr(fss->attr, "role"))) < 0)
return failure(fss, nil);
+ if(!iscli && p == &mschapv2)
+ return failure(fss, "role must be client");
+
s = emalloc(sizeof *s);
s->nresp = 0;
s->nsecret = 0;
fss->phasename = phasenames;
fss->maxphase = Maxphase;
s->asfd = -1;
- if(p == &mschap || p == &mschap2){
+ if(p == &mschap || p == &mschapv2 || p == &mschap2){
s->astype = AuthMSchap;
}else {
s->astype = AuthChap;
@@ -173,8 +177,35 @@ chapwrite(Fsstate *fss, void *va, uint n)
if(dom == nil)
dom = "";
s->nresp = domschap2(v, user, dom, (uchar*)a, s->resp, sizeof(s->resp));
- } else
+ }
+ else if(fss->proto == &mschapv2 || n == MSchallenv2){
+ uchar pchal[MSchallenv2];
+ DigestState *ds;
+
+ if(n < MSchallenv2)
+ break;
+ user = _strfindattr(fss->attr, "user");
+ if(user == nil)
+ break;
+
+ memrandom(pchal, MSchallenv2);
+
+ /* ChallengeHash() */
+ ds = sha1(pchal, MSchallenv2, nil, nil);
+ ds = sha1((uchar*)a, MSchallenv2, nil, ds);
+ sha1((uchar*)user, strlen(user), reply, ds);
+
+ s->nresp = domschap(v, reply, s->resp, sizeof(s->resp));
+ if(s->nresp <= 0)
+ break;
+
+ mcr = (MSchapreply*)s->resp;
+ memset(mcr->LMresp, 0, sizeof(mcr->LMresp));
+ memmove(mcr->LMresp, pchal, MSchallenv2);
+ }
+ else {
s->nresp = domschap(v, (uchar*)a, s->resp, sizeof(s->resp));
+ }
break;
case AuthChap:
if(n < ChapChallen+1)
@@ -379,8 +410,18 @@ Proto mschap = {
.keyprompt= "!password?"
};
+Proto mschapv2 = {
+.name= "mschapv2",
+.init= chapinit,
+.write= chapwrite,
+.read= chapread,
+.close= chapclose,
+.addkey= replacekey,
+.keyprompt= "user? !password?"
+};
+
Proto mschap2 = {
-.name= "mschap2",
+.name= "mschap2", /* really NTLMv2 */
.init= chapinit,
.write= chapwrite,
.read= chapread,
diff --git a/sys/src/cmd/auth/factotum/dat.h b/sys/src/cmd/auth/factotum/dat.h
index 92314f2a4..10cdc9a34 100644
--- a/sys/src/cmd/auth/factotum/dat.h
+++ b/sys/src/cmd/auth/factotum/dat.h
@@ -225,7 +225,7 @@ void writehostowner(char*);
/* protocols */
extern Proto apop, cram; /* apop.c */
extern Proto p9any, p9sk1, p9sk2; /* p9sk.c */
-extern Proto chap, mschap, mschap2; /* chap.c */
+extern Proto chap, mschap, mschapv2, mschap2; /* chap.c */
extern Proto p9cr, vnc; /* p9cr.c */
extern Proto pass; /* pass.c */
extern Proto rsa; /* rsa.c */
diff --git a/sys/src/cmd/auth/factotum/fs.c b/sys/src/cmd/auth/factotum/fs.c
index b5f2c1b22..b9a51d383 100644
--- a/sys/src/cmd/auth/factotum/fs.c
+++ b/sys/src/cmd/auth/factotum/fs.c
@@ -31,6 +31,7 @@ prototab[] =
&cram,
&httpdigest,
&mschap,
+ &mschapv2,
&mschap2,
&p9any,
&p9cr,