Commit 394ae7e10131a932def325fc3fc715056a784757

Edward Thomson 2018-10-22T17:35:35

proxy tests: support self-signed proxy cert Give the proxy tests a proxy certificate callback, and allow self-signed certificates when the `GITTEST_REMOTE_PROXY_SELFSIGNED` environment variable is set (to anything). In that case, simply compare the hostname from the callback to the hostname that we connected to.

diff --git a/tests/online/clone.c b/tests/online/clone.c
index 206b267..27b8839 100644
--- a/tests/online/clone.c
+++ b/tests/online/clone.c
@@ -28,6 +28,7 @@ static char *_remote_proxy_scheme = NULL;
 static char *_remote_proxy_host = NULL;
 static char *_remote_proxy_user = NULL;
 static char *_remote_proxy_pass = NULL;
+static char *_remote_proxy_selfsigned = NULL;
 
 static int _orig_proxies_need_reset = 0;
 static char *_orig_http_proxy = NULL;
@@ -57,6 +58,7 @@ void test_online_clone__initialize(void)
 	_remote_proxy_host = cl_getenv("GITTEST_REMOTE_PROXY_HOST");
 	_remote_proxy_user = cl_getenv("GITTEST_REMOTE_PROXY_USER");
 	_remote_proxy_pass = cl_getenv("GITTEST_REMOTE_PROXY_PASS");
+	_remote_proxy_selfsigned = cl_getenv("GITTEST_REMOTE_PROXY_SELFSIGNED");
 
 	_orig_proxies_need_reset = 0;
 }
@@ -80,6 +82,7 @@ void test_online_clone__cleanup(void)
 	git__free(_remote_proxy_host);
 	git__free(_remote_proxy_user);
 	git__free(_remote_proxy_pass);
+	git__free(_remote_proxy_selfsigned);
 
 	if (_orig_proxies_need_reset) {
 		cl_setenv("HTTP_PROXY", _orig_http_proxy);
@@ -727,6 +730,30 @@ static int proxy_creds(git_cred **out, const char *url, const char *username, un
 	return git_cred_userpass_plaintext_new(out, _remote_proxy_user, _remote_proxy_pass);
 }
 
+static int proxy_cert_cb(git_cert *cert, int valid, const char *host, void *payload)
+{
+	char *colon;
+	size_t host_len;
+
+	GIT_UNUSED(cert);
+	GIT_UNUSED(valid);
+	GIT_UNUSED(payload);
+
+	cl_assert(_remote_proxy_host);
+
+	if ((colon = strchr(_remote_proxy_host, ':')) != NULL)
+		host_len = (colon - _remote_proxy_host);
+	else
+		host_len = strlen(_remote_proxy_host);
+
+	if (_remote_proxy_selfsigned != NULL &&
+	    strlen(host) == host_len &&
+	    strncmp(_remote_proxy_host, host, host_len) == 0)
+		valid = 1;
+
+	return valid ? 0 : GIT_ECERTIFICATE;
+}
+
 void test_online_clone__proxy_credentials_request(void)
 {
 	git_buf url = GIT_BUF_INIT;
@@ -741,6 +768,7 @@ void test_online_clone__proxy_credentials_request(void)
 	g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED;
 	g_options.fetch_opts.proxy_opts.url = url.ptr;
 	g_options.fetch_opts.proxy_opts.credentials = proxy_creds;
+	g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb;
 	called_proxy_creds = 0;
 	cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options));
 	cl_assert(called_proxy_creds);
@@ -761,6 +789,7 @@ void test_online_clone__proxy_credentials_in_url(void)
 
 	g_options.fetch_opts.proxy_opts.type = GIT_PROXY_SPECIFIED;
 	g_options.fetch_opts.proxy_opts.url = url.ptr;
+	g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb;
 	called_proxy_creds = 0;
 	cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/TestGitRepository", "./foo", &g_options));
 	cl_assert(called_proxy_creds == 0);
@@ -780,6 +809,7 @@ void test_online_clone__proxy_credentials_in_environment(void)
 	_orig_proxies_need_reset = 1;
 
 	g_options.fetch_opts.proxy_opts.type = GIT_PROXY_AUTO;
+	g_options.fetch_opts.proxy_opts.certificate_check = proxy_cert_cb;
 
 	cl_git_pass(git_buf_printf(&url, "%s://%s:%s@%s/",
 		_remote_proxy_scheme ? _remote_proxy_scheme : "http",