Skip to content

Commit

Permalink
hostcheck: fix host name wildcard checking
Browse files Browse the repository at this point in the history
The leftmost "label" of the host name can now only match against single
'*'. Like the browsers have worked for a long time.

- extended unit test 1397 for this
- move some SOURCE variables from unit/Makefile.am to unit/Makefile.inc

Reported-by: Hiroki Kurosawa
Closes curl#11018
  • Loading branch information
bagder authored and bch committed Jul 19, 2023
1 parent a0d7166 commit 8d6a750
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 180 deletions.
50 changes: 22 additions & 28 deletions lib/vtls/hostcheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,61 +71,55 @@ static bool pmatch(const char *hostname, size_t hostlen,
* apparent distinction between a name and an IP. We need to detect the use of
* an IP address and not wildcard match on such names.
*
* Only match on "*" being used for the leftmost label, not "a*", "a*b" nor
* "*b".
*
* Return TRUE on a match. FALSE if not.
*
* @unittest: 1397
*/

static bool hostmatch(const char *hostname,
size_t hostlen,
const char *pattern,
size_t patternlen)
{
const char *pattern_label_end, *wildcard, *hostname_label_end;
size_t prefixlen, suffixlen;
const char *pattern_label_end;

/* normalize pattern and hostname by stripping off trailing dots */
DEBUGASSERT(pattern);
DEBUGASSERT(patternlen);
DEBUGASSERT(hostname);
DEBUGASSERT(hostlen);

/* normalize pattern and hostname by stripping off trailing dots */
if(hostname[hostlen-1]=='.')
hostlen--;
if(pattern[patternlen-1]=='.')
patternlen--;

wildcard = memchr(pattern, '*', patternlen);
if(!wildcard)
if(strncmp(pattern, "*.", 2))
return pmatch(hostname, hostlen, pattern, patternlen);

/* detect IP address as hostname and fail the match if so */
if(Curl_host_is_ipnum(hostname))
else if(Curl_host_is_ipnum(hostname))
return FALSE;

/* We require at least 2 dots in the pattern to avoid too wide wildcard
match. */
pattern_label_end = memchr(pattern, '.', patternlen);
if(!pattern_label_end ||
(memrchr(pattern, '.', patternlen) == pattern_label_end) ||
strncasecompare(pattern, "xn--", 4))
(memrchr(pattern, '.', patternlen) == pattern_label_end))
return pmatch(hostname, hostlen, pattern, patternlen);

hostname_label_end = memchr(hostname, '.', hostlen);
if(!hostname_label_end)
return FALSE;
else {
size_t skiphost = hostname_label_end - hostname;
size_t skiplen = pattern_label_end - pattern;
if(!pmatch(hostname_label_end, hostlen - skiphost,
pattern_label_end, patternlen - skiplen))
return FALSE;
const char *hostname_label_end = memchr(hostname, '.', hostlen);
if(hostname_label_end) {
size_t skiphost = hostname_label_end - hostname;
size_t skiplen = pattern_label_end - pattern;
return pmatch(hostname_label_end, hostlen - skiphost,
pattern_label_end, patternlen - skiplen);
}
}
/* The wildcard must match at least one character, so the left-most
label of the hostname is at least as large as the left-most label
of the pattern. */
if(hostname_label_end - hostname < pattern_label_end - pattern)
return FALSE;

prefixlen = wildcard - pattern;
suffixlen = pattern_label_end - (wildcard + 1);
return strncasecompare(pattern, hostname, prefixlen) &&
strncasecompare(wildcard + 1, hostname_label_end - suffixlen,
suffixlen) ? TRUE : FALSE;
return FALSE;
}

/*
Expand Down
10 changes: 4 additions & 6 deletions tests/data/test1397
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
<info>
<keywords>
unittest
ssl
wildcard
Curl_cert_hostcheck
</keywords>
</info>

Expand All @@ -16,9 +15,8 @@ none
<features>
unittest
</features>
<name>
Check wildcard certificate matching function Curl_cert_hostcheck
</name>
<name>
Curl_cert_hostcheck unit tests
</name>
</client>

</testcase>
94 changes: 0 additions & 94 deletions tests/unit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -67,97 +67,3 @@ noinst_PROGRAMS = $(UNITPROGS)
else
noinst_PROGRAMS =
endif

unit1300_SOURCES = unit1300.c $(UNITFILES)

unit1302_SOURCES = unit1302.c $(UNITFILES)

unit1303_SOURCES = unit1303.c $(UNITFILES)

unit1304_SOURCES = unit1304.c $(UNITFILES)

unit1305_SOURCES = unit1305.c $(UNITFILES)

unit1307_SOURCES = unit1307.c $(UNITFILES)

unit1308_SOURCES = unit1308.c $(UNITFILES)

unit1309_SOURCES = unit1309.c $(UNITFILES)

unit1323_SOURCES = unit1323.c $(UNITFILES)

unit1330_SOURCES = unit1330.c $(UNITFILES)

unit1394_SOURCES = unit1394.c $(UNITFILES)
unit1394_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
unit1394_LDFLAGS = $(top_builddir)/src/libcurltool.la
unit1394_LIBS =

unit1395_SOURCES = unit1395.c $(UNITFILES)

unit1396_SOURCES = unit1396.c $(UNITFILES)

unit1397_SOURCES = unit1397.c $(UNITFILES)

unit1398_SOURCES = unit1398.c $(UNITFILES)

unit1399_SOURCES = unit1399.c $(UNITFILES)

unit1600_SOURCES = unit1600.c $(UNITFILES)

unit1601_SOURCES = unit1601.c $(UNITFILES)

unit1602_SOURCES = unit1602.c $(UNITFILES)

unit1603_SOURCES = unit1603.c $(UNITFILES)

unit1604_SOURCES = unit1604.c $(UNITFILES)

unit1605_SOURCES = unit1605.c $(UNITFILES)

unit1606_SOURCES = unit1606.c $(UNITFILES)

unit1607_SOURCES = unit1607.c $(UNITFILES)

unit1608_SOURCES = unit1608.c $(UNITFILES)

unit1609_SOURCES = unit1609.c $(UNITFILES)

unit1610_SOURCES = unit1610.c $(UNITFILES)

unit1611_SOURCES = unit1611.c $(UNITFILES)

unit1612_SOURCES = unit1612.c $(UNITFILES)

unit1614_SOURCES = unit1614.c $(UNITFILES)

unit1620_SOURCES = unit1620.c $(UNITFILES)

unit1621_SOURCES = unit1621.c $(UNITFILES)
unit1621_LDADD = $(top_builddir)/src/libcurltool.la $(top_builddir)/lib/libcurl.la @NSS_LIBS@

unit1650_SOURCES = unit1650.c $(UNITFILES)

unit1651_SOURCES = unit1651.c $(UNITFILES)

unit1652_SOURCES = unit1652.c $(UNITFILES)

unit1653_SOURCES = unit1653.c $(UNITFILES)

unit1654_SOURCES = unit1654.c $(UNITFILES)

unit1655_SOURCES = unit1655.c $(UNITFILES)

unit1660_SOURCES = unit1660.c $(UNITFILES)

unit1661_SOURCES = unit1661.c $(UNITFILES)

unit2600_SOURCES = unit2600.c $(UNITFILES)

unit2601_SOURCES = unit2601.c $(UNITFILES)

unit2602_SOURCES = unit2602.c $(UNITFILES)

unit2603_SOURCES = unit2603.c $(UNITFILES)

unit3200_SOURCES = unit3200.c $(UNITFILES)
94 changes: 94 additions & 0 deletions tests/unit/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,97 @@ UNITPROGS = unit1300 unit1302 unit1303 unit1304 unit1305 unit1307 \
unit1660 unit1661 \
unit2600 unit2601 unit2602 unit2603 \
unit3200

unit1300_SOURCES = unit1300.c $(UNITFILES)

unit1302_SOURCES = unit1302.c $(UNITFILES)

unit1303_SOURCES = unit1303.c $(UNITFILES)

unit1304_SOURCES = unit1304.c $(UNITFILES)

unit1305_SOURCES = unit1305.c $(UNITFILES)

unit1307_SOURCES = unit1307.c $(UNITFILES)

unit1308_SOURCES = unit1308.c $(UNITFILES)

unit1309_SOURCES = unit1309.c $(UNITFILES)

unit1323_SOURCES = unit1323.c $(UNITFILES)

unit1330_SOURCES = unit1330.c $(UNITFILES)

unit1394_SOURCES = unit1394.c $(UNITFILES)
unit1394_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
unit1394_LDFLAGS = $(top_builddir)/src/libcurltool.la
unit1394_LIBS =

unit1395_SOURCES = unit1395.c $(UNITFILES)

unit1396_SOURCES = unit1396.c $(UNITFILES)

unit1397_SOURCES = unit1397.c $(UNITFILES)

unit1398_SOURCES = unit1398.c $(UNITFILES)

unit1399_SOURCES = unit1399.c $(UNITFILES)

unit1600_SOURCES = unit1600.c $(UNITFILES)

unit1601_SOURCES = unit1601.c $(UNITFILES)

unit1602_SOURCES = unit1602.c $(UNITFILES)

unit1603_SOURCES = unit1603.c $(UNITFILES)

unit1604_SOURCES = unit1604.c $(UNITFILES)

unit1605_SOURCES = unit1605.c $(UNITFILES)

unit1606_SOURCES = unit1606.c $(UNITFILES)

unit1607_SOURCES = unit1607.c $(UNITFILES)

unit1608_SOURCES = unit1608.c $(UNITFILES)

unit1609_SOURCES = unit1609.c $(UNITFILES)

unit1610_SOURCES = unit1610.c $(UNITFILES)

unit1611_SOURCES = unit1611.c $(UNITFILES)

unit1612_SOURCES = unit1612.c $(UNITFILES)

unit1614_SOURCES = unit1614.c $(UNITFILES)

unit1620_SOURCES = unit1620.c $(UNITFILES)

unit1621_SOURCES = unit1621.c $(UNITFILES)
unit1621_LDADD = $(top_builddir)/src/libcurltool.la $(top_builddir)/lib/libcurl.la @NSS_LIBS@

unit1650_SOURCES = unit1650.c $(UNITFILES)

unit1651_SOURCES = unit1651.c $(UNITFILES)

unit1652_SOURCES = unit1652.c $(UNITFILES)

unit1653_SOURCES = unit1653.c $(UNITFILES)

unit1654_SOURCES = unit1654.c $(UNITFILES)

unit1655_SOURCES = unit1655.c $(UNITFILES)

unit1660_SOURCES = unit1660.c $(UNITFILES)

unit1661_SOURCES = unit1661.c $(UNITFILES)

unit2600_SOURCES = unit2600.c $(UNITFILES)

unit2601_SOURCES = unit2601.c $(UNITFILES)

unit2602_SOURCES = unit2602.c $(UNITFILES)

unit2603_SOURCES = unit2603.c $(UNITFILES)

unit3200_SOURCES = unit3200.c $(UNITFILES)
Loading

0 comments on commit 8d6a750

Please sign in to comment.