summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlos@cmartin.tk>2012-05-17 22:22:05 +0200
committerCarlos Martín Nieto <carlos@cmartin.tk>2012-05-19 17:51:53 +0200
commit3f9eb1e50201a3a99dad84ce22ad799fed15eaf1 (patch)
treefa3cf990ec2e690bf188e69965509dc25b8489da
parentd3e1367f61030f78692fb9f02e82cd49b1f8e949 (diff)
downloadlibgit2-3f9eb1e50201a3a99dad84ce22ad799fed15eaf1.tar.gz
ssl: add support for certificates issues to an IP address
-rw-r--r--src/netops.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/src/netops.c b/src/netops.c
index 6967ebb5b..6341fb887 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -24,6 +24,7 @@
#endif
#include <ctype.h>
+#include <arpa/inet.h>
#include "git2/errors.h"
#include "common.h"
@@ -219,8 +220,23 @@ static int verify_server_cert(git_transport *t, const char *host)
X509 *cert;
X509_NAME *peer_name;
char buf[1024];
- int matched = -1;
+ int matched = -1, type = GEN_DNS;
GENERAL_NAMES *alts;
+ struct in6_addr addr6;
+ struct in_addr addr4;
+ void *addr;
+
+ /* Try to parse the host as an IP address to see if it is */
+ if (inet_pton(AF_INET, host, &addr4)) {
+ type = GEN_IPADD;
+ addr = &addr4;
+ } else {
+ if(inet_pton(AF_INET6, host, &addr6)) {
+ type = GEN_IPADD;
+ addr = &addr6;
+ }
+ }
+
cert = SSL_get_peer_certificate(t->ssl.ssl);
@@ -235,14 +251,23 @@ static int verify_server_cert(git_transport *t, const char *host)
const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);
- /* If it contains embedded NULs, don't even try */
- if (namelen != strnlen(name, namelen))
+ /* Skip any names of a type we're not looking for */
+ if (gn->type != type)
continue;
- if (check_host_name(name, host) < 0)
- matched = 0;
- else
- matched = 1;
+ if (type == GEN_DNS) {
+ /* If it contains embedded NULs, don't even try */
+ if (namelen != strnlen(name, namelen))
+ continue;
+
+ if (check_host_name(name, host) < 0)
+ matched = 0;
+ else
+ matched = 1;
+ } else if (type == GEN_IPADD) {
+ /* Here name isn't so much a name but a binary representation of the IP */
+ matched = !!memcmp(name, addr, namelen);
+ }
}
}
GENERAL_NAMES_free(alts);