Download raw body.
got-notify-http: implement basic auth
On Tue, Apr 16, 2024 at 10:11:53AM +0200, Omar Polo wrote:
> It makes the log output more verbose as a drawback though:
>
> : gotd: gotd: WARNING: Using basic authentication over plaintext http://
> : will leak credentials; https:// is recommended for URL
> : 'http://localhost:8000/'
Here is an alternative suggestion that avoids noise in the test suite
and should be somewhat safer:
gotd: /home/stsp/src/got/regress/gotd/gotd.conf:7: http://localhost:8000/: \
HTTP notifications with basic authentication over plaintext HTTP will \
leak credentials; add the 'insecure' config keyword if this is intentional
*** Error 1 in /home/stsp/src/got/regress/gotd
-----------------------------------------------
make it harder to leak notification credentials over plaintext HTTP
diff fd1b27119fe0bafd2e0b5ee26e877c742edfeb0e 953dac4f9d80392b44212d2822adba3e2b218fd5
commit - fd1b27119fe0bafd2e0b5ee26e877c742edfeb0e
commit + 953dac4f9d80392b44212d2822adba3e2b218fd5
blob - 6b1e63e34c2c42b7aeff0c238e2a303c5efa7c2a
blob + a346ab5981dac6f616103dfdb281f5c2785c60a2
--- gotd/gotd.conf.5
+++ gotd/gotd.conf.5
@@ -326,7 +326,7 @@ The
and
.Ic port
directives can be used to specify a different SMTP server address and port.
-.It Ic url Ar URL Oo Ic user Ar user Ic password Ar password Oc
+.It Ic url Ar URL Oo Ic user Ar user Ic password Ar password Oo Ic insecure Oc Oc
Send notifications via HTTP.
This directive may be specified multiple times to build a list of
HTTP servers to send notifications to.
@@ -353,6 +353,13 @@ must be specified.
The
.Ar password
must not be an empty string.
+Unless the
+.Ic insecure
+option is specified the notification target
+.Ar URL
+must be a
+.Dq https://
+URL to avoid leaking of authentication credentials.
.Pp
The request body contains a JSON object with a
.Dq notifications
blob - a3f897aa6bfb4b65dde83d437ee62682525ffc9f
blob + 0aa454a1c57aed05f6c61df19f663823fe60f40b
--- gotd/parse.y
+++ gotd/parse.y
@@ -110,7 +110,7 @@ static int conf_notify_ref_namespace(struct gotd_re
static int conf_notify_email(struct gotd_repo *,
char *, char *, char *, char *, char *);
static int conf_notify_http(struct gotd_repo *,
- char *, char *, char *);
+ char *, char *, char *, int);
static enum gotd_procid gotd_proc_id;
typedef struct {
@@ -127,7 +127,7 @@ typedef struct {
%token PATH ERROR LISTEN ON USER REPOSITORY PERMIT DENY
%token RO RW CONNECTION LIMIT REQUEST TIMEOUT
%token PROTECT NAMESPACE BRANCH TAG REFERENCE RELAY PORT
-%token NOTIFY EMAIL FROM REPLY TO URL PASSWORD
+%token NOTIFY EMAIL FROM REPLY TO URL PASSWORD INSECURE
%token <v.string> STRING
%token <v.number> NUMBER
@@ -600,7 +600,7 @@ notifyflags : BRANCH STRING {
gotd_proc_id == PROC_SESSION_WRITE ||
gotd_proc_id == PROC_NOTIFY) {
if (conf_notify_http(new_repo, $2, NULL,
- NULL)) {
+ NULL, 0)) {
free($2);
YYERROR;
}
@@ -611,7 +611,7 @@ notifyflags : BRANCH STRING {
if (gotd_proc_id == PROC_GOTD ||
gotd_proc_id == PROC_SESSION_WRITE ||
gotd_proc_id == PROC_NOTIFY) {
- if (conf_notify_http(new_repo, $2, $4, $6)) {
+ if (conf_notify_http(new_repo, $2, $4, $6, 0)) {
free($2);
free($4);
free($6);
@@ -622,6 +622,21 @@ notifyflags : BRANCH STRING {
free($4);
free($6);
}
+ | URL STRING USER STRING PASSWORD STRING INSECURE {
+ if (gotd_proc_id == PROC_GOTD ||
+ gotd_proc_id == PROC_SESSION_WRITE ||
+ gotd_proc_id == PROC_NOTIFY) {
+ if (conf_notify_http(new_repo, $2, $4, $6, 1)) {
+ free($2);
+ free($4);
+ free($6);
+ YYERROR;
+ }
+ }
+ free($2);
+ free($4);
+ free($6);
+ }
;
repository : REPOSITORY STRING {
@@ -767,6 +782,7 @@ lookup(char *s)
{ "deny", DENY },
{ "email", EMAIL },
{ "from", FROM },
+ { "insecure", INSECURE },
{ "limit", LIMIT },
{ "listen", LISTEN },
{ "namespace", NAMESPACE },
@@ -1535,7 +1551,8 @@ conf_notify_email(struct gotd_repo *repo, char *sender
}
static int
-conf_notify_http(struct gotd_repo *repo, char *url, char *user, char *password)
+conf_notify_http(struct gotd_repo *repo, char *url, char *user, char *password,
+ int insecure)
{
const struct got_error *error;
struct gotd_notification_target *target;
@@ -1565,10 +1582,13 @@ conf_notify_http(struct gotd_repo *repo, char *url, ch
goto done;
}
- if (strcmp(proto, "http") == 0 && (user != NULL || password != NULL)) {
- log_warnx("%s: WARNING: Using basic authentication over "
- "plaintext http:// will leak credentials; https:// is "
- "recommended for URL '%s'", getprogname(), url);
+ if (!insecure && strcmp(proto, "http") == 0 &&
+ (user != NULL || password != NULL)) {
+ yyerror("%s: HTTP notifications with basic authentication "
+ "over plaintext HTTP will leak credentials; add the "
+ "'insecure' config keyword if this is intentional", url);
+ ret = -1;
+ goto done;
}
STAILQ_FOREACH(target, &repo->notification_targets, entry) {
blob - c00bf5c27253d88367260cc43d44b187d066276e
blob + c38bd07b843aa78426c9e628f609604a4d815417
--- regress/gotd/Makefile
+++ regress/gotd/Makefile
@@ -188,7 +188,7 @@ start_gotd_http_notification: ensure_root
@echo ' path "$(GOTD_TEST_REPO)"' >> $(PWD)/gotd.conf
@echo ' permit rw $(GOTD_DEVUSER)' >> $(PWD)/gotd.conf
@echo ' notify {' >> $(PWD)/gotd.conf
- @echo ' url "http://localhost:${GOTD_TEST_HTTP_PORT}/" user flan password "password"' >> $(PWD)/gotd.conf
+ @echo ' url "http://localhost:${GOTD_TEST_HTTP_PORT}/" user flan password "password" insecure' >> $(PWD)/gotd.conf
@echo " }" >> $(PWD)/gotd.conf
@echo "}" >> $(PWD)/gotd.conf
@$(GOTD_TRAP); $(GOTD_START_CMD)
got-notify-http: implement basic auth