Commit Diff


commit - f7520f7a437fe99ad7db71964be0162efa23ff3d
commit + b4358cd08e510b24eaf6a190b1dba1c975ddb8e1
blob - 9c0a9efd1ed96a42a798c7f69a70c8645bdf0ead
blob + 2f400b4989361d4241dfeee8eb2a56038aa79131
--- gotd/gotd-secrets.conf.5
+++ gotd/gotd-secrets.conf.5
@@ -24,6 +24,8 @@
 holds the authentication data and HMAC secrets for
 .Xr gotd 8
 notifications.
+This file must be owned by the root user and must not be readable
+by any other users.
 .Pp
 The file format is line-based, with one entry per line.
 Comments can be put at the start of the line using a hash mark
blob - 6f507148f4fa7c50700629c3309906834c5a51b3
blob + f5488c6250b396af6322ec60a1446b0adc75e0a0
--- gotd/gotd.c
+++ gotd/gotd.c
@@ -2000,6 +2000,26 @@ unveil_notification_helpers(void)
 		fatal("unveil");
 }
 
+static void
+check_file_secrecy(int fd, const char *fname)
+{
+	struct stat st;
+
+	if (fstat(fd, &st))
+		fatal("cannot stat %s", fname);
+
+	if (st.st_uid != 0)
+		fatalx("secrets file %s must be owned by root", fname);
+
+	if (st.st_gid != 0)
+		fatalx("secrets file %s must be owned by group wheel/root",
+		    fname);
+
+	if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO))
+		fatalx("secrets file %s must not be group writable or world "
+		    "readable/writable", fname);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2099,9 +2119,10 @@ main(int argc, char **argv)
 
 		fp = fopen(p, "r");
 		if (fp == NULL && (secretspath != NULL || errno != ENOENT))
-			fatal("can't open secret file %s", p);
+			fatal("can't open secrets file %s", p);
 
 		if (fp != NULL) {
+			check_file_secrecy(fileno(fp), p);
 			error = gotd_secrets_parse(p, fp, &secrets);
 			fclose(fp);
 			if (error)
blob - d2f5c834b32eb56747464e08d55c728712cec941
blob + c3b16b4b439df9cf2fee1a80ae0caffffa7ab0de
--- regress/gotd/Makefile
+++ regress/gotd/Makefile
@@ -11,7 +11,7 @@ REGRESS_TARGETS=test_repo_read test_repo_read_group \
 NOOBJ=Yes
 CLEANFILES=gotd.conf
 
-.PHONY: ensure_root prepare_test_repo check_test_repo start_gotd
+.PHONY: ensure_root ensure_secrets prepare_test_repo check_test_repo start_gotd
 
 GOTD_TEST_ROOT=/tmp
 GOTD_DEVUSER?=gotdev
@@ -74,6 +74,12 @@ ensure_root:
 		false; \
 	fi
 
+ensure_secrets:
+	@echo 'auth flan password' > $(PWD)/gotd-secrets.conf
+	@echo 'hmac flan ${GOTD_TEST_HMAC_SECRET}' >> $(PWD)/gotd-secrets.conf
+	@chown root:0 $(PWD)/gotd-secrets.conf
+	@chmod 600 $(PWD)/gotd-secrets.conf
+
 start_gotd_ro: ensure_root
 	@echo 'listen on "$(GOTD_SOCK)"' > $(PWD)/gotd.conf
 	@echo "user $(GOTD_USER)" >> $(PWD)/gotd.conf
@@ -186,8 +192,7 @@ start_gotd_email_notification: ensure_root
 	@$(GOTD_TRAP); $(GOTD_START_CMD)
 	@$(GOTD_TRAP); sleep .5
 
-start_gotd_http_notification: ensure_root
-	@echo 'auth flan password' > $(PWD)/gotd-secrets.conf
+start_gotd_http_notification: ensure_root ensure_secrets
 	@echo 'listen on "$(GOTD_SOCK)"' > $(PWD)/gotd.conf
 	@echo "user $(GOTD_USER)" >> $(PWD)/gotd.conf
 	@echo 'repository "test-repo" {' >> $(PWD)/gotd.conf
@@ -200,8 +205,7 @@ start_gotd_http_notification: ensure_root
 	@$(GOTD_TRAP); $(GOTD_START_CMD) -s $(PWD)/gotd-secrets.conf
 	@$(GOTD_TRAP); sleep .5
 
-start_gotd_email_and_http_notification: ensure_root
-	@echo 'auth flan password' > $(PWD)/gotd-secrets.conf
+start_gotd_email_and_http_notification: ensure_root ensure_secrets
 	@echo 'listen on "$(GOTD_SOCK)"' > $(PWD)/gotd.conf
 	@echo "user $(GOTD_USER)" >> $(PWD)/gotd.conf
 	@echo 'repository "test-repo" {' >> $(PWD)/gotd.conf
@@ -216,9 +220,7 @@ start_gotd_email_and_http_notification: ensure_root
 	@$(GOTD_TRAP); $(GOTD_START_CMD) -s $(PWD)/gotd-secrets.conf
 	@$(GOTD_TRAP); sleep .5
 
-start_gotd_http_notification_hmac: ensure_root
-	@echo 'auth flan password' > $(PWD)/gotd-secrets.conf
-	@echo 'hmac flan ${GOTD_TEST_HMAC_SECRET}' >> $(PWD)/gotd-secrets.conf
+start_gotd_http_notification_hmac: ensure_root ensure_secrets
 	@echo 'listen on "$(GOTD_SOCK)"' > $(PWD)/gotd.conf
 	@echo "user $(GOTD_USER)" >> $(PWD)/gotd.conf
 	@echo 'repository "test-repo" {' >> $(PWD)/gotd.conf