commit - 9dc775ce5edf929701a9b3da70298d591862ba33
commit + a0993bddf38dffabddd7d5b9a246f35cc00121ef
blob - 0505fbd1f8d0b37fded75218be702fa5b8fe4fab
blob + a95ca469ac5b20574614e3fad8010383444bfd91
--- gotwebd/Makefile
+++ gotwebd/Makefile
CPPFLAGS += -I${.CURDIR}/../include -I${.CURDIR}/../lib -I${.CURDIR}
CPPFLAGS += -I${.CURDIR}/../template
-LDADD += -lz -levent -lutil -lm
+LDADD += -lz -levent -lutil -lm -lcrypto
YFLAGS =
-DPADD = ${LIBEVENT} ${LIBUTIL} ${LIBM}
+DPADD = ${LIBEVENT} ${LIBUTIL} ${LIBM} ${LIBCRIPTO}
#CFLAGS += -DGOT_NO_OBJ_CACHE
.if ${GOT_RELEASE} != "Yes"
blob - dee44e8340f2a08fb4909809fc41bf2ff6cd1e7d
blob + d0f886fe876d26c60a5fe6f31cf305ca77299395
--- gotwebd/auth.c
+++ gotwebd/auth.c
/*
* The token format is:
*
- * "v1"[issued at/64bit][expire/64bit][username]"\0"[host]"\0"
+ * "v1\0"[issued at/64bit][expire/64bit][username]"\0"[host]"\0"
*
* followed by the HMAC-SHA256 of it, all encoded in base64.
*/
int
auth_is_allowed(const char *token)
{
- return !strcmp(token, "42");
+ /* XXX should consult the ACLs */
+ return auth_check_token(token);
}
/* checks whether the token's signature matches, i.e. if it looks good. */
int
auth_check_token(const char *token)
{
- return !strcmp(token, "42");
+ time_t now;
+ uint64_t issued, expire;
+ uint8_t *data;
+ size_t len;
+ char hmac[32], exp[32];
+
+ /* xxx check for overflow */
+ len = (strlen(token) / 4) * 3;
+ if (len < 21 + 32) /* min length assuming empty username and host */
+ return -1;
+
+ data = malloc(len);
+ if (data == NULL)
+ return -1;
+
+ if (EVP_DecodeBlock(data, token, strlen(token)) == -1) {
+ free(data);
+ return -1;
+ }
+ now = time(NULL);
+
+ if (memcmp(data, "v1", 3) != 0) {
+ free(data);
+ return -1;
+ }
+
+ if (HMAC(EVP_sha256(), token_secret, sizeof(token_secret), data,
+ len - 32, exp, NULL) == NULL) {
+ free(data);
+ return -1;
+ }
+
+ memcpy(hmac, data + len - 32, 32);
+ if (memcmp(hmac, exp, 32) != 0) {
+ free(data);
+ return -1;
+ }
+
+ memcpy(&issued, data + 3, sizeof(issued));
+ memcpy(&expire, data + 3 + 8, sizeof(expire));
+
+ if (expire < now) {
+ free(data);
+ return -1;
+ }
+
+ /* xxx: extract username and host */
+ return 0;
}
/* */
blob - 98b573ad9c778c1a1e852430162d12d1be11dfc4
blob + db9f586dae8ab239b36bb87983f3f6345f44b4c0
--- gotwebd/gotweb.c
+++ gotwebd/gotweb.c
if (gotwebd_env->gotwebd_verbose > 0)
log_info("processing login: code='%s'", qs->login);
- if (!auth_check_token(qs->login)) {
+ if (auth_check_token(qs->login) == -1) {
log_warnx("invalid code for login");
if (gotweb_reply(c, 401, "text/html", NULL) == -1)
return (-1);
* TODO: pass the ACLs and the current repository.
*/
log_info("auth code is %s", c->auth_cookie);
- if (!auth_is_allowed(c->auth_cookie)) {
+ if (auth_is_allowed(c->auth_cookie) == -1) {
if (gotweb_reply(c, 401, "text/html", NULL) == -1)
return -1;
return gotweb_render_page(c->tp, gotweb_render_unauthorized);