#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include <ip.h>
#include <libsec.h>
#include "dat.h"
#include "fns.h"
enum {
AvpFlagV = 1<<7,
AvpFlagM = 1<<6,
AVPSHORTHDR = 8,
AVPLONGHDR = 12,
AvpUserName = 1,
AvpUserPassword = 2,
};
typedef struct AVP {
uchar code[4];
uchar flags;
uchar ln[3];
uchar vendorid[4]; //optional, if V flag set
} AVP;
static int
buildAPV(uchar *b, int vid, int code, uchar*s, int l)
{
int sz;
AVP *a;
uchar *p;
a = (AVP*)b;
hnputl(a->code, code);
a->flags = AvpFlagM;
if (vid != 0) {
a->flags |= AvpFlagV;
hnputl(a->vendorid, vid);
p = b+AVPLONGHDR;
} else {
p = b+AVPSHORTHDR;
}
memcpy(p, s, l);
sz = (p-b)+l;
p += l;
put24(a->ln, sz);
while(sz%4 != 0){
*p = 0;
p ++;
sz ++;
}
return sz;
}
void
doTTLSphase2(int fd)
{
uchar buf[Pktlen], *p;
int len, n;
char pwdbuf[256];
int pwdlen;
loglog("phase2 fd=%d...", fd);
if (fd < 0) {
loglog("cannot do TTLSphase2: fd=%d < 0 ", fd);
return;
}
// do PAP: send username, password, encoded as AVP
len = 0;
p = buf;
n = buildAPV(p, 0, AvpUserName, (uchar*)myId, strlen(myId));
len += n;
p += n;
memset(pwdbuf, 0, sizeof(pwdbuf));
strcpy(pwdbuf, myPasswd);
pwdlen=strlen(myPasswd);
if (pwdlen%16 != 0)
pwdlen += (16 - (pwdlen%16 ));
n = buildAPV(p, 0, AvpUserPassword, (uchar*)pwdbuf, pwdlen);
len += n;
p += n;
USED(p);
n = write(fd, buf, len);
if (n < 0)
logall("doTTLSphase2 write tlsfd failed: %r");
if (n != len)
logall("doTTLSphase2 write tlsfd ()n!=len: n=%d len=%d", n, len);
if (debug) print("doTTLSphase2 written %d of %d\n", n, len);
loglog("phase2 fd=%d ... data sent", fd);
}
|