Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #if defined(USE_OPENSSL) \
00026 || defined(USE_AXTLS) \
00027 || defined(USE_GSKIT) \
00028 || (defined(USE_SCHANNEL) && defined(_WIN32_WCE))
00029
00030
00031 #ifdef HAVE_NETINET_IN_H
00032 #include <netinet/in.h>
00033 #endif
00034
00035 #include "hostcheck.h"
00036 #include "strcase.h"
00037 #include "inet_pton.h"
00038
00039 #include "curl_memory.h"
00040
00041 #include "memdebug.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 static int hostmatch(char *hostname, char *pattern)
00064 {
00065 const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
00066 int wildcard_enabled;
00067 size_t prefixlen, suffixlen;
00068 struct in_addr ignored;
00069 #ifdef ENABLE_IPV6
00070 struct sockaddr_in6 si6;
00071 #endif
00072
00073
00074 size_t len = strlen(hostname);
00075 if(hostname[len-1]=='.')
00076 hostname[len-1]=0;
00077 len = strlen(pattern);
00078 if(pattern[len-1]=='.')
00079 pattern[len-1]=0;
00080
00081 pattern_wildcard = strchr(pattern, '*');
00082 if(pattern_wildcard == NULL)
00083 return strcasecompare(pattern, hostname) ?
00084 CURL_HOST_MATCH : CURL_HOST_NOMATCH;
00085
00086
00087 if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
00088 return CURL_HOST_NOMATCH;
00089 #ifdef ENABLE_IPV6
00090 else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
00091 return CURL_HOST_NOMATCH;
00092 #endif
00093
00094
00095
00096 wildcard_enabled = 1;
00097 pattern_label_end = strchr(pattern, '.');
00098 if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
00099 pattern_wildcard > pattern_label_end ||
00100 strncasecompare(pattern, "xn--", 4)) {
00101 wildcard_enabled = 0;
00102 }
00103 if(!wildcard_enabled)
00104 return strcasecompare(pattern, hostname) ?
00105 CURL_HOST_MATCH : CURL_HOST_NOMATCH;
00106
00107 hostname_label_end = strchr(hostname, '.');
00108 if(hostname_label_end == NULL ||
00109 !strcasecompare(pattern_label_end, hostname_label_end))
00110 return CURL_HOST_NOMATCH;
00111
00112
00113
00114
00115 if(hostname_label_end - hostname < pattern_label_end - pattern)
00116 return CURL_HOST_NOMATCH;
00117
00118 prefixlen = pattern_wildcard - pattern;
00119 suffixlen = pattern_label_end - (pattern_wildcard+1);
00120 return strncasecompare(pattern, hostname, prefixlen) &&
00121 strncasecompare(pattern_wildcard+1, hostname_label_end - suffixlen,
00122 suffixlen) ?
00123 CURL_HOST_MATCH : CURL_HOST_NOMATCH;
00124 }
00125
00126 int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
00127 {
00128 char *matchp;
00129 char *hostp;
00130 int res = 0;
00131 if(!match_pattern || !*match_pattern ||
00132 !hostname || !*hostname)
00133 ;
00134 else {
00135 matchp = strdup(match_pattern);
00136 if(matchp) {
00137 hostp = strdup(hostname);
00138 if(hostp) {
00139 if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
00140 res= 1;
00141 free(hostp);
00142 }
00143 free(matchp);
00144 }
00145 }
00146
00147 return res;
00148 }
00149
00150 #endif