From 1f0d4f3d8dd5c87d3f42a913a1af9d6f1f2da437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 26 Apr 2014 13:51:14 +0200 Subject: 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. --- src/netops.c | 8 ++++---- src/netops.h | 13 +++++++++++++ tests/network/matchhost.c | 13 +++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 tests/network/matchhost.c 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")); +} -- cgit v1.2.1