factotum: fix _adgetticket() filedescriptor race, add timeouts to all authserver transactions

This commit is contained in:
cinap_lenrek 2012-08-01 19:18:33 +02:00
parent acc239ef26
commit c7ad44a048
5 changed files with 54 additions and 22 deletions

View file

@ -209,6 +209,7 @@ static int
dochal(State *s) dochal(State *s)
{ {
char *dom, *user, trbuf[TICKREQLEN]; char *dom, *user, trbuf[TICKREQLEN];
int n;
s->asfd = -1; s->asfd = -1;
@ -232,9 +233,14 @@ dochal(State *s)
safecpy(s->tr.hostid, user, sizeof(s->tr.hostid)); safecpy(s->tr.hostid, user, sizeof(s->tr.hostid));
convTR2M(&s->tr, trbuf); convTR2M(&s->tr, trbuf);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN) alarm(30*1000);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN){
alarm(0);
goto err; goto err;
if(_asrdresp(s->asfd, s->chal, sizeof s->chal) <= 5) }
n = _asrdresp(s->asfd, s->chal, sizeof s->chal);
alarm(0);
if(n <= 5)
goto err; goto err;
return 0; return 0;
@ -253,25 +259,31 @@ doreply(State *s, char *user, char *response)
int n; int n;
Authenticator a; Authenticator a;
memrandom(s->tr.chal, CHALLEN);
safecpy(s->tr.uid, user, sizeof(s->tr.uid));
convTR2M(&s->tr, trbuf);
if((n=write(s->asfd, trbuf, TICKREQLEN)) != TICKREQLEN){
if(n >= 0)
werrstr("short write to auth server");
goto err;
}
/* send response to auth server */ /* send response to auth server */
if(strlen(response) != MD5dlen*2){ if(strlen(response) != MD5dlen*2){
werrstr("response not MD5 digest"); werrstr("response not MD5 digest");
goto err; goto err;
} }
if((n=write(s->asfd, response, MD5dlen*2)) != MD5dlen*2){
memrandom(s->tr.chal, CHALLEN);
safecpy(s->tr.uid, user, sizeof(s->tr.uid));
convTR2M(&s->tr, trbuf);
alarm(30*1000);
if((n=write(s->asfd, trbuf, TICKREQLEN)) != TICKREQLEN){
alarm(0);
if(n >= 0) if(n >= 0)
werrstr("short write to auth server"); werrstr("short write to auth server");
goto err; goto err;
} }
if(_asrdresp(s->asfd, ticket, TICKETLEN+AUTHENTLEN) < 0){ if((n=write(s->asfd, response, MD5dlen*2)) != MD5dlen*2){
alarm(0);
if(n >= 0)
werrstr("short write to auth server");
goto err;
}
n = _asrdresp(s->asfd, ticket, TICKETLEN+AUTHENTLEN);
alarm(0);
if(n < 0){
/* leave connection open so we can try again */ /* leave connection open so we can try again */
return -1; return -1;
} }

View file

@ -259,6 +259,7 @@ dochal(State *s)
{ {
char *dom, *user; char *dom, *user;
char trbuf[TICKREQLEN]; char trbuf[TICKREQLEN];
int ret;
s->asfd = -1; s->asfd = -1;
@ -278,12 +279,17 @@ dochal(State *s)
safecpy(s->tr.hostid, user, sizeof(s->tr.hostid)); safecpy(s->tr.hostid, user, sizeof(s->tr.hostid));
convTR2M(&s->tr, trbuf); convTR2M(&s->tr, trbuf);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN) alarm(30*1000);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN){
alarm(0);
goto err;
}
/* readn, not _asrdresp. needs to match auth.srv.c. */
ret = readn(s->asfd, s->chal, sizeof s->chal);
alarm(0);
if(ret != sizeof s->chal)
goto err; goto err;
/* readn, not _asrdresp. needs to match auth.srv.c. */
if(readn(s->asfd, s->chal, sizeof s->chal) != sizeof s->chal)
goto err;
return 0; return 0;
err: err:
@ -300,17 +306,20 @@ doreply(State *s, void *reply, int nreply)
int n; int n;
Authenticator a; Authenticator a;
alarm(30*1000);
if((n=write(s->asfd, reply, nreply)) != nreply){ if((n=write(s->asfd, reply, nreply)) != nreply){
alarm(0);
if(n >= 0) if(n >= 0)
werrstr("short write to auth server"); werrstr("short write to auth server");
goto err; goto err;
} }
if(_asrdresp(s->asfd, ticket, TICKETLEN+AUTHENTLEN) < 0){ if(_asrdresp(s->asfd, ticket, TICKETLEN+AUTHENTLEN) < 0){
alarm(0);
/* leave connection open so we can try again */ /* leave connection open so we can try again */
return -1; return -1;
} }
s->nsecret = readn(s->asfd, s->secret, sizeof s->secret); s->nsecret = readn(s->asfd, s->secret, sizeof s->secret);
alarm(0);
if(s->nsecret < 0) if(s->nsecret < 0)
s->nsecret = 0; s->nsecret = 0;
close(s->asfd); close(s->asfd);

View file

@ -281,11 +281,17 @@ p9crwrite(Fsstate *fss, void *va, uint n)
return failure(fss, Ebadarg); return failure(fss, Ebadarg);
memset(resp, 0, sizeof resp); memset(resp, 0, sizeof resp);
memmove(resp, data, n); memmove(resp, data, n);
if(write(s->asfd, resp, s->challen) != s->challen)
return failure(fss, Easproto);
alarm(30*1000);
if(write(s->asfd, resp, s->challen) != s->challen){
alarm(0);
return failure(fss, Easproto);
}
/* get ticket plus authenticator from auth server */ /* get ticket plus authenticator from auth server */
if(_asrdresp(s->asfd, tbuf, TICKETLEN+AUTHENTLEN) < 0) ret = _asrdresp(s->asfd, tbuf, TICKETLEN+AUTHENTLEN);
alarm(0);
if(ret < 0)
return failure(fss, nil); return failure(fss, nil);
/* check ticket */ /* check ticket */
@ -328,9 +334,13 @@ getchal(State *s, Fsstate *fss)
s->asfd = _authdial(nil, _strfindattr(s->key->attr, "dom")); s->asfd = _authdial(nil, _strfindattr(s->key->attr, "dom"));
if(s->asfd < 0) if(s->asfd < 0)
return failure(fss, Easproto); return failure(fss, Easproto);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN) alarm(30*1000);
if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN){
alarm(0);
return failure(fss, Easproto); return failure(fss, Easproto);
}
n = _asrdresp(s->asfd, s->chal, s->challen); n = _asrdresp(s->asfd, s->chal, s->challen);
alarm(0);
if(n <= 0){ if(n <= 0){
if(n == 0) if(n == 0)
werrstr("_asrdresp short read"); werrstr("_asrdresp short read");

View file

@ -424,7 +424,9 @@ getastickets(State *s, char *trbuf, char *tbuf)
asfd = _authdial(nil, dom); asfd = _authdial(nil, dom);
if(asfd < 0) if(asfd < 0)
return -1; return -1;
alarm(30*1000);
rv = _asgetticket(asfd, trbuf, tbuf); rv = _asgetticket(asfd, trbuf, tbuf);
alarm(0);
close(asfd); close(asfd);
return rv; return rv;
} }

View file

@ -8,7 +8,6 @@ int
_asgetticket(int fd, char *trbuf, char *tbuf) _asgetticket(int fd, char *trbuf, char *tbuf)
{ {
if(write(fd, trbuf, TICKREQLEN) < 0){ if(write(fd, trbuf, TICKREQLEN) < 0){
close(fd);
werrstr(pbmsg); werrstr(pbmsg);
return -1; return -1;
} }