New function to check for literal IPv4/IPv6 addresses

* bootstrap.conf: Add gnulib module 'inet_pton'
* docs/Makefile.am: Add man page libwget-ip.3
* wget/wget.h (struct wget_iri_st): New field 'is_ip_address'.
* libwget/Makefile.am: Add new file ip.c
* libwget/ip.c: New file defining new function wget_ip_is_family()
* libwget/iri.c (wget_iri_parse): Check for literal IP address
* src/wget.c: Do not add to HSTS if literal IP address
This commit is contained in:
Ander Juaristi
2016-11-06 17:12:21 +01:00
committed by Tim Rühsen
parent cdc1ed3b83
commit 58d18ad60c
7 changed files with 85 additions and 3 deletions

View File

@ -60,6 +60,7 @@ gettime
gitlog-to-changelog
glob
iconv
inet_pton
inline
inttypes
ioctl

View File

@ -13,7 +13,8 @@ man3_MANS =\
$(builddir)/man/man3/libwget-base64.3\
$(builddir)/man/man3/libwget-parse_atom.3\
$(builddir)/man/man3/libwget-parse_sitemap.3\
$(builddir)/man/man3/libwget-robots.3
$(builddir)/man/man3/libwget-robots.3\
$(builddir)/man/man3/libwget-ip.3
$(man3_MANS): doxy.stamp

View File

@ -829,6 +829,8 @@ typedef struct wget_iri_st {
query_allocated : 1; // if set, free query in iri_free()
unsigned int
fragment_allocated : 1; // if set, free fragment in iri_free()
unsigned int
is_ip_address : 1; // if set, the hostname part is a literal IPv4 or IPv6 address
} wget_iri_t;
void
@ -1322,6 +1324,9 @@ ssize_t
int
wget_tcp_ready_2_transfer(wget_tcp_t *tcp, int flags) G_GNUC_WGET_NONNULL_ALL LIBWGET_EXPORT;
int
wget_ip_is_family(const char *host, int family) G_GNUC_WGET_PURE LIBWGET_EXPORT;
/*
* SSL routines
*/

View File

@ -4,7 +4,7 @@ lib_LTLIBRARIES = libwget.la
libwget_la_SOURCES = \
atom_url.c bar.c buffer.c buffer_printf.c base64.c cookie.c\
css.c css_tokenizer.c css_tokenizer.h css_tokenizer.lex css_url.c\
decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c iri.c\
decompressor.c encoding.c hashfile.c hashmap.c io.c hsts.c html_url.c http.c init.c ip.c iri.c\
list.c log.c logger.c md5.c mem.c metalink.c net.c net.h netrc.c ocsp.c pipe.c printf.c random.c \
robots.c rss_url.c sitemap_url.c ssl_gnutls.c stringmap.c strlcpy.c thread.c tls_session.c utils.c \
vector.c xalloc.c xml.c private.h http_highlevel.c

69
libwget/ip.c Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright(c) 2016 Free Software Foundation, Inc.
*
* This file is part of libwget.
*
* Libwget is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Libwget is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libwget. If not, see <http://www.gnu.org/licenses/>.
*
*
* IP address helper routines
*
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <wget.h>
#include "private.h"
/**
* \file
* \brief IP address functions
* \defgroup libwget-ip IP address functions
* @{
*
* Routines to check IP address formats.
*/
/**
* \param[in] host Host/IP String
* \param[in] family IP address family
* \return
* 1 if \host matches is of \p family<br>
* 0 if \p host does not match \p family<br>
*
* This functions checks if \p host matches the given \p family or not.
*/
int wget_ip_is_family(const char *host, int family)
{
struct sockaddr_storage dst;
if (!host)
return 0;
switch (family) {
case WGET_NET_FAMILY_IPV4:
return inet_pton(AF_INET, host, (struct in_addr *) &dst);
case WGET_NET_FAMILY_IPV6:
return inet_pton(AF_INET6, host, (struct in6_addr *) &dst);
default:
return 0;
}
}
/**@}*/

View File

@ -373,6 +373,10 @@ wget_iri_t *wget_iri_parse(const char *url, const char *encoding)
iri->host = p;
iri->host_allocated = 1;
}
// Finally, if the host is a literal IPv4 or IPv6 address, mark it as so
if (wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV4) || wget_ip_is_family(iri->host, WGET_NET_FAMILY_IPV6))
iri->is_ip_address = 1;
}
else {
if (iri->scheme == WGET_IRI_SCHEME_HTTP || iri->scheme == WGET_IRI_SCHEME_HTTPS) {

View File

@ -1239,7 +1239,9 @@ static int process_response_header(wget_http_response_t *resp)
wget_cookie_store_cookies(config.cookie_db, resp->cookies); // store cookies
// care for HSTS feature
if (config.hsts && iri->scheme == WGET_IRI_SCHEME_HTTPS && resp->hsts) {
if (config.hsts &&
iri->scheme == WGET_IRI_SCHEME_HTTPS && !iri->is_ip_address &&
resp->hsts) {
wget_hsts_db_add(config.hsts_db, wget_hsts_new(iri->host, atoi(iri->resolv_port), resp->hsts_maxage, resp->hsts_include_subdomains));
hsts_changed = 1;
}