diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-01-25 07:49:50 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-01-25 07:49:50 +0100 |
commit | 5649042bff26fa0594217432d085b9f96b923298 (patch) | |
tree | 83d346c4eef189e315c30590baf34aeb14a03342 /sys/src/cmd/auth | |
parent | 91d3af942aeb9f102f3799b848f1798cc23ee002 (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/auth')
-rw-r--r-- | sys/src/cmd/auth/factotum/chap.c | 47 | ||||
-rw-r--r-- | sys/src/cmd/auth/factotum/dat.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/auth/factotum/fs.c | 1 |
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, |