From: Omar Polo Subject: got-notify-http: implement basic auth To: gameoftrees@openbsd.org Date: Tue, 16 Apr 2024 01:25:04 +0200 with this the authentication is properly implemented. I'm unsure how to plug it in the regress, so for the moment no tests. diff /home/op/w/got commit - c1003102a22a77d068a14f9ffa7877f67c28e95d path + /home/op/w/got blob - 9c8a90e392c27e03eb1dd32a88414aa62a355012 file + gotd/libexec/got-notify-http/got-notify-http.c --- gotd/libexec/got-notify-http/got-notify-http.c +++ gotd/libexec/got-notify-http/got-notify-http.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -730,17 +731,70 @@ jsonify(FILE *fp, const char *repo) return 0; } +static char +sixet2ch(int c) +{ + c &= 0x3F; + + if (c < 26) + return 'A' + c; + c -= 26; + if (c < 26) + return 'a' + c; + c -= 26; + if (c < 10) + return '0' + c; + c -= 10; + if (c == 0) + return '+'; + if (c == 1) + return '/'; + + errx(1, "invalid sixet 0x%x", c); +} + static char * basic_auth(const char *username, const char *password) { - char *tmp; - int len; + char *str, *tmp, *end, *s, *p; + char buf[3]; + int len, i, r; - len = asprintf(&tmp, "%s:%s", username, password); - if (len == -1) + r = asprintf(&str, "%s:%s", username, password); + if (r == -1) err(1, "asprintf"); - /* XXX base64-ify */ + /* + * Will need 4 * r/3 bytes to encode the string, plus a + * rounding to the next multiple of 4 for padding, plus NUL. + */ + len = 4 * r / 3; + len = (len + 3) & ~3; + len++; + + tmp = calloc(1, len); + if (tmp == NULL) + err(1, "malloc"); + + s = str; + p = tmp; + while (*s != '\0') { + memset(buf, 0, sizeof(buf)); + for (i = 0; i < 3 && *s != '\0'; ++i, ++s) + buf[i] = *s; + + *p++ = sixet2ch(buf[0] >> 2); + *p++ = sixet2ch((buf[1] >> 4) | (buf[0] << 4)); + if (i > 1) + *p++ = sixet2ch((buf[1] << 2) | (buf[2] >> 6)); + if (i > 2) + *p++ = sixet2ch(buf[2]); + } + + for (end = tmp + len - 1; p < end; ++p) + *p = '='; + + free(str); return tmp; } blob - 682368c09afd8f26371f3c0eb5b63f700ac39026 file + gotd/notify.c --- gotd/notify.c +++ gotd/notify.c @@ -161,7 +161,8 @@ gotd_notify_sighdlr(int sig, short event, void *arg) } static void -run_notification_helper(const char *prog, const char **argv, int fd) +run_notification_helper(const char *prog, const char **argv, int fd, + const char *user, const char *pass) { const struct got_error *err = NULL; pid_t pid; @@ -185,6 +186,11 @@ run_notification_helper(const char *prog, const char * closefrom(STDERR_FILENO + 1); + if (user != NULL && pass != NULL) { + setenv("GOT_NOTIFY_HTTP_USER", user, 1); + setenv("GOT_NOTIFY_HTTP_PASS", pass, 1); + } + if (execv(prog, (char *const *)argv) == -1) { fprintf(stderr, "%s: exec %s: %s\n", getprogname(), prog, strerror(errno)); @@ -249,7 +255,8 @@ notify_email(struct gotd_notification_target *target, argv[i] = NULL; - run_notification_helper(GOTD_PATH_PROG_NOTIFY_EMAIL, argv, fd); + run_notification_helper(GOTD_PATH_PROG_NOTIFY_EMAIL, argv, fd, + NULL, NULL); } static void @@ -273,7 +280,8 @@ notify_http(struct gotd_notification_target *target, c argv[argc] = NULL; - run_notification_helper(GOTD_PATH_PROG_NOTIFY_HTTP, argv, fd); + run_notification_helper(GOTD_PATH_PROG_NOTIFY_HTTP, argv, fd, + target->conf.http.user, target->conf.http.password); } static const struct got_error *