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")); +}