summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2014-04-26 13:51:14 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2014-04-26 17:27:42 +0200
commit1f0d4f3d8dd5c87d3f42a913a1af9d6f1f2da437 (patch)
tree1131f54640997311712161008ef652e77fda118a
parent4f9d54146d569fffb679386fd3057e571afacd1f (diff)
downloadlibgit2-1f0d4f3d8dd5c87d3f42a913a1af9d6f1f2da437.tar.gz
netops: unit-test the cert host-name pattern matching
This kind of stuff should have unit tests, even if it's just to show what we expect to match successfully.
-rw-r--r--src/netops.c8
-rw-r--r--src/netops.h13
-rw-r--r--tests/network/matchhost.c13
3 files changed, 30 insertions, 4 deletions
diff --git a/src/netops.c b/src/netops.c
index ad27d84cf..23f482b12 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -207,7 +207,7 @@ static int gitno_ssl_teardown(gitno_ssl *ssl)
}
/* Match host names according to RFC 2818 rules */
-static int match_host(const char *pattern, const char *host)
+int gitno__match_host(const char *pattern, const char *host)
{
for (;;) {
char c = tolower(*pattern++);
@@ -230,9 +230,9 @@ static int match_host(const char *pattern, const char *host)
while(*host) {
char h = tolower(*host);
if (c == h)
- return match_host(pattern, host++);
+ return gitno__match_host(pattern, host++);
if (h == '.')
- return match_host(pattern, host);
+ return gitno__match_host(pattern, host);
host++;
}
return -1;
@@ -250,7 +250,7 @@ static int check_host_name(const char *name, const char *host)
if (!strcasecmp(name, host))
return 0;
- if (match_host(name, host) < 0)
+ if (gitno__match_host(name, host) < 0)
return -1;
return 0;
diff --git a/src/netops.h b/src/netops.h
index 666d66b12..8e3a2524f 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -54,6 +54,19 @@ enum {
GITNO_CONNECT_SSL_NO_CHECK_CERT = 2,
};
+/**
+ * Check if the name in a cert matches the wanted hostname
+ *
+ * Check if a pattern from a certificate matches the hostname we
+ * wanted to connect to according to RFC2818 rules (which specifies
+ * HTTP over TLS). Mainly, an asterisk matches anything, but is
+ * limited to a single url component.
+ *
+ * Note that this does not set an error message. It expects the user
+ * to provide the message for the user.
+ */
+int gitno__match_host(const char *pattern, const char *host);
+
void gitno_buffer_setup(gitno_socket *t, gitno_buffer *buf, char *data, size_t len);
void gitno_buffer_setup_callback(gitno_socket *t, gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data);
int gitno_recv(gitno_buffer *buf);
diff --git a/tests/network/matchhost.c b/tests/network/matchhost.c
new file mode 100644
index 000000000..3100dc21d
--- /dev/null
+++ b/tests/network/matchhost.c
@@ -0,0 +1,13 @@
+#include "clar_libgit2.h"
+#include "netops.h"
+
+void test_network_matchhost__match(void)
+{
+ cl_git_pass(gitno__match_host("*.example.org", "www.example.org"));
+ cl_git_pass(gitno__match_host("*.foo.example.org", "www.foo.example.org"));
+ cl_git_fail(gitno__match_host("*.foo.example.org", "foo.example.org"));
+ cl_git_fail(gitno__match_host("*.foo.example.org", "www.example.org"));
+ cl_git_fail(gitno__match_host("*.example.org", "example.org"));
+ cl_git_fail(gitno__match_host("*.example.org", "www.foo.example.org"));
+ cl_git_fail(gitno__match_host("*.example.org", "blah.www.www.example.org"));
+}