Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ curl_verbose_msg="enabled (--disable-verbose)"
curl_rtmp_msg="no (--with-librtmp)"
curl_mtlnk_msg="no (--with-libmetalink)"
curl_psl_msg="no (--with-libpsl)"
curl_hsts_msg="no (--with-libhsts)"

ssl_backends=

Expand Down Expand Up @@ -3662,6 +3663,100 @@ if test X"$want_quiche" != Xno; then
fi
fi

dnl **********************************************************************
dnl Check for libhsts
dnl **********************************************************************
dnl libhsts project home page: https://gitlab.com/rockdaboot/libhsts
OPT_HSTS=off
AC_ARG_WITH(libhsts,dnl
AC_HELP_STRING([--with-libhsts=PATH],[Where to look for libhsts, PATH points to the libhsts installation; when possible, set the PKG_CONFIG_PATH environment variable instead of using this option])
AC_HELP_STRING([--without-libhsts], [disable HSTS]),
OPT_HSTS=$withval)

if test X"$OPT_HSTS" != Xno; then
dnl backup the pre-hsts variables
CLEANLDFLAGS="$LDFLAGS"
CLEANCPPFLAGS="$CPPFLAGS"
CLEANLIBS="$LIBS"

case "$OPT_HSTS" in
yes)
dnl --with-hsts (without path) used
CURL_CHECK_PKGCONFIG(libhsts)

if test "$PKGCONFIG" != "no" ; then
LIB_HSTS=`$PKGCONFIG --libs-only-l libhsts`
LD_HSTS=`$PKGCONFIG --libs-only-L libhsts`
CPP_HSTS=`$PKGCONFIG --cflags-only-I libhsts`
version=`$PKGCONFIG --modversion libhsts`
DIR_HSTS=`echo $LD_HSTS | $SED -e 's/-L//'`
fi

;;
off)
dnl no --with-hsts option given, just check default places
;;
*)
dnl use the given --with-hsts spot
PREFIX_HSTS=$OPT_HSTS
;;
esac

dnl if given with a prefix, we set -L and -I based on that
if test -n "$PREFIX_HSTS"; then
LIB_HSTS="-lhsts"
LD_HSTS=-L${PREFIX_HSTS}/lib$libsuff
CPP_HSTS=-I${PREFIX_HSTS}/include
DIR_HSTS=${PREFIX_HSTS}/lib$libsuff
fi

LDFLAGS="$LDFLAGS $LD_HSTS"
CPPFLAGS="$CPPFLAGS $CPP_HSTS"
LIBS="$LIB_HSTS $LIBS"

AC_CHECK_LIB(hsts, hsts_search)

AC_CHECK_HEADERS(libhsts.h,
curl_hsts_msg="enabled (libhsts)"
HAVE_HSTS=1
AC_DEFINE(USE_HSTS, 1, [if HSTS is in use])
AC_SUBST(USE_HSTS, [1])
)

if test X"$OPT_HSTS" != Xoff &&
test "$HAVE_HSTS" != "1"; then
AC_MSG_ERROR([HSTS libs and/or directories were not found where specified!])
fi

if test "$HAVE_HSTS" = "1"; then
if test -n "$DIR_HSTS"; then
dnl when the hsts shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to LD_LIBRARY_PATH
dnl to prevent further configure tests to fail due to this

if test "x$cross_compiling" != "xyes"; then
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$DIR_HSTS"
export LD_LIBRARY_PATH
AC_MSG_NOTICE([Added $DIR_HSTS to LD_LIBRARY_PATH])
fi
fi

AC_ARG_WITH(hsts-preload-file,
AC_HELP_STRING([--with-hsts-preload-file=FILE],
[Path to hsts.dafsa file]),
[ HSTS_PRELOAD_FILE="$withval" ] )
if test -n "$HSTS_PRELOAD_FILE" ; then
AC_DEFINE_UNQUOTED(HSTS_PRELOAD_FILE, "$HSTS_PRELOAD_FILE",
[Path to hsts.dafsa file] )
fi
else
dnl no hsts, revert back to clean variables
LDFLAGS=$CLEANLDFLAGS
CPPFLAGS=$CLEANCPPFLAGS
LIBS=$CLEANLIBS
fi
fi

dnl **********************************************************************
dnl Check for zsh completion path
dnl **********************************************************************
Expand Down Expand Up @@ -4801,6 +4896,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
Alt-svc: ${curl_altsvc_msg}
HTTP2: ${curl_h2_msg}
HTTP3: ${curl_h3_msg}
HSTS: ${curl_hsts_msg}
Protocols: ${SUPPORT_PROTOCOLS}
Features: ${SUPPORT_FEATURES}
])
Expand Down
2 changes: 2 additions & 0 deletions docs/libcurl/curl_easy_setopt.3
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ This HTTP/2 stream depends on another exclusively. See
\fICURLOPT_STREAM_DEPENDS_E(3)\fP
.IP CURLOPT_STREAM_WEIGHT
Set this HTTP/2 stream's weight. See \fICURLOPT_STREAM_WEIGHT(3)\fP
.IP CURLOPT_HSTS_PRELOAD_FILE
Preload HSTS data from a file. See \fICURLOPT_HSTS_PRELOAD_FILE(3)\fP
.SH SMTP OPTIONS
.IP CURLOPT_MAIL_FROM
Address of the sender. See \fICURLOPT_MAIL_FROM(3)\fP
Expand Down
3 changes: 3 additions & 0 deletions docs/libcurl/curl_version_info.3
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ to use the current user credentials without the app having to pass them on.
(Added in 7.38.0)
.IP CURL_VERSION_GSSNEGOTIATE
supports HTTP GSS-Negotiate (added in 7.10.6)
.IP CURL_VERSION_HSTS
libcurl was built with support for HSTS
(Added in 7.67.0)
.IP CURL_VERSION_HTTPS_PROXY
libcurl was built with support for HTTPS-proxy.
(Added in 7.52.0)
Expand Down
54 changes: 54 additions & 0 deletions docs/libcurl/opts/CURLOPT_HSTS_PRELOAD_FILE.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.\" **************************************************************************
.\" * _ _ ____ _
.\" * Project ___| | | | _ \| |
.\" * / __| | | | |_) | |
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <[email protected]>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
.\" *
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
.\" * copies of the Software, and permit persons to whom the Software is
.\" * furnished to do so, under the terms of the COPYING file.
.\" *
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
.\" * KIND, either express or implied.
.\" *
.\" **************************************************************************
.\"
.TH CURLOPT_HSTS_PRELOAD_FILE 3 "13 Sep 2019" "libcurl 7.67.0" "curl_easy_setopt options"
.SH NAME
CURLOPT_HSTS_PRELOAD_FILE \- specify a source for hsts preload data
.SH SYNOPSIS
#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HSTS_PRELOAD_FILE, char *path);
.SH DESCRIPTION
Pass a char * to a zero terminated file name. It must be a DAFSA file and
is read from to preload libhsts.

The application does not have to keep the string around after setting this
option.
.SH DEFAULT
NULL, not used
.SH PROTOCOLS
All
.SH EXAMPLE
.nf
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(curl, CURLOPT_HSTS_PRELOAD_FILE, "/var/lib/hsts.dafsa");
ret = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
.fi
.SH AVAILABILITY
Added in 7.67.0
.SH RETURN VALUE
Returns CURLE_OK on success or
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
1 change: 1 addition & 0 deletions docs/libcurl/opts/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ man_MANS = \
CURLOPT_HEADERDATA.3 \
CURLOPT_HEADERFUNCTION.3 \
CURLOPT_HEADEROPT.3 \
CURLOPT_HSTS_PRELOAD_FILE.3 \
CURLOPT_HTTP09_ALLOWED.3 \
CURLOPT_HTTP200ALIASES.3 \
CURLOPT_HTTPAUTH.3 \
Expand Down
2 changes: 2 additions & 0 deletions docs/libcurl/symbols-in-versions
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ CURLOPT_HEADER 7.1
CURLOPT_HEADERDATA 7.10
CURLOPT_HEADERFUNCTION 7.7.2
CURLOPT_HEADEROPT 7.37.0
CURLOPT_HSTS_PRELOAD_FILE 7.67.0
CURLOPT_HTTP09_ALLOWED 7.64.0
CURLOPT_HTTP200ALIASES 7.10.3
CURLOPT_HTTPAUTH 7.10.6
Expand Down Expand Up @@ -927,6 +928,7 @@ CURL_VERSION_CURLDEBUG 7.19.6
CURL_VERSION_DEBUG 7.10.6
CURL_VERSION_GSSAPI 7.38.0
CURL_VERSION_GSSNEGOTIATE 7.10.6 7.38.0
CURL_VERSION_HSTS 7.67.0
CURL_VERSION_HTTP2 7.33.0
CURL_VERSION_HTTP3 7.66.0
CURL_VERSION_HTTPS_PROXY 7.52.0
Expand Down
4 changes: 4 additions & 0 deletions include/curl/curl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,9 @@ typedef enum {
/* SASL authorisation identity */
CINIT(SASL_AUTHZID, STRINGPOINT, 289),

/* Set this option to the file you want to preload hsts data from */
CINIT(HSTS_PRELOAD_FILE, STRINGPOINT, 290),

CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

Expand Down Expand Up @@ -2799,6 +2802,7 @@ typedef struct {
#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */
#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */
#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */
#define CURL_VERSION_HSTS (1<<26) /* HSTS features are present */

/*
* NAME curl_version_info()
Expand Down
1 change: 1 addition & 0 deletions include/curl/typecheck-gcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
(option) == CURLOPT_FTPPORT || \
(option) == CURLOPT_FTP_ACCOUNT || \
(option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \
(option) == CURLOPT_HSTS_PRELOAD_FILE || \
(option) == CURLOPT_INTERFACE || \
(option) == CURLOPT_ISSUERCERT || \
(option) == CURLOPT_KEYPASSWD || \
Expand Down
9 changes: 9 additions & 0 deletions lib/setopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE],
va_arg(param, char *));
break;
#endif
#ifdef USE_HSTS
case CURLOPT_HSTS_PRELOAD_FILE:
/*
* Use this file to preload the HSTS lookup database
*/
result = Curl_setstropt(&data->set.str[STRING_HSTS_PRELOAD_FILE],
va_arg(param, char *));
break;
#endif
case CURLOPT_TRANSFERTEXT:
/*
Expand Down
57 changes: 54 additions & 3 deletions lib/url.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ bool curl_win32_idn_to_ascii(const char *in, char **out);
#include "strdup.h"
#include "setopt.h"
#include "altsvc.h"
#ifdef USE_HSTS
#include <libhsts.h>
#endif

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
Expand Down Expand Up @@ -290,6 +293,10 @@ void Curl_freeset(struct Curl_easy *data)
data->change.url = NULL;

Curl_mime_cleanpart(&data->set.mimepost);

#ifdef USE_HSTS
hsts_free(data->set.hsts);
#endif
}

/* free the URL pieces */
Expand Down Expand Up @@ -615,6 +622,35 @@ CURLcode Curl_open(struct Curl_easy **curl)

Curl_http2_init_state(&data->state);
}

#ifdef USE_HSTS
{
char *hsts_preload = NULL;
hsts_status_t hsts_status = HSTS_ERR_INPUT_FAILURE;
#if DEBUGBUILD
char *debug_hsts_file = curl_getenv("CURL_HSTSFILE");
if(debug_hsts_file) {
DEBUGF(fprintf(stderr, "DEBUG: HSTS file override: %s\n",
debug_hsts_file));
hsts_status = hsts_load_file(debug_hsts_file, &data->set.hsts);
free(debug_hsts_file);
}
else
#endif
hsts_preload = data->set.str[STRING_HSTS_PRELOAD_FILE];
#ifdef HSTS_PRELOAD_FILE
if(!hsts_preload)
hsts_preload = HSTS_PRELOAD_FILE
#endif
if(hsts_preload) {
hsts_status = hsts_load_file(hsts_preload, &data->set.hsts);
if(hsts_status < HSTS_SUCCESS) {
fprintf(stderr, "Failed loading HSTS preload file, error code %d!\n",
hsts_status);
}
}
}
#endif
}

if(result) {
Expand Down Expand Up @@ -1647,22 +1683,37 @@ const struct Curl_handler *Curl_builtin_scheme(const char *scheme)
{
const struct Curl_handler * const *pp;
const struct Curl_handler *p;
/* Scan protocol handler table and match against 'scheme'. The handler may
be changed later when the protocol specific setup function is called. */

/* Scan protocol handler table and match against 'protostr' to set a few
variables based on the URL. Now that the handler may be changed later
when the protocol specific setup function is called. */
for(pp = protocols; (p = *pp) != NULL; pp++)
if(strcasecompare(p->scheme, scheme))
/* Protocol found in table. Check if allowed */
return p;

return NULL; /* not found */
}


static CURLcode findprotocol(struct Curl_easy *data,
struct connectdata *conn,
const char *protostr)
{
const struct Curl_handler *p = Curl_builtin_scheme(protostr);

#ifdef USE_HSTS
/* HSTS means we override any http access with https if the domain
is listed in the HSTS database */
if(data->set.hsts && strcasecompare(protostr, "http")) {
hsts_status_t hsts_status = hsts_search(data->set.hsts,
conn->host.name, 0, NULL);
if(hsts_status == HSTS_SUCCESS) {
infof(data, "Domain found in HSTS database, upgrading to https\n");
p = Curl_builtin_scheme("https");
}
}
#endif

if(p && /* Protocol found in table. Check if allowed */
(data->set.allowed_protocols & p->protocol)) {

Expand Down
10 changes: 10 additions & 0 deletions lib/urldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ typedef enum {
#include <iconv.h>
#endif

#ifdef USE_HSTS
#include <libhsts.h>
#endif

/* Struct used for GSSAPI (Kerberos V5) authentication */
#if defined(USE_KERBEROS5)
struct kerberos5data {
Expand Down Expand Up @@ -1508,6 +1512,9 @@ enum dupstring {
STRING_SASL_AUTHZID, /* CURLOPT_SASL_AUTHZID */
#ifndef CURL_DISABLE_PROXY
STRING_TEMP_URL, /* temp URL storage for proxy use */
#endif
#ifdef USE_HSTS
STRING_HSTS_PRELOAD_FILE, /* file to preload hsts info from */
#endif
/* -- end of zero-terminated strings -- */

Expand Down Expand Up @@ -1766,6 +1773,9 @@ struct UserDefined {
bit doh:1; /* DNS-over-HTTPS enabled */
bit doh_get:1; /* use GET for DoH requests, instead of POST */
bit http09_allowed:1; /* allow HTTP/0.9 responses */
#ifdef USE_HSTS
hsts_t *hsts; /* libhsts handle */
#endif
};

struct Names {
Expand Down
Loading