summaryrefslogtreecommitdiff
path: root/src/libgit2
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-05-12 20:48:30 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-05-13 16:42:04 +0100
commit6e4bbf222d8c4babaff90aef40615546c8bc9cde (patch)
treeadd632fcb19f7266e22044022840d9500b5b3c84 /src/libgit2
parentdbe343b6e3e957b5cffbd04832c6e7364b496ae7 (diff)
downloadlibgit2-6e4bbf222d8c4babaff90aef40615546c8bc9cde.tar.gz
net: move rfc2818 hostname / wildcard matching to util
Diffstat (limited to 'src/libgit2')
-rw-r--r--src/libgit2/netops.c39
-rw-r--r--src/libgit2/netops.h13
-rw-r--r--src/libgit2/streams/openssl.c19
3 files changed, 6 insertions, 65 deletions
diff --git a/src/libgit2/netops.c b/src/libgit2/netops.c
index 00640c600..5cae374ad 100644
--- a/src/libgit2/netops.c
+++ b/src/libgit2/netops.c
@@ -83,42 +83,3 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
memset(buf->data + cons, 0x0, buf->len - buf->offset);
buf->offset -= cons;
}
-
-/* Match host names according to RFC 2818 rules */
-int gitno__match_host(const char *pattern, const char *host)
-{
- for (;;) {
- char c = git__tolower(*pattern++);
-
- if (c == '\0')
- return *host ? -1 : 0;
-
- if (c == '*') {
- c = *pattern;
- /* '*' at the end matches everything left */
- if (c == '\0')
- return 0;
-
- /*
- * We've found a pattern, so move towards the next matching
- * char. The '.' is handled specially because wildcards aren't
- * allowed to cross subdomains.
- */
-
- while(*host) {
- char h = git__tolower(*host);
- if (c == h)
- return gitno__match_host(pattern, host++);
- if (h == '.')
- return gitno__match_host(pattern, host);
- host++;
- }
- return -1;
- }
-
- if (c != git__tolower(*host++))
- return -1;
- }
-
- return -1;
-}
diff --git a/src/libgit2/netops.h b/src/libgit2/netops.h
index 56f968534..a3f4a0f95 100644
--- a/src/libgit2/netops.h
+++ b/src/libgit2/netops.h
@@ -45,19 +45,6 @@ enum {
GITNO_CONNECT_SSL = 1
};
-/**
- * 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_fromstream(git_stream *st, gitno_buffer *buf, char *data, size_t len);
void gitno_buffer_setup_callback(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/src/libgit2/streams/openssl.c b/src/libgit2/streams/openssl.c
index 5e0e2c939..58b2d1b23 100644
--- a/src/libgit2/streams/openssl.c
+++ b/src/libgit2/streams/openssl.c
@@ -18,6 +18,7 @@
#include "settings.h"
#include "posix.h"
#include "stream.h"
+#include "net.h"
#include "streams/socket.h"
#include "netops.h"
#include "git2/transport.h"
@@ -357,15 +358,10 @@ static int ssl_teardown(SSL *ssl)
return ret;
}
-static int check_host_name(const char *name, const char *host)
+static bool check_host_name(const char *host, const char *name)
{
- if (!strcasecmp(name, host))
- return 0;
-
- if (gitno__match_host(name, host) < 0)
- return -1;
-
- return 0;
+ return !strcasecmp(host, name) ||
+ git_net_hostname_matches_cert(host, name);
}
static int verify_server_cert(SSL *ssl, const char *host)
@@ -425,10 +421,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
if (memchr(name, '\0', namelen))
continue;
- if (check_host_name(name, host) < 0)
- matched = 0;
- else
- matched = 1;
+ matched = !!check_host_name(host, name);
} else if (type == GEN_IPADD) {
/* Here name isn't so much a name but a binary representation of the IP */
matched = addr && !!memcmp(name, addr, namelen);
@@ -481,7 +474,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
goto cert_fail_name;
}
- if (check_host_name((char *)peer_cn, host) < 0)
+ if (!check_host_name(host, (char *)peer_cn))
goto cert_fail_name;
goto cleanup;