Commit Diff


commit - 1b4b319ba6b74f3f066fdfc75995ea5241507caa
commit + 076101f2df32331f84fa9fe38d8394716e955814
blob - 7b5191095a645e3f1b5c9ade40cbf3811d5c5f42
blob + d6c4206f6fde168542a00fd487891e6fa296621a
--- gotsys/gotsys.h
+++ gotsys/gotsys.h
@@ -120,6 +120,7 @@ struct gotsys_conf {
 void gotsys_conf_init(struct gotsys_conf *);
 const struct got_error *gotsys_conf_parse(const char *, struct gotsys_conf *,
     int *);
+int gotsys_ref_name_is_valid(char *);
 void gotsys_authorized_key_free(struct gotsys_authorized_key *);
 void gotsys_authorized_keys_list_purge(struct gotsys_authorized_keys_list *);
 void gotsys_user_free(struct gotsys_user *);
blob - ebf1ff2a03bb1cd0a418e4a821cdd5a0f9d3a4e0
blob + bddef6d8953e3a78b7c1f65ddf31d79b77773d82
--- gotsys/parse.y
+++ gotsys/parse.y
@@ -1060,6 +1060,33 @@ conf_user_authorized_key(char *keytype, char *keydata,
 
 	STAILQ_INSERT_TAIL(&user->authorized_keys, key, entry);
 	return NULL;
+}
+
+/*
+ * Reference name restrictions specific to gotsys.conf.
+ * Exclude symbols which could be used to escape from strings and write
+ * arbitrary gotd.conf snippets. Also exclude whitespace because newlines
+ * are relevant to the parser.
+ */
+int
+gotsys_ref_name_is_valid(char *refname)
+{
+	const char *s;
+	const char forbidden[] = { '\'', '"', '{' , '}', '=' };
+	size_t i;
+
+	s = refname;
+	while (*s) {
+		for (i = 0; i < nitems(forbidden); i++) {
+			if (*s == forbidden[i])
+				return 0;
+		}
+		if (isspace((unsigned char)s[0]))
+			return 0;
+		s++;
+	}
+
+	return 1;
 }
 
 static int
@@ -1071,7 +1098,8 @@ refname_is_valid(char *refname)
 		return 0;
 	}
 
-	if (!got_ref_name_is_valid(refname)) {
+	if (!got_ref_name_is_valid(refname) ||
+	    !gotsys_ref_name_is_valid(refname)) {
 		yyerror("invalid reference name: %s", refname);
 		return 0;
 	}
blob - d7e399f5f7a3fefc412700402b3d12be575bb36d
blob + cee6986bf6095cfe5d4b8356cda3408ed7b8f7f5
--- regress/gotsysd/test_gotsysd.sh
+++ regress/gotsysd/test_gotsysd.sh
@@ -1171,6 +1171,91 @@ EOF
 	cat > ${testroot}/stderr.expected <<EOF
 git-receive-pack: gotsys.conf: line 3: syntax error
 got-send-pack: gotsys.conf: line 3: syntax error
+got: could not send pack file
+EOF
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	test_done "$testroot" "0"
+}
+
+test_bad_ref_in_gotsysconf() {
+	local testroot=`test_init bad_ref_in_gotsysconf 1`
+
+	got checkout -q $testroot/${GOTSYS_REPO} $testroot/wt >/dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got checkout failed unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	crypted_vm_pw=`echo ${GOTSYSD_VM_PASSWORD} | encrypt | tr -d '\n'`
+	crypted_pw=`echo ${GOTSYSD_DEV_PASSWORD} | encrypt | tr -d '\n'`
+	sshkey=`cat ${GOTSYSD_SSH_PUBKEY}`
+
+	# An attempt to send an invalid gotsys.conf file
+	cat > ${testroot}/wt/gotsys.conf <<EOF
+group slackers
+
+user ${GOTSYSD_TEST_USER} {
+	password "${crypted_vm_pw}" 
+	authorized key ${sshkey}
+}
+user ${GOTSYSD_DEV_USER} {
+	password "${crypted_pw}" 
+	authorized key ${sshkey}
+}
+repository gotsys.git {
+	permit rw ${GOTSYSD_TEST_USER}
+	permit rw ${GOTSYSD_DEV_USER}
+}
+repository "foo" {
+	permit rw ${GOTSYSD_DEV_USER}
+	permit ro anonymous
+	protect branch 'mai"n'
+}
+EOF
+	gotsys check -f ${testroot}/wt/gotsys.conf \
+		> $testroot/stdout  2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "gotsys check succeeded unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	echo "gotsys: ${testroot}/wt/gotsys.conf: line 18: invalid reference name: refs/heads/mai\"n" \
+		> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd ${testroot}/wt && got commit -m "commit a bad gotsys.conf" \
+		>/dev/null)
+	local commit_id=`git_show_head $testroot/${GOTSYS_REPO}`
+
+	got send -q -i ${GOTSYSD_SSH_KEY} -r ${testroot}/${GOTSYS_REPO} \
+		> $testroot/stdout 2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "got send succeeded unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	cat > ${testroot}/stderr.expected <<EOF
+git-receive-pack: gotsys.conf: line 18: invalid reference name: refs/heads/mai"n
+got-send-pack: gotsys.conf: line 18: invalid reference name: refs/heads/mai"n
 got: could not send pack file
 EOF
 	cmp -s $testroot/stderr.expected $testroot/stderr
@@ -1711,6 +1796,7 @@ run_test test_group_del
 run_test test_repo_create
 run_test test_user_anonymous
 run_test test_bad_gotsysconf
+run_test test_bad_ref_in_gotsysconf
 run_test test_set_head
 run_test test_protect_refs
 run_test test_deny_access