ip/sol: use httpdigest authentication

httpdigest authentication allows one to share the key
in factotum with the amt webserver on https://target:16993
This commit is contained in:
cinap_lenrek 2022-04-02 21:47:00 +00:00
parent 4a401e7703
commit 31294b6c1a
2 changed files with 68 additions and 35 deletions

View file

@ -18,15 +18,16 @@ enabled machines.
The protocol runs over tcp port 16995 and The protocol runs over tcp port 16995 and
and is protected using TLS. and is protected using TLS.
.PP .PP
For authentication, a username and password For authentication, a
is required. The default username, unless .B proto=httpdigest
key with a username and password is required.
The default username, unless
given by the given by the
.B -u .B -u
.I user .I user
argument, is "admin". argument, is "admin".
The password will be prompted and kept in The password will be prompted and kept in
factotum, tagged with the servers x509 factotum.
crtificate thumbprint.
.PP .PP
The The
.B -r .B -r

View file

@ -15,24 +15,24 @@ enum {
HEATBEAT_INTERVAL = 5000, HEATBEAT_INTERVAL = 5000,
}; };
int pid = 0, raw = -1, fd = -1; int authok = 0, pid = 0, raw = -1, fd = -1;
char thumbfile[] = "/sys/lib/tls/amt";
Biobuf bin, bout; Biobuf bin, bout;
jmp_buf reconnect; jmp_buf reconnect;
void void
killpid(void) killpid(void)
{ {
postnote(PNPROC, pid, "kill"); if(pid != 0){
postnote(PNPROC, pid, "kill");
pid = 0;
}
} }
void void
eof(void) eof(void)
{ {
if(pid == 0) sysfatal("eof: %r"); if(!authok) sysfatal("eof: %r");
killpid(); killpid();
pid = 0;
longjmp(reconnect, 1); longjmp(reconnect, 1);
} }
@ -123,6 +123,59 @@ send(char *fmt, ...)
} }
} }
void
digestauth(char *server, char *user, char *method, char *url)
{
char realm[256+1], nonce[256+1], qop[256+1], nc[10], cnonce[32+1], chal[1024], resp[1024], ouser[256];
static uint counter;
int reply, ok, n;
send("lblb[__b[____", 0x13, 4,
1+strlen(user) + 2 + 1+strlen(url) + 4,
strlen(user), user, strlen(user),
strlen(url), url, strlen(url));
recv("lbl", &reply, &ok, &n);
if(reply != 0x114 || ok != 4 || n == 0)
sysfatal("bad auth reply: %x %x", reply, ok);
recv("b", &n);
recv("[", realm, n);
realm[n] = '\0';
recv("b", &n);
recv("[", nonce, n);
nonce[n] = '\0';
recv("b", &n);
recv("[", qop, n);
qop[n] = '\0';
genrandom((uchar*)resp, 32);
snprint(cnonce, sizeof(cnonce), "%.32H", resp);
snprint(nc, sizeof(nc), "%8.8ud", ++counter);
n = snprint(chal, sizeof(chal), "%s:%s:%s:%s %s %s", nonce, nc, cnonce, qop, method, url);
n = auth_respond(chal, n, ouser, sizeof(ouser), resp, sizeof(resp), auth_getkey,
"proto=httpdigest role=client server=%q realm=%q user=%q", server, realm, user);
if(n < 0)
sysfatal("auth_respond: %r");
send("lblb[b[b[b[b[b[b[b[", 0x13, 4,
1+strlen(ouser)+1+strlen(realm)+1+strlen(nonce)+1+strlen(url)+
1+strlen(cnonce)+1+strlen(nc)+1+n+1+strlen(qop),
strlen(ouser), ouser, strlen(ouser),
strlen(realm), realm, strlen(realm),
strlen(nonce), nonce, strlen(nonce),
strlen(url), url, strlen(url),
strlen(cnonce), cnonce, strlen(cnonce),
strlen(nc), nc, strlen(nc),
n, resp, n,
strlen(qop), qop, strlen(qop));
recv("lb*", &reply, &ok);
if(reply != 0x14 && ok != 4)
sysfatal("bad auth reply: %x %x", reply, ok);
}
void void
usage(void) usage(void)
{ {
@ -133,10 +186,9 @@ usage(void)
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
uchar thumb[SHA2_256dlen], buf[MAX_TRANSMIT_BUFFER]; uchar buf[MAX_TRANSMIT_BUFFER];
TLSconn tls; TLSconn tls;
char *user = "admin"; char *user = "admin";
UserPasswd *up = nil;
int reply, ok, n; int reply, ok, n;
fmtinstall('[', encodefmt); fmtinstall('[', encodefmt);
@ -187,26 +239,11 @@ Reconnect:
fd = tlsClient(fd, &tls); fd = tlsClient(fd, &tls);
if(fd < 0) if(fd < 0)
sysfatal("tls client: %r"); sysfatal("tls client: %r");
sha2_256(tls.cert, tls.certlen, buf, nil);
free(tls.cert); free(tls.cert);
free(tls.sessionID); free(tls.sessionID);
memset(&tls, 0, sizeof(tls)); memset(&tls, 0, sizeof(tls));
if(up == nil){ authok = 0;
memmove(thumb, buf, sizeof(thumb));
up = auth_getuserpasswd(auth_getkey,
"proto=pass service=sol user=%q server=%q thumb='%.*['",
user, argv[0], sizeof(thumb), thumb);
if(up == nil)
sysfatal("auth_getuserpasswd: %r");
close(fd);
goto Reconnect;
}
if(memcmp(buf, thumb, sizeof(thumb)) != 0)
sysfatal("certificate thumb changed: %.*[, expected %.*[",
sizeof(thumb), buf, sizeof(thumb), thumb);
Binit(&bin, fd, OREAD); Binit(&bin, fd, OREAD);
Binit(&bout, fd, OWRITE); Binit(&bout, fd, OWRITE);
if(setjmp(reconnect)){ if(setjmp(reconnect)){
@ -221,13 +258,8 @@ Reconnect:
if(reply != 0x11 || ok != 1) if(reply != 0x11 || ok != 1)
sysfatal("bad session reply: %x %x", reply, ok); sysfatal("bad session reply: %x %x", reply, ok);
send("lblb[b[", 0x13, 1, digestauth(argv[0], user, "POST", "/RedirectionService");
strlen(up->user)+1+strlen(up->passwd)+1, authok = 1;
strlen(up->user), up->user, strlen(up->user),
strlen(up->passwd), up->passwd, strlen(up->passwd));
recv("lb*", &reply, &ok);
if(reply != 0x14 || ok != 1)
sysfatal("bad auth reply: %x %x", reply, ok);
send("l____wwwwww____", 0x20, send("l____wwwwww____", 0x20,
MAX_TRANSMIT_BUFFER, MAX_TRANSMIT_BUFFER,