Commit Diff


commit - 97b40d32ed205c32841ce663899df2669f835253
commit + 00fc2bb90963db33831c38e507e38a9391a433ea
blob - 18b5a178440f33fea8c8aa22d775a03b49c959f0
blob + 3b4293f212cd39c09fc0b944debb82296d969d75
--- gotsys/gotsys.h
+++ gotsys/gotsys.h
@@ -121,6 +121,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 - e76b20d277095e0aab05b355b91befb7045962fd
blob + 08b407f0d09827e5b609d2b71ef87965e3228586
--- gotsys/parse.y
+++ gotsys/parse.y
@@ -1120,6 +1120,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
@@ -1131,7 +1158,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 - cd4dfe61444049bb6012ccddeb973b174dbe2083
blob + 5bd0e83515bd1d7c8a3a6c47b024bb737e84d76d
--- 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