mirror of
https://github.com/curl/curl.git
synced 2025-09-14 16:12:43 +03:00
cmake: add support for "unity" builds
Aka "jumbo" or "amalgamation" builds. It means to compile all sources per target as a single C source. This is experimental. You can enable it by passing `-DCMAKE_UNITY_BUILD=ON` to cmake. It requires CMake 3.16 or newer. It makes builds (much) faster, allows for better optimizations and tends to promote less ambiguous code. Also add a new AppVeyor CI job and convert an existing one to use "unity" mode (one MSVC, one MinGW), and enable it for one macOS CI job. Fix related issues: - add missing include guard to `easy_lock.h`. - rename static variables and functions (and a macro) with names reused across sources, or shadowed by local variables. - add an `#undef` after use. - add a missing `#undef` before use. - move internal definitions from `ftp.h` to `ftp.c`. - `curl_memory.h` fixes to make it work when included repeatedly. - stop building/linking curlx bits twice for a static-mode curl tool. These caused doubly defined symbols in unity builds. - silence missing extern declarations compiler warning for ` _CRT_glob`. - fix extern declarations for `tool_freq` and `tool_isVistaOrGreater`. - fix colliding static symbols in debug mode: `debugtime()` and `statename`. - rename `ssl_backend_data` structure to unique names for each TLS-backend, along with the `ssl_connect_data` struct member referencing them. This required adding casts for each access. - add workaround for missing `[P]UNICODE_STRING` types in certain Windows builds when compiling `lib/ldap.c`. To support "unity" builds, we had to enable `SCHANNEL_USE_BLACKLISTS` for Schannel (a Windows `schannel.h` option) _globally_. This caused an indirect inclusion of Windows `schannel.h` from `ldap.c` via `winldap.h` to have it enabled as well. This requires `[P]UNICODE_STRING` types, which is apperantly not defined automatically (as seen with both MSVS and mingw-w64). This patch includes `<subauth.h>` to fix it. Ref: https://github.com/curl/curl/runs/13987772013 Ref: https://dev.azure.com/daniel0244/curl/_build/results?buildId=15827&view=logs&jobId=2c9f582d-e278-56b6-4354-f38a4d851906&j=2c9f582d-e278-56b6-4354-f38a4d851906&t=90509b00-34fa-5a81-35d7-5ed9569d331c - tweak unity builds to compile `lib/memdebug.c` separately in memory trace builds to avoid PP confusion. - force-disable unity for test programs. - do not compile and link libcurl sources to libtests _twice_ when libcurl is built in static mode. KNOWN ISSUES: - running tests with unity builds may fail in cases. - some build configurations/env may not compile in unity mode. E.g.: https://ci.appveyor.com/project/curlorg/curl/builds/47230972/job/51wfesgnfuauwl8q#L250 Ref: https://github.com/libssh2/libssh2/issues/1034 Ref: https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html Ref: https://en.wikipedia.org/wiki/Unity_build Closes #11095
This commit is contained in:
parent
e812473d1e
commit
3f8fc25720
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
|
@ -165,7 +165,7 @@ jobs:
|
||||||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON
|
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON
|
||||||
- name: LibreSSL
|
- name: LibreSSL
|
||||||
install: nghttp2 libressl
|
install: nghttp2 libressl
|
||||||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/libressl -DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON
|
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/libressl -DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON -DCMAKE_UNITY_BUILD=ON
|
||||||
- name: libssh2
|
- name: libssh2
|
||||||
install: nghttp2 openssl libssh2
|
install: nghttp2 openssl libssh2
|
||||||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_USE_LIBSSH2=ON
|
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_USE_LIBSSH2=ON
|
||||||
|
|
|
@ -97,6 +97,8 @@ endif()
|
||||||
|
|
||||||
include_directories(${CURL_SOURCE_DIR}/include)
|
include_directories(${CURL_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
|
||||||
|
|
||||||
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
|
option(CURL_WERROR "Turn compiler warnings into errors" OFF)
|
||||||
option(PICKY_COMPILER "Enable picky compiler options" ON)
|
option(PICKY_COMPILER "Enable picky compiler options" ON)
|
||||||
option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
|
option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
|
||||||
|
|
22
appveyor.yml
22
appveyor.yml
|
@ -28,6 +28,7 @@
|
||||||
version: 7.50.0.{build}
|
version: 7.50.0.{build}
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
UNITY: "OFF"
|
||||||
matrix:
|
matrix:
|
||||||
# generated CMake-based Visual Studio Release builds
|
# generated CMake-based Visual Studio Release builds
|
||||||
- job_name: "CMake, VS2008, Release x86, Schannel"
|
- job_name: "CMake, VS2008, Release x86, Schannel"
|
||||||
|
@ -42,7 +43,7 @@ environment:
|
||||||
TESTING: OFF
|
TESTING: OFF
|
||||||
SHARED: ON
|
SHARED: ON
|
||||||
DISABLED_TESTS: ""
|
DISABLED_TESTS: ""
|
||||||
- job_name: "CMake, VS2022, Release x64, OpenSSL, WebSockets"
|
- job_name: "CMake, VS2022, Release x64, OpenSSL, WebSockets, Unity"
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022"
|
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022"
|
||||||
BUILD_SYSTEM: CMake
|
BUILD_SYSTEM: CMake
|
||||||
PRJ_GEN: "Visual Studio 17 2022"
|
PRJ_GEN: "Visual Studio 17 2022"
|
||||||
|
@ -56,6 +57,7 @@ environment:
|
||||||
SHARED: ON
|
SHARED: ON
|
||||||
DISABLED_TESTS: ""
|
DISABLED_TESTS: ""
|
||||||
WEBSOCKETS: ON
|
WEBSOCKETS: ON
|
||||||
|
UNITY: "ON"
|
||||||
- job_name: "CMake, VS2022, Release arm64, Schannel, Static"
|
- job_name: "CMake, VS2022, Release arm64, Schannel, Static"
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022"
|
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2022"
|
||||||
BUILD_SYSTEM: CMake
|
BUILD_SYSTEM: CMake
|
||||||
|
@ -156,6 +158,21 @@ environment:
|
||||||
ADD_PATH: "C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin;C:\\msys64\\usr\\bin"
|
ADD_PATH: "C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin;C:\\msys64\\usr\\bin"
|
||||||
MSYS2_ARG_CONV_EXCL: "/*"
|
MSYS2_ARG_CONV_EXCL: "/*"
|
||||||
BUILD_OPT: -k
|
BUILD_OPT: -k
|
||||||
|
- job_name: "CMake, mingw-w64, Debug x64, Schannel, Static, Unity"
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
|
||||||
|
BUILD_SYSTEM: CMake
|
||||||
|
PRJ_GEN: "MSYS Makefiles"
|
||||||
|
PRJ_CFG: Debug
|
||||||
|
OPENSSL: OFF
|
||||||
|
SCHANNEL: ON
|
||||||
|
ENABLE_UNICODE: OFF
|
||||||
|
HTTP_ONLY: OFF
|
||||||
|
TESTING: OFF
|
||||||
|
SHARED: OFF
|
||||||
|
ADD_PATH: "C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin;C:\\msys64\\usr\\bin"
|
||||||
|
MSYS2_ARG_CONV_EXCL: "/*"
|
||||||
|
BUILD_OPT: -k
|
||||||
|
UNITY: "ON"
|
||||||
- job_name: "CMake, mingw-w64, Debug x86, Schannel, Static"
|
- job_name: "CMake, mingw-w64, Debug x86, Schannel, Static"
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
|
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2015"
|
||||||
BUILD_SYSTEM: CMake
|
BUILD_SYSTEM: CMake
|
||||||
|
@ -297,6 +314,7 @@ build_script:
|
||||||
-DBUILD_SHARED_LIBS=%SHARED%
|
-DBUILD_SHARED_LIBS=%SHARED%
|
||||||
-DBUILD_TESTING=%TESTING%
|
-DBUILD_TESTING=%TESTING%
|
||||||
-DENABLE_WEBSOCKETS=%WEBSOCKETS%
|
-DENABLE_WEBSOCKETS=%WEBSOCKETS%
|
||||||
|
-DCMAKE_UNITY_BUILD=%UNITY%
|
||||||
-DCURL_WERROR=ON
|
-DCURL_WERROR=ON
|
||||||
-DENABLE_DEBUG=ON
|
-DENABLE_DEBUG=ON
|
||||||
-DENABLE_UNICODE=%ENABLE_UNICODE%
|
-DENABLE_UNICODE=%ENABLE_UNICODE%
|
||||||
|
@ -370,4 +388,4 @@ artifacts:
|
||||||
- path: '**/curl.exe'
|
- path: '**/curl.exe'
|
||||||
name: curl
|
name: curl
|
||||||
- path: '**/*curl*.dll'
|
- path: '**/*curl*.dll'
|
||||||
name: libcurl
|
name: libcurl dll
|
||||||
|
|
|
@ -69,6 +69,12 @@ add_library(
|
||||||
ALIAS ${LIB_NAME}
|
ALIAS ${LIB_NAME}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(ENABLE_CURLDEBUG)
|
||||||
|
# We must compile memdebug.c separately to avoid memdebug.h redefinitions
|
||||||
|
# being applied to memdebug.c itself.
|
||||||
|
set_source_files_properties(memdebug.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT BUILD_SHARED_LIBS)
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -72,6 +72,7 @@ LIB_VTLS_HFILES = \
|
||||||
vtls/openssl.h \
|
vtls/openssl.h \
|
||||||
vtls/rustls.h \
|
vtls/rustls.h \
|
||||||
vtls/schannel.h \
|
vtls/schannel.h \
|
||||||
|
vtls/schannel_int.h \
|
||||||
vtls/sectransp.h \
|
vtls/sectransp.h \
|
||||||
vtls/vtls.h \
|
vtls/vtls.h \
|
||||||
vtls/vtls_int.h \
|
vtls/vtls_int.h \
|
||||||
|
|
|
@ -424,7 +424,7 @@ static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
/* to play well with debug builds, we can *set* a fixed time this will
|
/* to play well with debug builds, we can *set* a fixed time this will
|
||||||
return */
|
return */
|
||||||
static time_t debugtime(void *unused)
|
static time_t altsvc_debugtime(void *unused)
|
||||||
{
|
{
|
||||||
char *timestr = getenv("CURL_TIME");
|
char *timestr = getenv("CURL_TIME");
|
||||||
(void)unused;
|
(void)unused;
|
||||||
|
@ -434,7 +434,8 @@ static time_t debugtime(void *unused)
|
||||||
}
|
}
|
||||||
return time(NULL);
|
return time(NULL);
|
||||||
}
|
}
|
||||||
#define time(x) debugtime(x)
|
#undef time
|
||||||
|
#define time(x) altsvc_debugtime(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
#define ISNEWLINE(x) (((x) == '\n') || (x) == '\r')
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
/* ---- Base64 Encoding/Decoding Table --- */
|
/* ---- Base64 Encoding/Decoding Table --- */
|
||||||
/* Padding character string starts at offset 64. */
|
/* Padding character string starts at offset 64. */
|
||||||
static const char base64[]=
|
static const char base64encdec[]=
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
|
||||||
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
|
/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648
|
||||||
|
@ -120,7 +120,7 @@ CURLcode Curl_base64_decode(const char *src,
|
||||||
/* replaces
|
/* replaces
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
const unsigned char *p = (const unsigned char *)base64;
|
const unsigned char *p = (const unsigned char *)base64encdec;
|
||||||
for(c = 0; *p; c++, p++)
|
for(c = 0; *p; c++, p++)
|
||||||
lookup[*p] = c;
|
lookup[*p] = c;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ static CURLcode base64_encode(const char *table64,
|
||||||
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
CURLcode Curl_base64_encode(const char *inputbuff, size_t insize,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
return base64_encode(base64, inputbuff, insize, outptr, outlen);
|
return base64_encode(base64encdec, inputbuff, insize, outptr, outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -54,16 +54,16 @@
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TUNNEL_INIT, /* init/default/no tunnel state */
|
H1_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||||
TUNNEL_CONNECT, /* CONNECT request is being send */
|
H1_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||||
TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */
|
||||||
TUNNEL_RESPONSE, /* CONNECT response received completely */
|
H1_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||||
TUNNEL_ESTABLISHED,
|
H1_TUNNEL_ESTABLISHED,
|
||||||
TUNNEL_FAILED
|
H1_TUNNEL_FAILED
|
||||||
} tunnel_state;
|
} h1_tunnel_state;
|
||||||
|
|
||||||
/* struct for HTTP CONNECT tunneling */
|
/* struct for HTTP CONNECT tunneling */
|
||||||
struct tunnel_state {
|
struct h1_tunnel_state {
|
||||||
int sockindex;
|
int sockindex;
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
int remote_port;
|
int remote_port;
|
||||||
|
@ -78,23 +78,23 @@ struct tunnel_state {
|
||||||
KEEPON_IGNORE
|
KEEPON_IGNORE
|
||||||
} keepon;
|
} keepon;
|
||||||
curl_off_t cl; /* size of content to read and ignore */
|
curl_off_t cl; /* size of content to read and ignore */
|
||||||
tunnel_state tunnel_state;
|
h1_tunnel_state tunnel_state;
|
||||||
BIT(chunked_encoding);
|
BIT(chunked_encoding);
|
||||||
BIT(close_connection);
|
BIT(close_connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static bool tunnel_is_established(struct tunnel_state *ts)
|
static bool tunnel_is_established(struct h1_tunnel_state *ts)
|
||||||
{
|
{
|
||||||
return ts && (ts->tunnel_state == TUNNEL_ESTABLISHED);
|
return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tunnel_is_failed(struct tunnel_state *ts)
|
static bool tunnel_is_failed(struct h1_tunnel_state *ts)
|
||||||
{
|
{
|
||||||
return ts && (ts->tunnel_state == TUNNEL_FAILED);
|
return ts && (ts->tunnel_state == H1_TUNNEL_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode tunnel_reinit(struct tunnel_state *ts,
|
static CURLcode tunnel_reinit(struct h1_tunnel_state *ts,
|
||||||
struct connectdata *conn,
|
struct connectdata *conn,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +102,7 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
|
||||||
DEBUGASSERT(ts);
|
DEBUGASSERT(ts);
|
||||||
Curl_dyn_reset(&ts->rcvbuf);
|
Curl_dyn_reset(&ts->rcvbuf);
|
||||||
Curl_dyn_reset(&ts->req);
|
Curl_dyn_reset(&ts->req);
|
||||||
ts->tunnel_state = TUNNEL_INIT;
|
ts->tunnel_state = H1_TUNNEL_INIT;
|
||||||
ts->keepon = KEEPON_CONNECT;
|
ts->keepon = KEEPON_CONNECT;
|
||||||
ts->cl = 0;
|
ts->cl = 0;
|
||||||
ts->close_connection = FALSE;
|
ts->close_connection = FALSE;
|
||||||
|
@ -124,12 +124,12 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts,
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode tunnel_init(struct tunnel_state **pts,
|
static CURLcode tunnel_init(struct h1_tunnel_state **pts,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct connectdata *conn,
|
struct connectdata *conn,
|
||||||
int sockindex)
|
int sockindex)
|
||||||
{
|
{
|
||||||
struct tunnel_state *ts;
|
struct h1_tunnel_state *ts;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
|
if(conn->handler->flags & PROTOPT_NOTCPPROXY) {
|
||||||
|
@ -157,16 +157,16 @@ static CURLcode tunnel_init(struct tunnel_state **pts,
|
||||||
return tunnel_reinit(ts, conn, data);
|
return tunnel_reinit(ts, conn, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tunnel_go_state(struct Curl_cfilter *cf,
|
static void h1_tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
tunnel_state new_state,
|
h1_tunnel_state new_state,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
if(ts->tunnel_state == new_state)
|
if(ts->tunnel_state == new_state)
|
||||||
return;
|
return;
|
||||||
/* leaving this one */
|
/* leaving this one */
|
||||||
switch(ts->tunnel_state) {
|
switch(ts->tunnel_state) {
|
||||||
case TUNNEL_CONNECT:
|
case H1_TUNNEL_CONNECT:
|
||||||
data->req.ignorebody = FALSE;
|
data->req.ignorebody = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -174,36 +174,36 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
/* entering this one */
|
/* entering this one */
|
||||||
switch(new_state) {
|
switch(new_state) {
|
||||||
case TUNNEL_INIT:
|
case H1_TUNNEL_INIT:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
|
||||||
tunnel_reinit(ts, cf->conn, data);
|
tunnel_reinit(ts, cf->conn, data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_CONNECT:
|
case H1_TUNNEL_CONNECT:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
|
||||||
ts->tunnel_state = TUNNEL_CONNECT;
|
ts->tunnel_state = H1_TUNNEL_CONNECT;
|
||||||
ts->keepon = KEEPON_CONNECT;
|
ts->keepon = KEEPON_CONNECT;
|
||||||
Curl_dyn_reset(&ts->rcvbuf);
|
Curl_dyn_reset(&ts->rcvbuf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_RECEIVE:
|
case H1_TUNNEL_RECEIVE:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'receive'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'receive'"));
|
||||||
ts->tunnel_state = TUNNEL_RECEIVE;
|
ts->tunnel_state = H1_TUNNEL_RECEIVE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_RESPONSE:
|
case H1_TUNNEL_RESPONSE:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
|
||||||
ts->tunnel_state = TUNNEL_RESPONSE;
|
ts->tunnel_state = H1_TUNNEL_RESPONSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_ESTABLISHED:
|
case H1_TUNNEL_ESTABLISHED:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
|
||||||
infof(data, "CONNECT phase completed");
|
infof(data, "CONNECT phase completed");
|
||||||
data->state.authproxy.done = TRUE;
|
data->state.authproxy.done = TRUE;
|
||||||
data->state.authproxy.multipass = FALSE;
|
data->state.authproxy.multipass = FALSE;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case TUNNEL_FAILED:
|
case H1_TUNNEL_FAILED:
|
||||||
if(new_state == TUNNEL_FAILED)
|
if(new_state == H1_TUNNEL_FAILED)
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
|
||||||
ts->tunnel_state = new_state;
|
ts->tunnel_state = new_state;
|
||||||
Curl_dyn_reset(&ts->rcvbuf);
|
Curl_dyn_reset(&ts->rcvbuf);
|
||||||
|
@ -225,9 +225,9 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
static void tunnel_free(struct Curl_cfilter *cf,
|
static void tunnel_free(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct tunnel_state *ts = cf->ctx;
|
struct h1_tunnel_state *ts = cf->ctx;
|
||||||
if(ts) {
|
if(ts) {
|
||||||
tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
|
||||||
Curl_dyn_free(&ts->rcvbuf);
|
Curl_dyn_free(&ts->rcvbuf);
|
||||||
Curl_dyn_free(&ts->req);
|
Curl_dyn_free(&ts->req);
|
||||||
free(ts);
|
free(ts);
|
||||||
|
@ -270,7 +270,7 @@ static CURLcode CONNECT_host(struct Curl_easy *data,
|
||||||
#ifndef USE_HYPER
|
#ifndef USE_HYPER
|
||||||
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts)
|
struct h1_tunnel_state *ts)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = cf->conn;
|
struct connectdata *conn = cf->conn;
|
||||||
char *hostheader = NULL;
|
char *hostheader = NULL;
|
||||||
|
@ -351,7 +351,7 @@ out:
|
||||||
|
|
||||||
static CURLcode send_CONNECT(struct Curl_easy *data,
|
static CURLcode send_CONNECT(struct Curl_easy *data,
|
||||||
struct connectdata *conn,
|
struct connectdata *conn,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
bool *done)
|
bool *done)
|
||||||
{
|
{
|
||||||
struct SingleRequest *k = &data->req;
|
struct SingleRequest *k = &data->req;
|
||||||
|
@ -399,7 +399,7 @@ out:
|
||||||
|
|
||||||
static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
const char *header)
|
const char *header)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
@ -475,7 +475,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
bool *done)
|
bool *done)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
@ -671,7 +671,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||||
/* The Hyper version of CONNECT */
|
/* The Hyper version of CONNECT */
|
||||||
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
static CURLcode start_CONNECT(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts)
|
struct h1_tunnel_state *ts)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = cf->conn;
|
struct connectdata *conn = cf->conn;
|
||||||
struct hyptransfer *h = &data->hyp;
|
struct hyptransfer *h = &data->hyp;
|
||||||
|
@ -882,7 +882,7 @@ error:
|
||||||
|
|
||||||
static CURLcode send_CONNECT(struct Curl_easy *data,
|
static CURLcode send_CONNECT(struct Curl_easy *data,
|
||||||
struct connectdata *conn,
|
struct connectdata *conn,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
bool *done)
|
bool *done)
|
||||||
{
|
{
|
||||||
struct hyptransfer *h = &data->hyp;
|
struct hyptransfer *h = &data->hyp;
|
||||||
|
@ -919,7 +919,7 @@ error:
|
||||||
|
|
||||||
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts,
|
struct h1_tunnel_state *ts,
|
||||||
bool *done)
|
bool *done)
|
||||||
{
|
{
|
||||||
struct hyptransfer *h = &data->hyp;
|
struct hyptransfer *h = &data->hyp;
|
||||||
|
@ -949,9 +949,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
#endif /* USE_HYPER */
|
#endif /* USE_HYPER */
|
||||||
|
|
||||||
static CURLcode CONNECT(struct Curl_cfilter *cf,
|
static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_state *ts)
|
struct h1_tunnel_state *ts)
|
||||||
{
|
{
|
||||||
struct connectdata *conn = cf->conn;
|
struct connectdata *conn = cf->conn;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
@ -973,25 +973,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(ts->tunnel_state) {
|
switch(ts->tunnel_state) {
|
||||||
case TUNNEL_INIT:
|
case H1_TUNNEL_INIT:
|
||||||
/* Prepare the CONNECT request and make a first attempt to send. */
|
/* Prepare the CONNECT request and make a first attempt to send. */
|
||||||
DEBUGF(LOG_CF(data, cf, "CONNECT start"));
|
DEBUGF(LOG_CF(data, cf, "CONNECT start"));
|
||||||
result = start_CONNECT(cf, data, ts);
|
result = start_CONNECT(cf, data, ts);
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case TUNNEL_CONNECT:
|
case H1_TUNNEL_CONNECT:
|
||||||
/* see that the request is completely sent */
|
/* see that the request is completely sent */
|
||||||
DEBUGF(LOG_CF(data, cf, "CONNECT send"));
|
DEBUGF(LOG_CF(data, cf, "CONNECT send"));
|
||||||
result = send_CONNECT(data, cf->conn, ts, &done);
|
result = send_CONNECT(data, cf->conn, ts, &done);
|
||||||
if(result || !done)
|
if(result || !done)
|
||||||
goto out;
|
goto out;
|
||||||
tunnel_go_state(cf, ts, TUNNEL_RECEIVE, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case TUNNEL_RECEIVE:
|
case H1_TUNNEL_RECEIVE:
|
||||||
/* read what is there */
|
/* read what is there */
|
||||||
DEBUGF(LOG_CF(data, cf, "CONNECT receive"));
|
DEBUGF(LOG_CF(data, cf, "CONNECT receive"));
|
||||||
result = recv_CONNECT_resp(cf, data, ts, &done);
|
result = recv_CONNECT_resp(cf, data, ts, &done);
|
||||||
|
@ -1003,10 +1003,10 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
if(result || !done)
|
if(result || !done)
|
||||||
goto out;
|
goto out;
|
||||||
/* got it */
|
/* got it */
|
||||||
tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case TUNNEL_RESPONSE:
|
case H1_TUNNEL_RESPONSE:
|
||||||
DEBUGF(LOG_CF(data, cf, "CONNECT response"));
|
DEBUGF(LOG_CF(data, cf, "CONNECT response"));
|
||||||
if(data->req.newurl) {
|
if(data->req.newurl) {
|
||||||
/* not the "final" response, we need to do a follow up request.
|
/* not the "final" response, we need to do a follow up request.
|
||||||
|
@ -1028,7 +1028,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* staying on this connection, reset state */
|
/* staying on this connection, reset state */
|
||||||
tunnel_go_state(cf, ts, TUNNEL_INIT, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1039,25 +1039,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
} while(data->req.newurl);
|
} while(data->req.newurl);
|
||||||
|
|
||||||
DEBUGASSERT(ts->tunnel_state == TUNNEL_RESPONSE);
|
DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE);
|
||||||
if(data->info.httpproxycode/100 != 2) {
|
if(data->info.httpproxycode/100 != 2) {
|
||||||
/* a non-2xx response and we have no next url to try. */
|
/* a non-2xx response and we have no next url to try. */
|
||||||
Curl_safefree(data->req.newurl);
|
Curl_safefree(data->req.newurl);
|
||||||
/* failure, close this connection to avoid re-use */
|
/* failure, close this connection to avoid re-use */
|
||||||
streamclose(conn, "proxy CONNECT failure");
|
streamclose(conn, "proxy CONNECT failure");
|
||||||
tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
|
||||||
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
|
failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode);
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
}
|
}
|
||||||
/* 2xx response, SUCCESS! */
|
/* 2xx response, SUCCESS! */
|
||||||
tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data);
|
||||||
infof(data, "CONNECT tunnel established, response %d",
|
infof(data, "CONNECT tunnel established, response %d",
|
||||||
data->info.httpproxycode);
|
data->info.httpproxycode);
|
||||||
result = CURLE_OK;
|
result = CURLE_OK;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if(result)
|
if(result)
|
||||||
tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
|
h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,7 +1066,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
|
||||||
bool blocking, bool *done)
|
bool blocking, bool *done)
|
||||||
{
|
{
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct tunnel_state *ts = cf->ctx;
|
struct h1_tunnel_state *ts = cf->ctx;
|
||||||
|
|
||||||
if(cf->connected) {
|
if(cf->connected) {
|
||||||
*done = TRUE;
|
*done = TRUE;
|
||||||
|
@ -1089,7 +1089,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf,
|
||||||
/* TODO: can we do blocking? */
|
/* TODO: can we do blocking? */
|
||||||
/* We want "seamless" operations through HTTP proxy tunnel */
|
/* We want "seamless" operations through HTTP proxy tunnel */
|
||||||
|
|
||||||
result = CONNECT(cf, data, ts);
|
result = H1_CONNECT(cf, data, ts);
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
Curl_safefree(data->state.aptr.proxyuserpwd);
|
Curl_safefree(data->state.aptr.proxyuserpwd);
|
||||||
|
@ -1107,7 +1107,7 @@ static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
curl_socket_t *socks)
|
curl_socket_t *socks)
|
||||||
{
|
{
|
||||||
struct tunnel_state *ts = cf->ctx;
|
struct h1_tunnel_state *ts = cf->ctx;
|
||||||
int fds;
|
int fds;
|
||||||
|
|
||||||
fds = cf->next->cft->get_select_socks(cf->next, data, socks);
|
fds = cf->next->cft->get_select_socks(cf->next, data, socks);
|
||||||
|
@ -1143,7 +1143,7 @@ static void cf_h1_proxy_close(struct Curl_cfilter *cf,
|
||||||
DEBUGF(LOG_CF(data, cf, "close"));
|
DEBUGF(LOG_CF(data, cf, "close"));
|
||||||
cf->connected = FALSE;
|
cf->connected = FALSE;
|
||||||
if(cf->ctx) {
|
if(cf->ctx) {
|
||||||
tunnel_go_state(cf, cf->ctx, TUNNEL_INIT, data);
|
h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data);
|
||||||
}
|
}
|
||||||
if(cf->next)
|
if(cf->next)
|
||||||
cf->next->cft->close(cf->next, data);
|
cf->next->cft->close(cf->next, data);
|
||||||
|
|
|
@ -45,10 +45,10 @@
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define H2_NW_CHUNK_SIZE (128*1024)
|
#define H2_NW_CHUNK_SIZE (128*1024)
|
||||||
#define H2_NW_RECV_CHUNKS 1
|
#define PROXY_H2_NW_RECV_CHUNKS 1
|
||||||
#define H2_NW_SEND_CHUNKS 1
|
#define PROXY_H2_NW_SEND_CHUNKS 1
|
||||||
|
|
||||||
#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
|
#define PROXY_HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */
|
||||||
|
|
||||||
#define H2_TUNNEL_WINDOW_SIZE (1024 * 1024)
|
#define H2_TUNNEL_WINDOW_SIZE (1024 * 1024)
|
||||||
#define H2_TUNNEL_CHUNK_SIZE (32 * 1024)
|
#define H2_TUNNEL_CHUNK_SIZE (32 * 1024)
|
||||||
|
@ -58,12 +58,12 @@
|
||||||
(H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
|
(H2_TUNNEL_WINDOW_SIZE / H2_TUNNEL_CHUNK_SIZE)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TUNNEL_INIT, /* init/default/no tunnel state */
|
H2_TUNNEL_INIT, /* init/default/no tunnel state */
|
||||||
TUNNEL_CONNECT, /* CONNECT request is being send */
|
H2_TUNNEL_CONNECT, /* CONNECT request is being send */
|
||||||
TUNNEL_RESPONSE, /* CONNECT response received completely */
|
H2_TUNNEL_RESPONSE, /* CONNECT response received completely */
|
||||||
TUNNEL_ESTABLISHED,
|
H2_TUNNEL_ESTABLISHED,
|
||||||
TUNNEL_FAILED
|
H2_TUNNEL_FAILED
|
||||||
} tunnel_state;
|
} h2_tunnel_state;
|
||||||
|
|
||||||
struct tunnel_stream {
|
struct tunnel_stream {
|
||||||
struct http_resp *resp;
|
struct http_resp *resp;
|
||||||
|
@ -72,7 +72,7 @@ struct tunnel_stream {
|
||||||
char *authority;
|
char *authority;
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
uint32_t error;
|
uint32_t error;
|
||||||
tunnel_state state;
|
h2_tunnel_state state;
|
||||||
bool has_final_response;
|
bool has_final_response;
|
||||||
bool closed;
|
bool closed;
|
||||||
bool reset;
|
bool reset;
|
||||||
|
@ -85,7 +85,7 @@ static CURLcode tunnel_stream_init(struct Curl_cfilter *cf,
|
||||||
int port;
|
int port;
|
||||||
bool ipv6_ip = cf->conn->bits.ipv6_ip;
|
bool ipv6_ip = cf->conn->bits.ipv6_ip;
|
||||||
|
|
||||||
ts->state = TUNNEL_INIT;
|
ts->state = H2_TUNNEL_INIT;
|
||||||
ts->stream_id = -1;
|
ts->stream_id = -1;
|
||||||
Curl_bufq_init2(&ts->recvbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
|
Curl_bufq_init2(&ts->recvbuf, H2_TUNNEL_CHUNK_SIZE, H2_TUNNEL_RECV_CHUNKS,
|
||||||
BUFQ_OPT_SOFT_LIMIT);
|
BUFQ_OPT_SOFT_LIMIT);
|
||||||
|
@ -123,12 +123,12 @@ static void tunnel_stream_clear(struct tunnel_stream *ts)
|
||||||
Curl_bufq_free(&ts->sendbuf);
|
Curl_bufq_free(&ts->sendbuf);
|
||||||
Curl_safefree(ts->authority);
|
Curl_safefree(ts->authority);
|
||||||
memset(ts, 0, sizeof(*ts));
|
memset(ts, 0, sizeof(*ts));
|
||||||
ts->state = TUNNEL_INIT;
|
ts->state = H2_TUNNEL_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tunnel_go_state(struct Curl_cfilter *cf,
|
static void h2_tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
struct tunnel_stream *ts,
|
struct tunnel_stream *ts,
|
||||||
tunnel_state new_state,
|
h2_tunnel_state new_state,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
(void)cf;
|
(void)cf;
|
||||||
|
@ -137,7 +137,7 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
return;
|
return;
|
||||||
/* leaving this one */
|
/* leaving this one */
|
||||||
switch(ts->state) {
|
switch(ts->state) {
|
||||||
case TUNNEL_CONNECT:
|
case H2_TUNNEL_CONNECT:
|
||||||
data->req.ignorebody = FALSE;
|
data->req.ignorebody = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -145,29 +145,29 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
/* entering this one */
|
/* entering this one */
|
||||||
switch(new_state) {
|
switch(new_state) {
|
||||||
case TUNNEL_INIT:
|
case H2_TUNNEL_INIT:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'"));
|
||||||
tunnel_stream_clear(ts);
|
tunnel_stream_clear(ts);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_CONNECT:
|
case H2_TUNNEL_CONNECT:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'"));
|
||||||
ts->state = TUNNEL_CONNECT;
|
ts->state = H2_TUNNEL_CONNECT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_RESPONSE:
|
case H2_TUNNEL_RESPONSE:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'"));
|
||||||
ts->state = TUNNEL_RESPONSE;
|
ts->state = H2_TUNNEL_RESPONSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_ESTABLISHED:
|
case H2_TUNNEL_ESTABLISHED:
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'"));
|
||||||
infof(data, "CONNECT phase completed");
|
infof(data, "CONNECT phase completed");
|
||||||
data->state.authproxy.done = TRUE;
|
data->state.authproxy.done = TRUE;
|
||||||
data->state.authproxy.multipass = FALSE;
|
data->state.authproxy.multipass = FALSE;
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case TUNNEL_FAILED:
|
case H2_TUNNEL_FAILED:
|
||||||
if(new_state == TUNNEL_FAILED)
|
if(new_state == H2_TUNNEL_FAILED)
|
||||||
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
|
DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'"));
|
||||||
ts->state = new_state;
|
ts->state = new_state;
|
||||||
/* If a proxy-authorization header was used for the proxy, then we should
|
/* If a proxy-authorization header was used for the proxy, then we should
|
||||||
|
@ -194,6 +194,7 @@ struct cf_h2_proxy_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How to access `call_data` from a cf_h2 filter */
|
/* How to access `call_data` from a cf_h2 filter */
|
||||||
|
#undef CF_CTX_CALL_DATA
|
||||||
#define CF_CTX_CALL_DATA(cf) \
|
#define CF_CTX_CALL_DATA(cf) \
|
||||||
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
((struct cf_h2_proxy_ctx *)(cf)->ctx)->call_data
|
||||||
|
|
||||||
|
@ -219,7 +220,7 @@ static void cf_h2_proxy_ctx_free(struct cf_h2_proxy_ctx *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t nw_in_reader(void *reader_ctx,
|
static ssize_t proxy_nw_in_reader(void *reader_ctx,
|
||||||
unsigned char *buf, size_t buflen,
|
unsigned char *buf, size_t buflen,
|
||||||
CURLcode *err)
|
CURLcode *err)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +234,7 @@ static ssize_t nw_in_reader(void *reader_ctx,
|
||||||
return nread;
|
return nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t nw_out_writer(void *writer_ctx,
|
static ssize_t proxy_h2_nw_out_writer(void *writer_ctx,
|
||||||
const unsigned char *buf, size_t buflen,
|
const unsigned char *buf, size_t buflen,
|
||||||
CURLcode *err)
|
CURLcode *err)
|
||||||
{
|
{
|
||||||
|
@ -246,7 +247,7 @@ static ssize_t nw_out_writer(void *writer_ctx,
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int h2_client_new(struct Curl_cfilter *cf,
|
static int proxy_h2_client_new(struct Curl_cfilter *cf,
|
||||||
nghttp2_session_callbacks *cbs)
|
nghttp2_session_callbacks *cbs)
|
||||||
{
|
{
|
||||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||||
|
@ -271,11 +272,14 @@ static int h2_client_new(struct Curl_cfilter *cf,
|
||||||
static ssize_t on_session_send(nghttp2_session *h2,
|
static ssize_t on_session_send(nghttp2_session *h2,
|
||||||
const uint8_t *buf, size_t blen,
|
const uint8_t *buf, size_t blen,
|
||||||
int flags, void *userp);
|
int flags, void *userp);
|
||||||
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
static int proxy_h2_on_frame_recv(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame,
|
||||||
void *userp);
|
void *userp);
|
||||||
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
static int proxy_h2_on_stream_close(nghttp2_session *session,
|
||||||
|
int32_t stream_id,
|
||||||
uint32_t error_code, void *userp);
|
uint32_t error_code, void *userp);
|
||||||
static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
static int proxy_h2_on_header(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame,
|
||||||
const uint8_t *name, size_t namelen,
|
const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen,
|
const uint8_t *value, size_t valuelen,
|
||||||
uint8_t flags,
|
uint8_t flags,
|
||||||
|
@ -298,8 +302,8 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||||
DEBUGASSERT(!ctx->h2);
|
DEBUGASSERT(!ctx->h2);
|
||||||
memset(&ctx->tunnel, 0, sizeof(ctx->tunnel));
|
memset(&ctx->tunnel, 0, sizeof(ctx->tunnel));
|
||||||
|
|
||||||
Curl_bufq_init(&ctx->inbufq, H2_NW_CHUNK_SIZE, H2_NW_RECV_CHUNKS);
|
Curl_bufq_init(&ctx->inbufq, H2_NW_CHUNK_SIZE, PROXY_H2_NW_RECV_CHUNKS);
|
||||||
Curl_bufq_init(&ctx->outbufq, H2_NW_CHUNK_SIZE, H2_NW_SEND_CHUNKS);
|
Curl_bufq_init(&ctx->outbufq, H2_NW_CHUNK_SIZE, PROXY_H2_NW_SEND_CHUNKS);
|
||||||
|
|
||||||
if(tunnel_stream_init(cf, &ctx->tunnel))
|
if(tunnel_stream_init(cf, &ctx->tunnel))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -311,14 +315,16 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_send_callback(cbs, on_session_send);
|
nghttp2_session_callbacks_set_send_callback(cbs, on_session_send);
|
||||||
nghttp2_session_callbacks_set_on_frame_recv_callback(cbs, on_frame_recv);
|
nghttp2_session_callbacks_set_on_frame_recv_callback(
|
||||||
|
cbs, proxy_h2_on_frame_recv);
|
||||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
|
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
|
||||||
cbs, tunnel_recv_callback);
|
cbs, tunnel_recv_callback);
|
||||||
nghttp2_session_callbacks_set_on_stream_close_callback(cbs, on_stream_close);
|
nghttp2_session_callbacks_set_on_stream_close_callback(
|
||||||
nghttp2_session_callbacks_set_on_header_callback(cbs, on_header);
|
cbs, proxy_h2_on_stream_close);
|
||||||
|
nghttp2_session_callbacks_set_on_header_callback(cbs, proxy_h2_on_header);
|
||||||
|
|
||||||
/* The nghttp2 session is not yet setup, do it */
|
/* The nghttp2 session is not yet setup, do it */
|
||||||
rc = h2_client_new(cf, cbs);
|
rc = proxy_h2_client_new(cf, cbs);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
failf(data, "Couldn't initialize nghttp2");
|
failf(data, "Couldn't initialize nghttp2");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -343,7 +349,7 @@ static CURLcode cf_h2_proxy_ctx_init(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0,
|
rc = nghttp2_session_set_local_window_size(ctx->h2, NGHTTP2_FLAG_NONE, 0,
|
||||||
HTTP2_HUGE_WINDOW_SIZE);
|
PROXY_HTTP2_HUGE_WINDOW_SIZE);
|
||||||
if(rc) {
|
if(rc) {
|
||||||
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
|
failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
|
||||||
nghttp2_strerror(rc), rc);
|
nghttp2_strerror(rc), rc);
|
||||||
|
@ -362,7 +368,7 @@ out:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode nw_out_flush(struct Curl_cfilter *cf,
|
static CURLcode proxy_h2_nw_out_flush(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||||
|
@ -375,7 +381,8 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes", buflen));
|
DEBUGF(LOG_CF(data, cf, "h2 conn flush %zu bytes", buflen));
|
||||||
nwritten = Curl_bufq_pass(&ctx->outbufq, nw_out_writer, cf, &result);
|
nwritten = Curl_bufq_pass(&ctx->outbufq, proxy_h2_nw_out_writer, cf,
|
||||||
|
&result);
|
||||||
if(nwritten < 0) {
|
if(nwritten < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -390,7 +397,7 @@ static CURLcode nw_out_flush(struct Curl_cfilter *cf,
|
||||||
* This function returns 0 if it succeeds, or -1 and error code will
|
* This function returns 0 if it succeeds, or -1 and error code will
|
||||||
* be assigned to *err.
|
* be assigned to *err.
|
||||||
*/
|
*/
|
||||||
static int h2_process_pending_input(struct Curl_cfilter *cf,
|
static int proxy_h2_process_pending_input(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
CURLcode *err)
|
CURLcode *err)
|
||||||
{
|
{
|
||||||
|
@ -433,7 +440,7 @@ static int h2_process_pending_input(struct Curl_cfilter *cf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
static CURLcode proxy_h2_progress_ingress(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||||
|
@ -444,7 +451,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
||||||
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
|
if(!Curl_bufq_is_empty(&ctx->inbufq)) {
|
||||||
DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
|
DEBUGF(LOG_CF(data, cf, "Process %zd bytes in connection buffer",
|
||||||
Curl_bufq_len(&ctx->inbufq)));
|
Curl_bufq_len(&ctx->inbufq)));
|
||||||
if(h2_process_pending_input(cf, data, &result) < 0)
|
if(proxy_h2_process_pending_input(cf, data, &result) < 0)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +462,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
||||||
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
|
Curl_bufq_is_empty(&ctx->inbufq) && /* and we consumed our input */
|
||||||
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
|
!Curl_bufq_is_full(&ctx->tunnel.recvbuf)) {
|
||||||
|
|
||||||
nread = Curl_bufq_slurp(&ctx->inbufq, nw_in_reader, cf, &result);
|
nread = Curl_bufq_slurp(&ctx->inbufq, proxy_nw_in_reader, cf, &result);
|
||||||
DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
|
DEBUGF(LOG_CF(data, cf, "read %zd bytes nw data -> %zd, %d",
|
||||||
Curl_bufq_len(&ctx->inbufq), nread, result));
|
Curl_bufq_len(&ctx->inbufq), nread, result));
|
||||||
if(nread < 0) {
|
if(nread < 0) {
|
||||||
|
@ -470,7 +477,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(h2_process_pending_input(cf, data, &result))
|
if(proxy_h2_process_pending_input(cf, data, &result))
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +494,7 @@ static CURLcode h2_progress_ingress(struct Curl_cfilter *cf,
|
||||||
* info.
|
* info.
|
||||||
* Flush any out data pending in the network buffer.
|
* Flush any out data pending in the network buffer.
|
||||||
*/
|
*/
|
||||||
static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
|
static CURLcode proxy_h2_progress_egress(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||||
|
@ -499,7 +506,7 @@ static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
|
||||||
nghttp2_strerror(rv), rv));
|
nghttp2_strerror(rv), rv));
|
||||||
return CURLE_SEND_ERROR;
|
return CURLE_SEND_ERROR;
|
||||||
}
|
}
|
||||||
return nw_out_flush(cf, data);
|
return proxy_h2_nw_out_flush(cf, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t on_session_send(nghttp2_session *h2,
|
static ssize_t on_session_send(nghttp2_session *h2,
|
||||||
|
@ -517,7 +524,7 @@ static ssize_t on_session_send(nghttp2_session *h2,
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
|
|
||||||
nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
|
nwritten = Curl_bufq_write_pass(&ctx->outbufq, buf, blen,
|
||||||
nw_out_writer, cf, &result);
|
proxy_h2_nw_out_writer, cf, &result);
|
||||||
if(nwritten < 0) {
|
if(nwritten < 0) {
|
||||||
if(result == CURLE_AGAIN) {
|
if(result == CURLE_AGAIN) {
|
||||||
return NGHTTP2_ERR_WOULDBLOCK;
|
return NGHTTP2_ERR_WOULDBLOCK;
|
||||||
|
@ -532,7 +539,8 @@ static ssize_t on_session_send(nghttp2_session *h2,
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
static int proxy_h2_on_frame_recv(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame,
|
||||||
void *userp)
|
void *userp)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = userp;
|
struct Curl_cfilter *cf = userp;
|
||||||
|
@ -616,7 +624,8 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
static int proxy_h2_on_header(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame,
|
||||||
const uint8_t *name, size_t namelen,
|
const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen,
|
const uint8_t *value, size_t valuelen,
|
||||||
uint8_t flags,
|
uint8_t flags,
|
||||||
|
@ -752,7 +761,8 @@ static int tunnel_recv_callback(nghttp2_session *session, uint8_t flags,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
static int proxy_h2_on_stream_close(nghttp2_session *session,
|
||||||
|
int32_t stream_id,
|
||||||
uint32_t error_code, void *userp)
|
uint32_t error_code, void *userp)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = userp;
|
struct Curl_cfilter *cf = userp;
|
||||||
|
@ -765,7 +775,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||||
if(stream_id != ctx->tunnel.stream_id)
|
if(stream_id != ctx->tunnel.stream_id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] on_stream_close, %s (err %d)",
|
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] proxy_h2_on_stream_close, %s (err %d)",
|
||||||
stream_id, nghttp2_http2_strerror(error_code), error_code));
|
stream_id, nghttp2_http2_strerror(error_code), error_code));
|
||||||
ctx->tunnel.closed = TRUE;
|
ctx->tunnel.closed = TRUE;
|
||||||
ctx->tunnel.error = error_code;
|
ctx->tunnel.error = error_code;
|
||||||
|
@ -773,7 +783,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode h2_submit(int32_t *pstream_id,
|
static CURLcode proxy_h2_submit(int32_t *pstream_id,
|
||||||
struct Curl_cfilter *cf,
|
struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
nghttp2_session *h2,
|
nghttp2_session *h2,
|
||||||
|
@ -881,7 +891,7 @@ static CURLcode submit_CONNECT(struct Curl_cfilter *cf,
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
result = h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
|
result = proxy_h2_submit(&ts->stream_id, cf, data, ctx->h2, req,
|
||||||
NULL, ts, tunnel_send_callback, cf);
|
NULL, ts, tunnel_send_callback, cf);
|
||||||
if(result) {
|
if(result) {
|
||||||
DEBUGF(LOG_CF(data, cf, "send: nghttp2_submit_request error (%s)%u",
|
DEBUGF(LOG_CF(data, cf, "send: nghttp2_submit_request error (%s)%u",
|
||||||
|
@ -907,7 +917,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
|
||||||
DEBUGASSERT(ts->resp);
|
DEBUGASSERT(ts->resp);
|
||||||
if(ts->resp->status/100 == 2) {
|
if(ts->resp->status/100 == 2) {
|
||||||
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
|
infof(data, "CONNECT tunnel established, response %d", ts->resp->status);
|
||||||
tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_ESTABLISHED, data);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,7 +938,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
|
||||||
if(data->req.newurl) {
|
if(data->req.newurl) {
|
||||||
/* Inidicator that we should try again */
|
/* Inidicator that we should try again */
|
||||||
Curl_safefree(data->req.newurl);
|
Curl_safefree(data->req.newurl);
|
||||||
tunnel_go_state(cf, ts, TUNNEL_INIT, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_INIT, data);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -937,7 +947,7 @@ static CURLcode inspect_response(struct Curl_cfilter *cf,
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode CONNECT(struct Curl_cfilter *cf,
|
static CURLcode H2_CONNECT(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct tunnel_stream *ts)
|
struct tunnel_stream *ts)
|
||||||
{
|
{
|
||||||
|
@ -948,27 +958,27 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
DEBUGASSERT(ts->authority);
|
DEBUGASSERT(ts->authority);
|
||||||
do {
|
do {
|
||||||
switch(ts->state) {
|
switch(ts->state) {
|
||||||
case TUNNEL_INIT:
|
case H2_TUNNEL_INIT:
|
||||||
/* Prepare the CONNECT request and make a first attempt to send. */
|
/* Prepare the CONNECT request and make a first attempt to send. */
|
||||||
DEBUGF(LOG_CF(data, cf, "CONNECT start for %s", ts->authority));
|
DEBUGF(LOG_CF(data, cf, "CONNECT start for %s", ts->authority));
|
||||||
result = submit_CONNECT(cf, data, ts);
|
result = submit_CONNECT(cf, data, ts);
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
tunnel_go_state(cf, ts, TUNNEL_CONNECT, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_CONNECT, data);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case TUNNEL_CONNECT:
|
case H2_TUNNEL_CONNECT:
|
||||||
/* see that the request is completely sent */
|
/* see that the request is completely sent */
|
||||||
result = h2_progress_ingress(cf, data);
|
result = proxy_h2_progress_ingress(cf, data);
|
||||||
if(!result)
|
if(!result)
|
||||||
result = h2_progress_egress(cf, data);
|
result = proxy_h2_progress_egress(cf, data);
|
||||||
if(result) {
|
if(result) {
|
||||||
tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ts->has_final_response) {
|
if(ts->has_final_response) {
|
||||||
tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_RESPONSE, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = CURLE_OK;
|
result = CURLE_OK;
|
||||||
|
@ -976,28 +986,28 @@ static CURLcode CONNECT(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
case TUNNEL_RESPONSE:
|
case H2_TUNNEL_RESPONSE:
|
||||||
DEBUGASSERT(ts->has_final_response);
|
DEBUGASSERT(ts->has_final_response);
|
||||||
result = inspect_response(cf, data, ts);
|
result = inspect_response(cf, data, ts);
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUNNEL_ESTABLISHED:
|
case H2_TUNNEL_ESTABLISHED:
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
case TUNNEL_FAILED:
|
case H2_TUNNEL_FAILED:
|
||||||
return CURLE_RECV_ERROR;
|
return CURLE_RECV_ERROR;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while(ts->state == TUNNEL_INIT);
|
} while(ts->state == H2_TUNNEL_INIT);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if(result || ctx->tunnel.closed)
|
if(result || ctx->tunnel.closed)
|
||||||
tunnel_go_state(cf, ts, TUNNEL_FAILED, data);
|
h2_tunnel_go_state(cf, ts, H2_TUNNEL_FAILED, data);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,10 +1053,10 @@ static CURLcode cf_h2_proxy_connect(struct Curl_cfilter *cf,
|
||||||
/* for the secondary socket (FTP), use the "connect to host"
|
/* for the secondary socket (FTP), use the "connect to host"
|
||||||
* but ignore the "connect to port" (use the secondary port)
|
* but ignore the "connect to port" (use the secondary port)
|
||||||
*/
|
*/
|
||||||
result = CONNECT(cf, data, ts);
|
result = H2_CONNECT(cf, data, ts);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
*done = (result == CURLE_OK) && (ts->state == TUNNEL_ESTABLISHED);
|
*done = (result == CURLE_OK) && (ts->state == H2_TUNNEL_ESTABLISHED);
|
||||||
cf->connected = *done;
|
cf->connected = *done;
|
||||||
CF_DATA_RESTORE(cf, save);
|
CF_DATA_RESTORE(cf, save);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1082,7 +1092,7 @@ static bool cf_h2_proxy_data_pending(struct Curl_cfilter *cf,
|
||||||
{
|
{
|
||||||
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
struct cf_h2_proxy_ctx *ctx = cf->ctx;
|
||||||
if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) ||
|
if((ctx && !Curl_bufq_is_empty(&ctx->inbufq)) ||
|
||||||
(ctx && ctx->tunnel.state == TUNNEL_ESTABLISHED &&
|
(ctx && ctx->tunnel.state == H2_TUNNEL_ESTABLISHED &&
|
||||||
!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
|
!Curl_bufq_is_empty(&ctx->tunnel.recvbuf)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
|
return cf->next? cf->next->cft->has_data_pending(cf->next, data) : FALSE;
|
||||||
|
@ -1188,14 +1198,14 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
|
||||||
struct cf_call_data save;
|
struct cf_call_data save;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
|
if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
|
||||||
*err = CURLE_RECV_ERROR;
|
*err = CURLE_RECV_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CF_DATA_SAVE(save, cf, data);
|
CF_DATA_SAVE(save, cf, data);
|
||||||
|
|
||||||
if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
|
if(Curl_bufq_is_empty(&ctx->tunnel.recvbuf)) {
|
||||||
*err = h2_progress_ingress(cf, data);
|
*err = proxy_h2_progress_ingress(cf, data);
|
||||||
if(*err)
|
if(*err)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -1208,7 +1218,7 @@ static ssize_t cf_h2_proxy_recv(struct Curl_cfilter *cf,
|
||||||
nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread);
|
nghttp2_session_consume(ctx->h2, ctx->tunnel.stream_id, (size_t)nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = h2_progress_egress(cf, data);
|
result = proxy_h2_progress_egress(cf, data);
|
||||||
if(result) {
|
if(result) {
|
||||||
*err = result;
|
*err = result;
|
||||||
nread = -1;
|
nread = -1;
|
||||||
|
@ -1232,7 +1242,7 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf,
|
||||||
size_t start_len = len;
|
size_t start_len = len;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if(ctx->tunnel.state != TUNNEL_ESTABLISHED) {
|
if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) {
|
||||||
*err = CURLE_SEND_ERROR;
|
*err = CURLE_SEND_ERROR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1264,7 +1274,7 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf,
|
||||||
nwritten = -1;
|
nwritten = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
*err = h2_progress_egress(cf, data);
|
*err = proxy_h2_progress_egress(cf, data);
|
||||||
if(*err) {
|
if(*err) {
|
||||||
nwritten = -1;
|
nwritten = -1;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -376,7 +376,7 @@ static bool cf_hc_data_pending(struct Curl_cfilter *cf,
|
||||||
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
|
|| cf_hc_baller_data_pending(&ctx->h21_baller, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct curltime get_max_baller_time(struct Curl_cfilter *cf,
|
static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
int query)
|
int query)
|
||||||
{
|
{
|
||||||
|
@ -408,12 +408,12 @@ static CURLcode cf_hc_query(struct Curl_cfilter *cf,
|
||||||
switch(query) {
|
switch(query) {
|
||||||
case CF_QUERY_TIMER_CONNECT: {
|
case CF_QUERY_TIMER_CONNECT: {
|
||||||
struct curltime *when = pres2;
|
struct curltime *when = pres2;
|
||||||
*when = get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
|
*when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
case CF_QUERY_TIMER_APPCONNECT: {
|
case CF_QUERY_TIMER_APPCONNECT: {
|
||||||
struct curltime *when = pres2;
|
struct curltime *when = pres2;
|
||||||
*when = get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
|
*when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -123,7 +123,8 @@ static void freecookie(struct Cookie *co)
|
||||||
free(co);
|
free(co);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tailmatch(const char *cookie_domain, size_t cookie_domain_len,
|
static bool cookie_tailmatch(const char *cookie_domain,
|
||||||
|
size_t cookie_domain_len,
|
||||||
const char *hostname)
|
const char *hostname)
|
||||||
{
|
{
|
||||||
size_t hostname_len = strlen(hostname);
|
size_t hostname_len = strlen(hostname);
|
||||||
|
@ -696,7 +697,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||||
if(!domain
|
if(!domain
|
||||||
|| (is_ip && !strncmp(valuep, domain, vlen) &&
|
|| (is_ip && !strncmp(valuep, domain, vlen) &&
|
||||||
(vlen == strlen(domain)))
|
(vlen == strlen(domain)))
|
||||||
|| (!is_ip && tailmatch(valuep, vlen, domain))) {
|
|| (!is_ip && cookie_tailmatch(valuep, vlen, domain))) {
|
||||||
strstore(&co->domain, valuep, vlen);
|
strstore(&co->domain, valuep, vlen);
|
||||||
if(!co->domain) {
|
if(!co->domain) {
|
||||||
badcookie = TRUE;
|
badcookie = TRUE;
|
||||||
|
@ -1431,7 +1432,7 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
|
||||||
/* now check if the domain is correct */
|
/* now check if the domain is correct */
|
||||||
if(!co->domain ||
|
if(!co->domain ||
|
||||||
(co->tailmatch && !is_ip &&
|
(co->tailmatch && !is_ip &&
|
||||||
tailmatch(co->domain, strlen(co->domain), host)) ||
|
cookie_tailmatch(co->domain, strlen(co->domain), host)) ||
|
||||||
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
|
((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
|
||||||
/*
|
/*
|
||||||
* the right part of the host matches the domain stuff in the
|
* the right part of the host matches the domain stuff in the
|
||||||
|
|
|
@ -55,9 +55,65 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HEADER_CURL_MEMDEBUG_H
|
#ifdef HEADER_CURL_MEMDEBUG_H
|
||||||
#error "Header memdebug.h shall not be included before curl_memory.h"
|
/* cleanup after memdebug.h */
|
||||||
|
|
||||||
|
#ifdef MEMDEBUG_NODEFINES
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
|
||||||
|
#undef strdup
|
||||||
|
#undef malloc
|
||||||
|
#undef calloc
|
||||||
|
#undef realloc
|
||||||
|
#undef free
|
||||||
|
#undef send
|
||||||
|
#undef recv
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# ifdef UNICODE
|
||||||
|
# undef wcsdup
|
||||||
|
# undef _wcsdup
|
||||||
|
# undef _tcsdup
|
||||||
|
# else
|
||||||
|
# undef _tcsdup
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef socket
|
||||||
|
#undef accept
|
||||||
|
#ifdef HAVE_SOCKETPAIR
|
||||||
|
#undef socketpair
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETADDRINFO
|
||||||
|
#if defined(getaddrinfo) && defined(__osf__)
|
||||||
|
#undef ogetaddrinfo
|
||||||
|
#else
|
||||||
|
#undef getaddrinfo
|
||||||
|
#endif
|
||||||
|
#endif /* HAVE_GETADDRINFO */
|
||||||
|
|
||||||
|
#ifdef HAVE_FREEADDRINFO
|
||||||
|
#undef freeaddrinfo
|
||||||
|
#endif /* HAVE_FREEADDRINFO */
|
||||||
|
|
||||||
|
/* sclose is probably already defined, redefine it! */
|
||||||
|
#undef sclose
|
||||||
|
#undef fopen
|
||||||
|
#undef fdopen
|
||||||
|
#undef fclose
|
||||||
|
|
||||||
|
#endif /* MEMDEBUG_NODEFINES */
|
||||||
|
#endif /* CURLDEBUG */
|
||||||
|
|
||||||
|
#undef HEADER_CURL_MEMDEBUG_H
|
||||||
|
#endif /* HEADER_CURL_MEMDEBUG_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Following section applies even when CURLDEBUG is not defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef fake_sclose
|
||||||
|
|
||||||
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
|
#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
|
||||||
/*
|
/*
|
||||||
* The following memory function replacement typedef's are COPIED from
|
* The following memory function replacement typedef's are COPIED from
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
# undef vprintf
|
# undef vprintf
|
||||||
# undef vfprintf
|
# undef vfprintf
|
||||||
# undef vsnprintf
|
# undef vsnprintf
|
||||||
|
# undef mvsnprintf
|
||||||
# undef aprintf
|
# undef aprintf
|
||||||
# undef vaprintf
|
# undef vaprintf
|
||||||
# define printf curl_mprintf
|
# define printf curl_mprintf
|
||||||
|
|
|
@ -221,11 +221,11 @@ void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* state()
|
* sasl_state()
|
||||||
*
|
*
|
||||||
* This is the ONLY way to change SASL state!
|
* This is the ONLY way to change SASL state!
|
||||||
*/
|
*/
|
||||||
static void state(struct SASL *sasl, struct Curl_easy *data,
|
static void sasl_state(struct SASL *sasl, struct Curl_easy *data,
|
||||||
saslstate newstate)
|
saslstate newstate)
|
||||||
{
|
{
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
|
@ -508,7 +508,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
*progress = SASL_INPROGRESS;
|
*progress = SASL_INPROGRESS;
|
||||||
state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
|
sasl_state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,14 +548,14 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
if(code != sasl->params->finalcode)
|
if(code != sasl->params->finalcode)
|
||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
*progress = SASL_DONE;
|
*progress = SASL_DONE;
|
||||||
state(sasl, data, SASL_STOP);
|
sasl_state(sasl, data, SASL_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
|
if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
|
||||||
code != sasl->params->contcode) {
|
code != sasl->params->contcode) {
|
||||||
*progress = SASL_DONE;
|
*progress = SASL_DONE;
|
||||||
state(sasl, data, SASL_STOP);
|
sasl_state(sasl, data, SASL_STOP);
|
||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +698,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
if(code == sasl->params->finalcode) {
|
if(code == sasl->params->finalcode) {
|
||||||
/* Final response was received so we are done */
|
/* Final response was received so we are done */
|
||||||
*progress = SASL_DONE;
|
*progress = SASL_DONE;
|
||||||
state(sasl, data, SASL_STOP);
|
sasl_state(sasl, data, SASL_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if(code == sasl->params->contcode) {
|
else if(code == sasl->params->contcode) {
|
||||||
|
@ -708,7 +708,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*progress = SASL_DONE;
|
*progress = SASL_DONE;
|
||||||
state(sasl, data, SASL_STOP);
|
sasl_state(sasl, data, SASL_STOP);
|
||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +745,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
|
||||||
|
|
||||||
Curl_bufref_free(&resp);
|
Curl_bufref_free(&resp);
|
||||||
|
|
||||||
state(sasl, data, newstate);
|
sasl_state(sasl, data, newstate);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,12 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SCHANNEL
|
||||||
|
/* Must set this before <schannel.h> is included directly or indirectly by
|
||||||
|
another Windows header. */
|
||||||
|
# define SCHANNEL_USE_BLACKLISTS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __hpux
|
#ifdef __hpux
|
||||||
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
|
||||||
# ifdef _APP32_64BIT_OFF_T
|
# ifdef _APP32_64BIT_OFF_T
|
||||||
|
|
10
lib/easy.c
10
lib/easy.c
|
@ -83,7 +83,7 @@
|
||||||
|
|
||||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||||
static unsigned int initialized;
|
static unsigned int initialized;
|
||||||
static long init_flags;
|
static long easy_init_flags;
|
||||||
|
|
||||||
#ifdef GLOBAL_INIT_IS_THREADSAFE
|
#ifdef GLOBAL_INIT_IS_THREADSAFE
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_flags = flags;
|
easy_init_flags = flags;
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
if(getenv("CURL_GLOBAL_INIT"))
|
if(getenv("CURL_GLOBAL_INIT"))
|
||||||
|
@ -274,7 +274,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* curl_global_cleanup() globally cleanups curl, uses the value of
|
* curl_global_cleanup() globally cleanups curl, uses the value of
|
||||||
* "init_flags" to determine what needs to be cleaned up and what doesn't.
|
* "easy_init_flags" to determine what needs to be cleaned up and what doesn't.
|
||||||
*/
|
*/
|
||||||
void curl_global_cleanup(void)
|
void curl_global_cleanup(void)
|
||||||
{
|
{
|
||||||
|
@ -294,7 +294,7 @@ void curl_global_cleanup(void)
|
||||||
Curl_resolver_global_cleanup();
|
Curl_resolver_global_cleanup();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Curl_win32_cleanup(init_flags);
|
Curl_win32_cleanup(easy_init_flags);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Curl_amiga_cleanup();
|
Curl_amiga_cleanup();
|
||||||
|
@ -308,7 +308,7 @@ void curl_global_cleanup(void)
|
||||||
free(leakpointer);
|
free(leakpointer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_flags = 0;
|
easy_init_flags = 0;
|
||||||
|
|
||||||
global_init_unlock();
|
global_init_unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#ifndef HEADER_CURL_EASY_LOCK_H
|
||||||
|
#define HEADER_CURL_EASY_LOCK_H
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
|
@ -103,3 +105,5 @@ static inline void curl_simple_lock_unlock(curl_simple_lock *lock)
|
||||||
#undef GLOBAL_INIT_IS_THREADSAFE
|
#undef GLOBAL_INIT_IS_THREADSAFE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* HEADER_CURL_EASY_LOCK_H */
|
||||||
|
|
120
lib/ftp.c
120
lib/ftp.c
|
@ -93,14 +93,14 @@
|
||||||
|
|
||||||
/* Local API functions */
|
/* Local API functions */
|
||||||
#ifndef DEBUGBUILD
|
#ifndef DEBUGBUILD
|
||||||
static void _state(struct Curl_easy *data,
|
static void _ftp_state(struct Curl_easy *data,
|
||||||
ftpstate newstate);
|
ftpstate newstate);
|
||||||
#define state(x,y) _state(x,y)
|
#define ftp_state(x,y) _ftp_state(x,y)
|
||||||
#else
|
#else
|
||||||
static void _state(struct Curl_easy *data,
|
static void _ftp_state(struct Curl_easy *data,
|
||||||
ftpstate newstate,
|
ftpstate newstate,
|
||||||
int lineno);
|
int lineno);
|
||||||
#define state(x,y) _state(x,y,__LINE__)
|
#define ftp_state(x,y) _ftp_state(x,y,__LINE__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CURLcode ftp_sendquote(struct Curl_easy *data,
|
static CURLcode ftp_sendquote(struct Curl_easy *data,
|
||||||
|
@ -463,7 +463,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
|
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
@ -591,7 +591,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
|
||||||
* generically is a good idea.
|
* generically is a good idea.
|
||||||
*/
|
*/
|
||||||
infof(data, "We got a 421 - timeout");
|
infof(data, "We got a 421 - timeout");
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return CURLE_OPERATION_TIMEDOUT;
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +750,7 @@ static const char * const ftp_state_names[]={
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the ONLY way to change FTP state! */
|
/* This is the ONLY way to change FTP state! */
|
||||||
static void _state(struct Curl_easy *data,
|
static void _ftp_state(struct Curl_easy *data,
|
||||||
ftpstate newstate
|
ftpstate newstate
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
, int lineno
|
, int lineno
|
||||||
|
@ -784,7 +784,7 @@ static CURLcode ftp_state_user(struct Curl_easy *data,
|
||||||
if(!result) {
|
if(!result) {
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
ftpc->ftp_trying_alternative = FALSE;
|
ftpc->ftp_trying_alternative = FALSE;
|
||||||
state(data, FTP_USER);
|
ftp_state(data, FTP_USER);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -794,7 +794,7 @@ static CURLcode ftp_state_pwd(struct Curl_easy *data,
|
||||||
{
|
{
|
||||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD");
|
CURLcode result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "%s", "PWD");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_PWD);
|
ftp_state(data, FTP_PWD);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -872,7 +872,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
|
||||||
for all upcoming ones in the ftp->dirs[] array */
|
for all upcoming ones in the ftp->dirs[] array */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath);
|
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s", ftpc->entrypath);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_CWD);
|
ftp_state(data, FTP_CWD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(ftpc->dirdepth) {
|
if(ftpc->dirdepth) {
|
||||||
|
@ -882,7 +882,7 @@ static CURLcode ftp_state_cwd(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
|
||||||
ftpc->dirs[ftpc->cwdcount -1]);
|
ftpc->dirs[ftpc->cwdcount -1]);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_CWD);
|
ftp_state(data, FTP_CWD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* No CWD necessary */
|
/* No CWD necessary */
|
||||||
|
@ -1261,11 +1261,11 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
||||||
if(result)
|
if(result)
|
||||||
goto out;
|
goto out;
|
||||||
portsock = CURL_SOCKET_BAD; /* now held in filter */
|
portsock = CURL_SOCKET_BAD; /* now held in filter */
|
||||||
state(data, FTP_PORT);
|
ftp_state(data, FTP_PORT);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if(result) {
|
if(result) {
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
}
|
}
|
||||||
if(portsock != CURL_SOCKET_BAD)
|
if(portsock != CURL_SOCKET_BAD)
|
||||||
Curl_socket_close(data, conn, portsock);
|
Curl_socket_close(data, conn, portsock);
|
||||||
|
@ -1307,7 +1307,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
|
result = Curl_pp_sendf(data, &ftpc->pp, "%s", mode[modeoff]);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
ftpc->count1 = modeoff;
|
ftpc->count1 = modeoff;
|
||||||
state(data, FTP_PASV);
|
ftp_state(data, FTP_PASV);
|
||||||
infof(data, "Connect data stream passively");
|
infof(data, "Connect data stream passively");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -1330,7 +1330,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
|
||||||
/* doesn't transfer any data */
|
/* doesn't transfer any data */
|
||||||
|
|
||||||
/* still possibly do PRE QUOTE jobs */
|
/* still possibly do PRE QUOTE jobs */
|
||||||
state(data, FTP_RETR_PREQUOTE);
|
ftp_state(data, FTP_RETR_PREQUOTE);
|
||||||
result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
|
result = ftp_state_quote(data, TRUE, FTP_RETR_PREQUOTE);
|
||||||
}
|
}
|
||||||
else if(data->set.ftp_use_port) {
|
else if(data->set.ftp_use_port) {
|
||||||
|
@ -1355,7 +1355,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "PRET RETR %s",
|
||||||
conn->proto.ftpc.file);
|
conn->proto.ftpc.file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_PRET);
|
ftp_state(data, FTP_PRET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_use_pasv(data, conn);
|
result = ftp_state_use_pasv(data, conn);
|
||||||
|
@ -1377,7 +1377,7 @@ static CURLcode ftp_state_rest(struct Curl_easy *data,
|
||||||
whether it supports range */
|
whether it supports range */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0);
|
result = Curl_pp_sendf(data, &ftpc->pp, "REST %d", 0);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_REST);
|
ftp_state(data, FTP_REST);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_prepare_transfer(data);
|
result = ftp_state_prepare_transfer(data);
|
||||||
|
@ -1398,7 +1398,7 @@ static CURLcode ftp_state_size(struct Curl_easy *data,
|
||||||
/* we know ftpc->file is a valid pointer to a file name */
|
/* we know ftpc->file is a valid pointer to a file name */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_SIZE);
|
ftp_state(data, FTP_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_rest(data, conn);
|
result = ftp_state_rest(data, conn);
|
||||||
|
@ -1466,7 +1466,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data)
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_LIST);
|
ftp_state(data, FTP_LIST);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1530,7 +1530,7 @@ static CURLcode ftp_state_mdtm(struct Curl_easy *data)
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "MDTM %s", ftpc->file);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_MDTM);
|
ftp_state(data, FTP_MDTM);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_type(data);
|
result = ftp_state_type(data);
|
||||||
|
@ -1569,7 +1569,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
|
||||||
/* Got no given size to start from, figure it out */
|
/* Got no given size to start from, figure it out */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_STOR_SIZE);
|
ftp_state(data, FTP_STOR_SIZE);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1624,7 +1624,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
|
||||||
* ftp_done() because we didn't transfer anything! */
|
* ftp_done() because we didn't transfer anything! */
|
||||||
ftp->transfer = PPTRANSFER_NONE;
|
ftp->transfer = PPTRANSFER_NONE;
|
||||||
|
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1634,7 +1634,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s",
|
||||||
ftpc->file);
|
ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_STOR);
|
ftp_state(data, FTP_STOR);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1695,7 +1695,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
|
result = Curl_pp_sendf(data, &ftpc->pp, "%s", cmd);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
state(data, instate);
|
ftp_state(data, instate);
|
||||||
quote = TRUE;
|
quote = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1709,7 +1709,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
|
||||||
break;
|
break;
|
||||||
case FTP_RETR_PREQUOTE:
|
case FTP_RETR_PREQUOTE:
|
||||||
if(ftp->transfer != PPTRANSFER_BODY)
|
if(ftp->transfer != PPTRANSFER_BODY)
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
else {
|
else {
|
||||||
if(ftpc->known_filesize != -1) {
|
if(ftpc->known_filesize != -1) {
|
||||||
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
|
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
|
||||||
|
@ -1731,12 +1731,12 @@ static CURLcode ftp_state_quote(struct Curl_easy *data,
|
||||||
*/
|
*/
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_RETR);
|
ftp_state(data, FTP_RETR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "SIZE %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_RETR_SIZE);
|
ftp_state(data, FTP_RETR_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1780,7 +1780,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data,
|
||||||
if(!result) {
|
if(!result) {
|
||||||
conn->proto.ftpc.count1++;
|
conn->proto.ftpc.count1++;
|
||||||
/* remain in/go to the FTP_PASV state */
|
/* remain in/go to the FTP_PASV state */
|
||||||
state(data, FTP_PASV);
|
ftp_state(data, FTP_PASV);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2005,7 +2005,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
conn->bits.do_more = TRUE;
|
conn->bits.do_more = TRUE;
|
||||||
state(data, FTP_STOP); /* this phase is completed */
|
ftp_state(data, FTP_STOP); /* this phase is completed */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2039,7 +2039,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
infof(data, "Connect data stream actively");
|
infof(data, "Connect data stream actively");
|
||||||
state(data, FTP_STOP); /* end of DO phase */
|
ftp_state(data, FTP_STOP); /* end of DO phase */
|
||||||
result = ftp_dophase_done(data, FALSE);
|
result = ftp_dophase_done(data, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2151,7 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||||
infof(data, "The requested document is not new enough");
|
infof(data, "The requested document is not new enough");
|
||||||
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
||||||
data->info.timecond = TRUE;
|
data->info.timecond = TRUE;
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2160,7 +2160,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
|
||||||
infof(data, "The requested document is not old enough");
|
infof(data, "The requested document is not old enough");
|
||||||
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */
|
||||||
data->info.timecond = TRUE;
|
data->info.timecond = TRUE;
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2268,7 +2268,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
|
||||||
/* Set ->transfer so that we won't get any error in ftp_done()
|
/* Set ->transfer so that we won't get any error in ftp_done()
|
||||||
* because we didn't transfer the any file */
|
* because we didn't transfer the any file */
|
||||||
ftp->transfer = PPTRANSFER_NONE;
|
ftp->transfer = PPTRANSFER_NONE;
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2279,13 +2279,13 @@ static CURLcode ftp_state_retr(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
|
result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
|
||||||
data->state.resume_from);
|
data->state.resume_from);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_RETR_REST);
|
ftp_state(data, FTP_RETR_REST);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* no resume */
|
/* no resume */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_RETR);
|
ftp_state(data, FTP_RETR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -2385,7 +2385,7 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data,
|
||||||
else {
|
else {
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_RETR);
|
ftp_state(data, FTP_RETR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2401,7 +2401,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
|
||||||
|
|
||||||
if(ftpcode >= 400) {
|
if(ftpcode >= 400) {
|
||||||
failf(data, "Failed FTP upload: %0d", ftpcode);
|
failf(data, "Failed FTP upload: %0d", ftpcode);
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
/* oops, we never close the sockets! */
|
/* oops, we never close the sockets! */
|
||||||
return CURLE_UPLOAD_FAILED;
|
return CURLE_UPLOAD_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -2412,7 +2412,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data,
|
||||||
if(data->set.ftp_use_port) {
|
if(data->set.ftp_use_port) {
|
||||||
bool connected;
|
bool connected;
|
||||||
|
|
||||||
state(data, FTP_STOP); /* no longer in STOR state */
|
ftp_state(data, FTP_STOP); /* no longer in STOR state */
|
||||||
|
|
||||||
result = AllowServerConnect(data, &connected);
|
result = AllowServerConnect(data, &connected);
|
||||||
if(result)
|
if(result)
|
||||||
|
@ -2535,7 +2535,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||||
if(!connected) {
|
if(!connected) {
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
infof(data, "Data conn was not available immediately");
|
infof(data, "Data conn was not available immediately");
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
ftpc->wait_data_conn = TRUE;
|
ftpc->wait_data_conn = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2546,7 +2546,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
|
||||||
if((instate == FTP_LIST) && (ftpcode == 450)) {
|
if((instate == FTP_LIST) && (ftpcode == 450)) {
|
||||||
/* simply no matching files in the dir listing */
|
/* simply no matching files in the dir listing */
|
||||||
ftp->transfer = PPTRANSFER_NONE; /* don't download anything */
|
ftp->transfer = PPTRANSFER_NONE; /* don't download anything */
|
||||||
state(data, FTP_STOP); /* this phase is over */
|
ftp_state(data, FTP_STOP); /* this phase is over */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "RETR response: %03d", ftpcode);
|
failf(data, "RETR response: %03d", ftpcode);
|
||||||
|
@ -2582,7 +2582,7 @@ static CURLcode ftp_state_loggedin(struct Curl_easy *data)
|
||||||
*/
|
*/
|
||||||
result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0);
|
result = Curl_pp_sendf(data, &conn->proto.ftpc.pp, "PBSZ %d", 0);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_PBSZ);
|
ftp_state(data, FTP_PBSZ);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = ftp_state_pwd(data, conn);
|
result = ftp_state_pwd(data, conn);
|
||||||
|
@ -2605,7 +2605,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "PASS %s",
|
||||||
conn->passwd?conn->passwd:"");
|
conn->passwd?conn->passwd:"");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_PASS);
|
ftp_state(data, FTP_PASS);
|
||||||
}
|
}
|
||||||
else if(ftpcode/100 == 2) {
|
else if(ftpcode/100 == 2) {
|
||||||
/* 230 User ... logged in.
|
/* 230 User ... logged in.
|
||||||
|
@ -2617,7 +2617,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "ACCT %s",
|
||||||
data->set.str[STRING_FTP_ACCOUNT]);
|
data->set.str[STRING_FTP_ACCOUNT]);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_ACCT);
|
ftp_state(data, FTP_ACCT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "ACCT requested but none available");
|
failf(data, "ACCT requested but none available");
|
||||||
|
@ -2638,7 +2638,7 @@ static CURLcode ftp_state_user_resp(struct Curl_easy *data,
|
||||||
data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
|
data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
ftpc->ftp_trying_alternative = TRUE;
|
ftpc->ftp_trying_alternative = TRUE;
|
||||||
state(data, FTP_USER);
|
ftp_state(data, FTP_USER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2741,7 +2741,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "AUTH %s",
|
||||||
ftpauth[ftpc->count1]);
|
ftpauth[ftpc->count1]);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_AUTH);
|
ftp_state(data, FTP_AUTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_user(data, conn);
|
result = ftp_state_user(data, conn);
|
||||||
|
@ -2808,7 +2808,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
Curl_pp_sendf(data, &ftpc->pp, "PROT %c",
|
Curl_pp_sendf(data, &ftpc->pp, "PROT %c",
|
||||||
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
|
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_PROT);
|
ftp_state(data, FTP_PROT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FTP_PROT:
|
case FTP_PROT:
|
||||||
|
@ -2827,7 +2827,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
*/
|
*/
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC");
|
result = Curl_pp_sendf(data, &ftpc->pp, "%s", "CCC");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_CCC);
|
ftp_state(data, FTP_CCC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = ftp_state_pwd(data, conn);
|
result = ftp_state_pwd(data, conn);
|
||||||
|
@ -2919,7 +2919,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
infof(data, "Entry path is '%s'", ftpc->entrypath);
|
infof(data, "Entry path is '%s'", ftpc->entrypath);
|
||||||
/* also save it where getinfo can access it: */
|
/* also save it where getinfo can access it: */
|
||||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||||
state(data, FTP_SYST);
|
ftp_state(data, FTP_SYST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2935,7 +2935,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
infof(data, "Failed to figure out path");
|
infof(data, "Failed to figure out path");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2970,7 +2970,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
/* remember target server OS */
|
/* remember target server OS */
|
||||||
Curl_safefree(ftpc->server_os);
|
Curl_safefree(ftpc->server_os);
|
||||||
ftpc->server_os = os;
|
ftpc->server_os = os;
|
||||||
state(data, FTP_NAMEFMT);
|
ftp_state(data, FTP_NAMEFMT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Nothing special for the target server. */
|
/* Nothing special for the target server. */
|
||||||
|
@ -2982,7 +2982,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
/* Cannot identify server OS. Continue anyway and cross fingers. */
|
/* Cannot identify server OS. Continue anyway and cross fingers. */
|
||||||
}
|
}
|
||||||
|
|
||||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2993,7 +2993,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
ftp_state(data, FTP_STOP); /* we are done with the CONNECT phase! */
|
||||||
DEBUGF(infof(data, "protocol connect phase DONE"));
|
DEBUGF(infof(data, "protocol connect phase DONE"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3026,7 +3026,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "MKD %s",
|
||||||
ftpc->dirs[ftpc->cwdcount - 1]);
|
ftpc->dirs[ftpc->cwdcount - 1]);
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, FTP_MKD);
|
ftp_state(data, FTP_MKD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* return failure */
|
/* return failure */
|
||||||
|
@ -3055,7 +3055,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
result = CURLE_REMOTE_ACCESS_DENIED;
|
result = CURLE_REMOTE_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state(data, FTP_CWD);
|
ftp_state(data, FTP_CWD);
|
||||||
/* send CWD */
|
/* send CWD */
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
|
result = Curl_pp_sendf(data, &ftpc->pp, "CWD %s",
|
||||||
ftpc->dirs[ftpc->cwdcount - 1]);
|
ftpc->dirs[ftpc->cwdcount - 1]);
|
||||||
|
@ -3114,7 +3114,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
|
||||||
/* fallthrough, just stop! */
|
/* fallthrough, just stop! */
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* if(ftpcode) */
|
} /* if(ftpcode) */
|
||||||
|
@ -3191,7 +3191,7 @@ static CURLcode ftp_connect(struct Curl_easy *data,
|
||||||
|
|
||||||
/* When we connect, we start in the state where we await the 220
|
/* When we connect, we start in the state where we await the 220
|
||||||
response */
|
response */
|
||||||
state(data, FTP_WAIT220);
|
ftp_state(data, FTP_WAIT220);
|
||||||
|
|
||||||
result = ftp_multi_statemach(data, done);
|
result = ftp_multi_statemach(data, done);
|
||||||
|
|
||||||
|
@ -3516,13 +3516,13 @@ static CURLcode ftp_nb_type(struct Curl_easy *data,
|
||||||
char want = (char)(ascii?'A':'I');
|
char want = (char)(ascii?'A':'I');
|
||||||
|
|
||||||
if(ftpc->transfertype == want) {
|
if(ftpc->transfertype == want) {
|
||||||
state(data, newstate);
|
ftp_state(data, newstate);
|
||||||
return ftp_state_type_resp(data, 200, newstate);
|
return ftp_state_type_resp(data, 200, newstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want);
|
result = Curl_pp_sendf(data, &ftpc->pp, "TYPE %c", want);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
state(data, newstate);
|
ftp_state(data, newstate);
|
||||||
|
|
||||||
/* keep track of our current transfer type */
|
/* keep track of our current transfer type */
|
||||||
ftpc->transfertype = want;
|
ftpc->transfertype = want;
|
||||||
|
@ -4039,11 +4039,11 @@ static CURLcode ftp_quit(struct Curl_easy *data, struct connectdata *conn)
|
||||||
curl_easy_strerror(result));
|
curl_easy_strerror(result));
|
||||||
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
|
conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
|
||||||
connclose(conn, "QUIT command failed"); /* mark for connection closure */
|
connclose(conn, "QUIT command failed"); /* mark for connection closure */
|
||||||
state(data, FTP_STOP);
|
ftp_state(data, FTP_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
state(data, FTP_QUIT);
|
ftp_state(data, FTP_QUIT);
|
||||||
|
|
||||||
result = ftp_block_statemach(data, conn);
|
result = ftp_block_statemach(data, conn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
/* to play well with debug builds, we can *set* a fixed time this will
|
/* to play well with debug builds, we can *set* a fixed time this will
|
||||||
return */
|
return */
|
||||||
time_t deltatime; /* allow for "adjustments" for unit test purposes */
|
time_t deltatime; /* allow for "adjustments" for unit test purposes */
|
||||||
static time_t debugtime(void *unused)
|
static time_t hsts_debugtime(void *unused)
|
||||||
{
|
{
|
||||||
char *timestr = getenv("CURL_TIME");
|
char *timestr = getenv("CURL_TIME");
|
||||||
(void)unused;
|
(void)unused;
|
||||||
|
@ -70,7 +70,8 @@ static time_t debugtime(void *unused)
|
||||||
}
|
}
|
||||||
return time(NULL);
|
return time(NULL);
|
||||||
}
|
}
|
||||||
#define time(x) debugtime(x)
|
#undef time
|
||||||
|
#define time(x) hsts_debugtime(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct hsts *Curl_hsts_init(void)
|
struct hsts *Curl_hsts_init(void)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_URL_LEN (4*1024)
|
#define H1_MAX_URL_LEN (4*1024)
|
||||||
|
|
||||||
void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len)
|
void Curl_h1_req_parse_init(struct h1_req_parser *parser, size_t max_line_len)
|
||||||
{
|
{
|
||||||
|
@ -231,7 +231,7 @@ static CURLcode start_req(struct h1_req_parser *parser,
|
||||||
else {
|
else {
|
||||||
/* origin-form OR absolute-form */
|
/* origin-form OR absolute-form */
|
||||||
CURLUcode uc;
|
CURLUcode uc;
|
||||||
char tmp[MAX_URL_LEN];
|
char tmp[H1_MAX_URL_LEN];
|
||||||
|
|
||||||
/* default, unless we see an absolute URL */
|
/* default, unless we see an absolute URL */
|
||||||
path = target;
|
path = target;
|
||||||
|
|
|
@ -137,6 +137,7 @@ struct cf_h2_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How to access `call_data` from a cf_h2 filter */
|
/* How to access `call_data` from a cf_h2 filter */
|
||||||
|
#undef CF_CTX_CALL_DATA
|
||||||
#define CF_CTX_CALL_DATA(cf) \
|
#define CF_CTX_CALL_DATA(cf) \
|
||||||
((struct cf_h2_ctx *)(cf)->ctx)->call_data
|
((struct cf_h2_ctx *)(cf)->ctx)->call_data
|
||||||
|
|
||||||
|
|
56
lib/imap.c
56
lib/imap.c
|
@ -385,11 +385,11 @@ static CURLcode imap_get_message(struct Curl_easy *data, struct bufref *out)
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* imap_state()
|
||||||
*
|
*
|
||||||
* This is the ONLY way to change IMAP state!
|
* This is the ONLY way to change IMAP state!
|
||||||
*/
|
*/
|
||||||
static void state(struct Curl_easy *data, imapstate newstate)
|
static void imap_state(struct Curl_easy *data, imapstate newstate)
|
||||||
{
|
{
|
||||||
struct imap_conn *imapc = &data->conn->proto.imapc;
|
struct imap_conn *imapc = &data->conn->proto.imapc;
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
|
@ -441,7 +441,7 @@ static CURLcode imap_perform_capability(struct Curl_easy *data,
|
||||||
result = imap_sendf(data, "CAPABILITY");
|
result = imap_sendf(data, "CAPABILITY");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_CAPABILITY);
|
imap_state(data, IMAP_CAPABILITY);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ static CURLcode imap_perform_starttls(struct Curl_easy *data)
|
||||||
CURLcode result = imap_sendf(data, "STARTTLS");
|
CURLcode result = imap_sendf(data, "STARTTLS");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_STARTTLS);
|
imap_state(data, IMAP_STARTTLS);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data,
|
||||||
if(!result) {
|
if(!result) {
|
||||||
imapc->ssldone = ssldone;
|
imapc->ssldone = ssldone;
|
||||||
if(imapc->state != IMAP_UPGRADETLS)
|
if(imapc->state != IMAP_UPGRADETLS)
|
||||||
state(data, IMAP_UPGRADETLS);
|
imap_state(data, IMAP_UPGRADETLS);
|
||||||
|
|
||||||
if(imapc->ssldone) {
|
if(imapc->ssldone) {
|
||||||
imap_to_imaps(conn);
|
imap_to_imaps(conn);
|
||||||
|
@ -514,7 +514,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
|
||||||
/* Check we have a username and password to authenticate with and end the
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we don't */
|
connect phase if we don't */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.aptr.user) {
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data,
|
||||||
free(passwd);
|
free(passwd);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_LOGIN);
|
imap_state(data, IMAP_LOGIN);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +615,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
|
||||||
with and end the connect phase if we don't */
|
with and end the connect phase if we don't */
|
||||||
if(imapc->preauth ||
|
if(imapc->preauth ||
|
||||||
!Curl_sasl_can_authenticate(&imapc->sasl, data)) {
|
!Curl_sasl_can_authenticate(&imapc->sasl, data)) {
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data,
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
if(progress == SASL_INPROGRESS)
|
if(progress == SASL_INPROGRESS)
|
||||||
state(data, IMAP_AUTHENTICATE);
|
imap_state(data, IMAP_AUTHENTICATE);
|
||||||
else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
|
else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
|
||||||
/* Perform clear text authentication */
|
/* Perform clear text authentication */
|
||||||
result = imap_perform_login(data, conn);
|
result = imap_perform_login(data, conn);
|
||||||
|
@ -667,7 +667,7 @@ static CURLcode imap_perform_list(struct Curl_easy *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_LIST);
|
imap_state(data, IMAP_LIST);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -707,7 +707,7 @@ static CURLcode imap_perform_select(struct Curl_easy *data)
|
||||||
free(mailbox);
|
free(mailbox);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_SELECT);
|
imap_state(data, IMAP_SELECT);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -749,7 +749,7 @@ static CURLcode imap_perform_fetch(struct Curl_easy *data)
|
||||||
return CURLE_URL_MALFORMAT;
|
return CURLE_URL_MALFORMAT;
|
||||||
}
|
}
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_FETCH);
|
imap_state(data, IMAP_FETCH);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -820,7 +820,7 @@ static CURLcode imap_perform_append(struct Curl_easy *data)
|
||||||
free(mailbox);
|
free(mailbox);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_APPEND);
|
imap_state(data, IMAP_APPEND);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -846,7 +846,7 @@ static CURLcode imap_perform_search(struct Curl_easy *data)
|
||||||
result = imap_sendf(data, "SEARCH %s", imap->query);
|
result = imap_sendf(data, "SEARCH %s", imap->query);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_SEARCH);
|
imap_state(data, IMAP_SEARCH);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -863,7 +863,7 @@ static CURLcode imap_perform_logout(struct Curl_easy *data)
|
||||||
CURLcode result = imap_sendf(data, "LOGOUT");
|
CURLcode result = imap_sendf(data, "LOGOUT");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_LOGOUT);
|
imap_state(data, IMAP_LOGOUT);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1017,7 @@ static CURLcode imap_state_auth_resp(struct Curl_easy *data,
|
||||||
if(!result)
|
if(!result)
|
||||||
switch(progress) {
|
switch(progress) {
|
||||||
case SASL_DONE:
|
case SASL_DONE:
|
||||||
state(data, IMAP_STOP); /* Authenticated */
|
imap_state(data, IMAP_STOP); /* Authenticated */
|
||||||
break;
|
break;
|
||||||
case SASL_IDLE: /* No mechanism left after cancellation */
|
case SASL_IDLE: /* No mechanism left after cancellation */
|
||||||
if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
|
if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
|
||||||
|
@ -1049,7 +1049,7 @@ static CURLcode imap_state_login_resp(struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of connect phase */
|
/* End of connect phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1075,7 +1075,7 @@ static CURLcode imap_state_listsearch_resp(struct Curl_easy *data,
|
||||||
result = CURLE_QUOTE_ERROR;
|
result = CURLE_QUOTE_ERROR;
|
||||||
else
|
else
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1143,7 +1143,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
|
||||||
|
|
||||||
if(imapcode != '*') {
|
if(imapcode != '*') {
|
||||||
Curl_pgrsSetDownloadSize(data, -1);
|
Curl_pgrsSetDownloadSize(data, -1);
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,7 +1178,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
|
||||||
|
|
||||||
if(!chunk) {
|
if(!chunk) {
|
||||||
/* no size, we're done with the data */
|
/* no size, we're done with the data */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk);
|
result = Curl_client_write(data, CLIENTWRITE_BODY, pp->cache, chunk);
|
||||||
|
@ -1224,7 +1224,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1242,7 +1242,7 @@ static CURLcode imap_state_fetch_final_resp(struct Curl_easy *data,
|
||||||
result = CURLE_WEIRD_SERVER_REPLY;
|
result = CURLE_WEIRD_SERVER_REPLY;
|
||||||
else
|
else
|
||||||
/* End of DONE phase */
|
/* End of DONE phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1265,7 +1265,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data, int imapcode,
|
||||||
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||||
|
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1284,7 +1284,7 @@ static CURLcode imap_state_append_final_resp(struct Curl_easy *data,
|
||||||
result = CURLE_UPLOAD_FAILED;
|
result = CURLE_UPLOAD_FAILED;
|
||||||
else
|
else
|
||||||
/* End of DONE phase */
|
/* End of DONE phase */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1372,7 +1372,7 @@ static CURLcode imap_statemachine(struct Curl_easy *data,
|
||||||
/* fallthrough, just stop! */
|
/* fallthrough, just stop! */
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
state(data, IMAP_STOP);
|
imap_state(data, IMAP_STOP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
|
} while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
|
||||||
|
@ -1475,7 +1475,7 @@ static CURLcode imap_connect(struct Curl_easy *data, bool *done)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* Start off waiting for the server greeting response */
|
/* Start off waiting for the server greeting response */
|
||||||
state(data, IMAP_SERVERGREET);
|
imap_state(data, IMAP_SERVERGREET);
|
||||||
|
|
||||||
/* Start off with an response id of '*' */
|
/* Start off with an response id of '*' */
|
||||||
strcpy(imapc->resptag, "*");
|
strcpy(imapc->resptag, "*");
|
||||||
|
@ -1516,12 +1516,12 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
|
||||||
/* Handle responses after FETCH or APPEND transfer has finished */
|
/* Handle responses after FETCH or APPEND transfer has finished */
|
||||||
|
|
||||||
if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
|
if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
|
||||||
state(data, IMAP_FETCH_FINAL);
|
imap_state(data, IMAP_FETCH_FINAL);
|
||||||
else {
|
else {
|
||||||
/* End the APPEND command first by sending an empty line */
|
/* End the APPEND command first by sending an empty line */
|
||||||
result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", "");
|
result = Curl_pp_sendf(data, &conn->proto.imapc.pp, "%s", "");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, IMAP_APPEND_FINAL);
|
imap_state(data, IMAP_APPEND_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run the state-machine */
|
/* Run the state-machine */
|
||||||
|
|
|
@ -50,6 +50,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
|
#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(push)
|
||||||
|
# pragma warning(disable: 4201)
|
||||||
|
# endif
|
||||||
|
# include <subauth.h> /* for [P]UNICODE_STRING */
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma warning(pop)
|
||||||
|
# endif
|
||||||
# include <winldap.h>
|
# include <winldap.h>
|
||||||
# ifndef LDAP_VENDOR_NAME
|
# ifndef LDAP_VENDOR_NAME
|
||||||
# error Your Platform SDK is NOT sufficient for LDAP support! \
|
# error Your Platform SDK is NOT sufficient for LDAP support! \
|
||||||
|
|
16
lib/mime.c
16
lib/mime.c
|
@ -84,7 +84,7 @@ static const struct mime_encoder encoders[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Base64 encoding table */
|
/* Base64 encoding table */
|
||||||
static const char base64[] =
|
static const char base64enc[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
/* Quoted-printable character class table.
|
/* Quoted-printable character class table.
|
||||||
|
@ -469,10 +469,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||||
i = st->buf[st->bufbeg++] & 0xFF;
|
i = st->buf[st->bufbeg++] & 0xFF;
|
||||||
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
|
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
|
||||||
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
|
i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
|
||||||
*ptr++ = base64[(i >> 18) & 0x3F];
|
*ptr++ = base64enc[(i >> 18) & 0x3F];
|
||||||
*ptr++ = base64[(i >> 12) & 0x3F];
|
*ptr++ = base64enc[(i >> 12) & 0x3F];
|
||||||
*ptr++ = base64[(i >> 6) & 0x3F];
|
*ptr++ = base64enc[(i >> 6) & 0x3F];
|
||||||
*ptr++ = base64[i & 0x3F];
|
*ptr++ = base64enc[i & 0x3F];
|
||||||
cursize += 4;
|
cursize += 4;
|
||||||
st->pos += 4;
|
st->pos += 4;
|
||||||
size -= 4;
|
size -= 4;
|
||||||
|
@ -496,10 +496,10 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
|
||||||
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
|
i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
|
||||||
|
|
||||||
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
|
i |= (st->buf[st->bufbeg] & 0xFF) << 16;
|
||||||
ptr[0] = base64[(i >> 18) & 0x3F];
|
ptr[0] = base64enc[(i >> 18) & 0x3F];
|
||||||
ptr[1] = base64[(i >> 12) & 0x3F];
|
ptr[1] = base64enc[(i >> 12) & 0x3F];
|
||||||
if(++st->bufbeg != st->bufend) {
|
if(++st->bufbeg != st->bufend) {
|
||||||
ptr[2] = base64[(i >> 6) & 0x3F];
|
ptr[2] = base64enc[(i >> 6) & 0x3F];
|
||||||
st->bufbeg++;
|
st->bufbeg++;
|
||||||
}
|
}
|
||||||
cursize += 4;
|
cursize += 4;
|
||||||
|
|
|
@ -112,7 +112,7 @@ static CURLMcode multi_timeout(struct Curl_multi *multi,
|
||||||
static void process_pending_handles(struct Curl_multi *multi);
|
static void process_pending_handles(struct Curl_multi *multi);
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
static const char * const statename[]={
|
static const char * const multi_statename[]={
|
||||||
"INIT",
|
"INIT",
|
||||||
"PENDING",
|
"PENDING",
|
||||||
"CONNECT",
|
"CONNECT",
|
||||||
|
@ -201,7 +201,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state
|
||||||
|
|
||||||
infof(data,
|
infof(data,
|
||||||
"STATE: %s => %s handle %p; line %d (connection #%ld)",
|
"STATE: %s => %s handle %p; line %d (connection #%ld)",
|
||||||
statename[oldstate], statename[data->mstate],
|
multi_statename[oldstate], multi_statename[data->mstate],
|
||||||
(void *)data, lineno, connection_id);
|
(void *)data, lineno, connection_id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3798,7 +3798,7 @@ void Curl_multi_dump(struct Curl_multi *multi)
|
||||||
/* only display handles that are not completed */
|
/* only display handles that are not completed */
|
||||||
fprintf(stderr, "handle %p, state %s, %d sockets\n",
|
fprintf(stderr, "handle %p, state %s, %d sockets\n",
|
||||||
(void *)data,
|
(void *)data,
|
||||||
statename[data->mstate], data->numsocks);
|
multi_statename[data->mstate], data->numsocks);
|
||||||
for(i = 0; i < data->numsocks; i++) {
|
for(i = 0; i < data->numsocks; i++) {
|
||||||
curl_socket_t s = data->sockets[i];
|
curl_socket_t s = data->sockets[i];
|
||||||
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
|
struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
|
||||||
|
|
44
lib/pop3.c
44
lib/pop3.c
|
@ -282,11 +282,11 @@ static CURLcode pop3_get_message(struct Curl_easy *data, struct bufref *out)
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* pop3_state()
|
||||||
*
|
*
|
||||||
* This is the ONLY way to change POP3 state!
|
* This is the ONLY way to change POP3 state!
|
||||||
*/
|
*/
|
||||||
static void state(struct Curl_easy *data, pop3state newstate)
|
static void pop3_state(struct Curl_easy *data, pop3state newstate)
|
||||||
{
|
{
|
||||||
struct pop3_conn *pop3c = &data->conn->proto.pop3c;
|
struct pop3_conn *pop3c = &data->conn->proto.pop3c;
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
|
@ -335,7 +335,7 @@ static CURLcode pop3_perform_capa(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
|
result = Curl_pp_sendf(data, &pop3c->pp, "%s", "CAPA");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_CAPA);
|
pop3_state(data, POP3_CAPA);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ static CURLcode pop3_perform_starttls(struct Curl_easy *data,
|
||||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
|
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "STLS");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_STARTTLS);
|
pop3_state(data, POP3_STARTTLS);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data,
|
||||||
if(!result) {
|
if(!result) {
|
||||||
pop3c->ssldone = ssldone;
|
pop3c->ssldone = ssldone;
|
||||||
if(pop3c->state != POP3_UPGRADETLS)
|
if(pop3c->state != POP3_UPGRADETLS)
|
||||||
state(data, POP3_UPGRADETLS);
|
pop3_state(data, POP3_UPGRADETLS);
|
||||||
|
|
||||||
if(pop3c->ssldone) {
|
if(pop3c->ssldone) {
|
||||||
pop3_to_pop3s(conn);
|
pop3_to_pop3s(conn);
|
||||||
|
@ -408,7 +408,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
||||||
/* Check we have a username and password to authenticate with and end the
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we don't */
|
connect phase if we don't */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.aptr.user) {
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ static CURLcode pop3_perform_user(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
|
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "USER %s",
|
||||||
conn->user ? conn->user : "");
|
conn->user ? conn->user : "");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_USER);
|
pop3_state(data, POP3_USER);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
||||||
/* Check we have a username and password to authenticate with and end the
|
/* Check we have a username and password to authenticate with and end the
|
||||||
connect phase if we don't */
|
connect phase if we don't */
|
||||||
if(!data->state.aptr.user) {
|
if(!data->state.aptr.user) {
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +468,7 @@ static CURLcode pop3_perform_apop(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
|
result = Curl_pp_sendf(data, &pop3c->pp, "APOP %s %s", conn->user, secret);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_APOP);
|
pop3_state(data, POP3_APOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -552,7 +552,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
|
||||||
/* Check we have enough data to authenticate with and end the
|
/* Check we have enough data to authenticate with and end the
|
||||||
connect phase if we don't */
|
connect phase if we don't */
|
||||||
if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) {
|
if(!Curl_sasl_can_authenticate(&pop3c->sasl, data)) {
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data,
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
if(progress == SASL_INPROGRESS)
|
if(progress == SASL_INPROGRESS)
|
||||||
state(data, POP3_AUTH);
|
pop3_state(data, POP3_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result && progress == SASL_IDLE) {
|
if(!result && progress == SASL_IDLE) {
|
||||||
|
@ -620,7 +620,7 @@ static CURLcode pop3_perform_command(struct Curl_easy *data)
|
||||||
pop3->custom : command));
|
pop3->custom : command));
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_COMMAND);
|
pop3_state(data, POP3_COMMAND);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -638,7 +638,7 @@ static CURLcode pop3_perform_quit(struct Curl_easy *data,
|
||||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
|
CURLcode result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "%s", "QUIT");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_QUIT);
|
pop3_state(data, POP3_QUIT);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -831,7 +831,7 @@ static CURLcode pop3_state_auth_resp(struct Curl_easy *data,
|
||||||
if(!result)
|
if(!result)
|
||||||
switch(progress) {
|
switch(progress) {
|
||||||
case SASL_DONE:
|
case SASL_DONE:
|
||||||
state(data, POP3_STOP); /* Authenticated */
|
pop3_state(data, POP3_STOP); /* Authenticated */
|
||||||
break;
|
break;
|
||||||
case SASL_IDLE: /* No mechanism left after cancellation */
|
case SASL_IDLE: /* No mechanism left after cancellation */
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
|
@ -869,7 +869,7 @@ static CURLcode pop3_state_apop_resp(struct Curl_easy *data, int pop3code,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of connect phase */
|
/* End of connect phase */
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -892,7 +892,7 @@ static CURLcode pop3_state_user_resp(struct Curl_easy *data, int pop3code,
|
||||||
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
|
result = Curl_pp_sendf(data, &conn->proto.pop3c.pp, "PASS %s",
|
||||||
conn->passwd ? conn->passwd : "");
|
conn->passwd ? conn->passwd : "");
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, POP3_PASS);
|
pop3_state(data, POP3_PASS);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,7 @@ static CURLcode pop3_state_pass_resp(struct Curl_easy *data, int pop3code,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of connect phase */
|
/* End of connect phase */
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -929,7 +929,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
if(pop3code != '+') {
|
if(pop3code != '+') {
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
return CURLE_WEIRD_SERVER_REPLY;
|
return CURLE_WEIRD_SERVER_REPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,7 +967,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1037,12 +1037,12 @@ static CURLcode pop3_statemachine(struct Curl_easy *data,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POP3_QUIT:
|
case POP3_QUIT:
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
state(data, POP3_STOP);
|
pop3_state(data, POP3_STOP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
|
} while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
|
||||||
|
@ -1143,7 +1143,7 @@ static CURLcode pop3_connect(struct Curl_easy *data, bool *done)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* Start off waiting for the server greeting response */
|
/* Start off waiting for the server greeting response */
|
||||||
state(data, POP3_SERVERGREET);
|
pop3_state(data, POP3_SERVERGREET);
|
||||||
|
|
||||||
result = pop3_multi_statemach(data, done);
|
result = pop3_multi_statemach(data, done);
|
||||||
|
|
||||||
|
|
195
lib/smb.c
195
lib/smb.c
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
|
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
|
||||||
|
|
||||||
#define BUILDING_CURL_SMB_C
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define getpid GetCurrentProcessId
|
#define getpid GetCurrentProcessId
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,6 +48,199 @@
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definitions for SMB protocol data structures
|
||||||
|
*/
|
||||||
|
#if defined(_MSC_VER) || defined(__ILEC400__)
|
||||||
|
# define PACK
|
||||||
|
# pragma pack(push)
|
||||||
|
# pragma pack(1)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define PACK __attribute__((packed))
|
||||||
|
#else
|
||||||
|
# define PACK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SMB_COM_CLOSE 0x04
|
||||||
|
#define SMB_COM_READ_ANDX 0x2e
|
||||||
|
#define SMB_COM_WRITE_ANDX 0x2f
|
||||||
|
#define SMB_COM_TREE_DISCONNECT 0x71
|
||||||
|
#define SMB_COM_NEGOTIATE 0x72
|
||||||
|
#define SMB_COM_SETUP_ANDX 0x73
|
||||||
|
#define SMB_COM_TREE_CONNECT_ANDX 0x75
|
||||||
|
#define SMB_COM_NT_CREATE_ANDX 0xa2
|
||||||
|
#define SMB_COM_NO_ANDX_COMMAND 0xff
|
||||||
|
|
||||||
|
#define SMB_WC_CLOSE 0x03
|
||||||
|
#define SMB_WC_READ_ANDX 0x0c
|
||||||
|
#define SMB_WC_WRITE_ANDX 0x0e
|
||||||
|
#define SMB_WC_SETUP_ANDX 0x0d
|
||||||
|
#define SMB_WC_TREE_CONNECT_ANDX 0x04
|
||||||
|
#define SMB_WC_NT_CREATE_ANDX 0x18
|
||||||
|
|
||||||
|
#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
|
||||||
|
#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
|
||||||
|
#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
|
||||||
|
#define SMB_FLAGS2_IS_LONG_NAME 0x0040
|
||||||
|
#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
|
||||||
|
|
||||||
|
#define SMB_CAP_LARGE_FILES 0x08
|
||||||
|
#define SMB_GENERIC_WRITE 0x40000000
|
||||||
|
#define SMB_GENERIC_READ 0x80000000
|
||||||
|
#define SMB_FILE_SHARE_ALL 0x07
|
||||||
|
#define SMB_FILE_OPEN 0x01
|
||||||
|
#define SMB_FILE_OVERWRITE_IF 0x05
|
||||||
|
|
||||||
|
#define SMB_ERR_NOACCESS 0x00050001
|
||||||
|
|
||||||
|
struct smb_header {
|
||||||
|
unsigned char nbt_type;
|
||||||
|
unsigned char nbt_flags;
|
||||||
|
unsigned short nbt_length;
|
||||||
|
unsigned char magic[4];
|
||||||
|
unsigned char command;
|
||||||
|
unsigned int status;
|
||||||
|
unsigned char flags;
|
||||||
|
unsigned short flags2;
|
||||||
|
unsigned short pid_high;
|
||||||
|
unsigned char signature[8];
|
||||||
|
unsigned short pad;
|
||||||
|
unsigned short tid;
|
||||||
|
unsigned short pid;
|
||||||
|
unsigned short uid;
|
||||||
|
unsigned short mid;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_negotiate_response {
|
||||||
|
struct smb_header h;
|
||||||
|
unsigned char word_count;
|
||||||
|
unsigned short dialect_index;
|
||||||
|
unsigned char security_mode;
|
||||||
|
unsigned short max_mpx_count;
|
||||||
|
unsigned short max_number_vcs;
|
||||||
|
unsigned int max_buffer_size;
|
||||||
|
unsigned int max_raw_size;
|
||||||
|
unsigned int session_key;
|
||||||
|
unsigned int capabilities;
|
||||||
|
unsigned int system_time_low;
|
||||||
|
unsigned int system_time_high;
|
||||||
|
unsigned short server_time_zone;
|
||||||
|
unsigned char encryption_key_length;
|
||||||
|
unsigned short byte_count;
|
||||||
|
char bytes[1];
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct andx {
|
||||||
|
unsigned char command;
|
||||||
|
unsigned char pad;
|
||||||
|
unsigned short offset;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_setup {
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned short max_buffer_size;
|
||||||
|
unsigned short max_mpx_count;
|
||||||
|
unsigned short vc_number;
|
||||||
|
unsigned int session_key;
|
||||||
|
unsigned short lengths[2];
|
||||||
|
unsigned int pad;
|
||||||
|
unsigned int capabilities;
|
||||||
|
unsigned short byte_count;
|
||||||
|
char bytes[1024];
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_tree_connect {
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned short flags;
|
||||||
|
unsigned short pw_len;
|
||||||
|
unsigned short byte_count;
|
||||||
|
char bytes[1024];
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_nt_create {
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned char pad;
|
||||||
|
unsigned short name_length;
|
||||||
|
unsigned int flags;
|
||||||
|
unsigned int root_fid;
|
||||||
|
unsigned int access;
|
||||||
|
curl_off_t allocation_size;
|
||||||
|
unsigned int ext_file_attributes;
|
||||||
|
unsigned int share_access;
|
||||||
|
unsigned int create_disposition;
|
||||||
|
unsigned int create_options;
|
||||||
|
unsigned int impersonation_level;
|
||||||
|
unsigned char security_flags;
|
||||||
|
unsigned short byte_count;
|
||||||
|
char bytes[1024];
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_nt_create_response {
|
||||||
|
struct smb_header h;
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned char op_lock_level;
|
||||||
|
unsigned short fid;
|
||||||
|
unsigned int create_disposition;
|
||||||
|
|
||||||
|
curl_off_t create_time;
|
||||||
|
curl_off_t last_access_time;
|
||||||
|
curl_off_t last_write_time;
|
||||||
|
curl_off_t last_change_time;
|
||||||
|
unsigned int ext_file_attributes;
|
||||||
|
curl_off_t allocation_size;
|
||||||
|
curl_off_t end_of_file;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_read {
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned short fid;
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned short max_bytes;
|
||||||
|
unsigned short min_bytes;
|
||||||
|
unsigned int timeout;
|
||||||
|
unsigned short remaining;
|
||||||
|
unsigned int offset_high;
|
||||||
|
unsigned short byte_count;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_write {
|
||||||
|
struct smb_header h;
|
||||||
|
unsigned char word_count;
|
||||||
|
struct andx andx;
|
||||||
|
unsigned short fid;
|
||||||
|
unsigned int offset;
|
||||||
|
unsigned int timeout;
|
||||||
|
unsigned short write_mode;
|
||||||
|
unsigned short remaining;
|
||||||
|
unsigned short pad;
|
||||||
|
unsigned short data_length;
|
||||||
|
unsigned short data_offset;
|
||||||
|
unsigned int offset_high;
|
||||||
|
unsigned short byte_count;
|
||||||
|
unsigned char pad2;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_close {
|
||||||
|
unsigned char word_count;
|
||||||
|
unsigned short fid;
|
||||||
|
unsigned int last_mtime;
|
||||||
|
unsigned short byte_count;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
struct smb_tree_disconnect {
|
||||||
|
unsigned char word_count;
|
||||||
|
unsigned short byte_count;
|
||||||
|
} PACK;
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) || defined(__ILEC400__)
|
||||||
|
# pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Local API functions */
|
/* Local API functions */
|
||||||
static CURLcode smb_setup_connection(struct Curl_easy *data,
|
static CURLcode smb_setup_connection(struct Curl_easy *data,
|
||||||
struct connectdata *conn);
|
struct connectdata *conn);
|
||||||
|
|
197
lib/smb.h
197
lib/smb.h
|
@ -48,203 +48,6 @@ struct smb_conn {
|
||||||
size_t got;
|
size_t got;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Definitions for SMB protocol data structures
|
|
||||||
*/
|
|
||||||
#ifdef BUILDING_CURL_SMB_C
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__ILEC400__)
|
|
||||||
# define PACK
|
|
||||||
# pragma pack(push)
|
|
||||||
# pragma pack(1)
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define PACK __attribute__((packed))
|
|
||||||
#else
|
|
||||||
# define PACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SMB_COM_CLOSE 0x04
|
|
||||||
#define SMB_COM_READ_ANDX 0x2e
|
|
||||||
#define SMB_COM_WRITE_ANDX 0x2f
|
|
||||||
#define SMB_COM_TREE_DISCONNECT 0x71
|
|
||||||
#define SMB_COM_NEGOTIATE 0x72
|
|
||||||
#define SMB_COM_SETUP_ANDX 0x73
|
|
||||||
#define SMB_COM_TREE_CONNECT_ANDX 0x75
|
|
||||||
#define SMB_COM_NT_CREATE_ANDX 0xa2
|
|
||||||
#define SMB_COM_NO_ANDX_COMMAND 0xff
|
|
||||||
|
|
||||||
#define SMB_WC_CLOSE 0x03
|
|
||||||
#define SMB_WC_READ_ANDX 0x0c
|
|
||||||
#define SMB_WC_WRITE_ANDX 0x0e
|
|
||||||
#define SMB_WC_SETUP_ANDX 0x0d
|
|
||||||
#define SMB_WC_TREE_CONNECT_ANDX 0x04
|
|
||||||
#define SMB_WC_NT_CREATE_ANDX 0x18
|
|
||||||
|
|
||||||
#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
|
|
||||||
#define SMB_FLAGS_CASELESS_PATHNAMES 0x08
|
|
||||||
#define SMB_FLAGS2_UNICODE_STRINGS 0x8000
|
|
||||||
#define SMB_FLAGS2_IS_LONG_NAME 0x0040
|
|
||||||
#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001
|
|
||||||
|
|
||||||
#define SMB_CAP_LARGE_FILES 0x08
|
|
||||||
#define SMB_GENERIC_WRITE 0x40000000
|
|
||||||
#define SMB_GENERIC_READ 0x80000000
|
|
||||||
#define SMB_FILE_SHARE_ALL 0x07
|
|
||||||
#define SMB_FILE_OPEN 0x01
|
|
||||||
#define SMB_FILE_OVERWRITE_IF 0x05
|
|
||||||
|
|
||||||
#define SMB_ERR_NOACCESS 0x00050001
|
|
||||||
|
|
||||||
struct smb_header {
|
|
||||||
unsigned char nbt_type;
|
|
||||||
unsigned char nbt_flags;
|
|
||||||
unsigned short nbt_length;
|
|
||||||
unsigned char magic[4];
|
|
||||||
unsigned char command;
|
|
||||||
unsigned int status;
|
|
||||||
unsigned char flags;
|
|
||||||
unsigned short flags2;
|
|
||||||
unsigned short pid_high;
|
|
||||||
unsigned char signature[8];
|
|
||||||
unsigned short pad;
|
|
||||||
unsigned short tid;
|
|
||||||
unsigned short pid;
|
|
||||||
unsigned short uid;
|
|
||||||
unsigned short mid;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_negotiate_response {
|
|
||||||
struct smb_header h;
|
|
||||||
unsigned char word_count;
|
|
||||||
unsigned short dialect_index;
|
|
||||||
unsigned char security_mode;
|
|
||||||
unsigned short max_mpx_count;
|
|
||||||
unsigned short max_number_vcs;
|
|
||||||
unsigned int max_buffer_size;
|
|
||||||
unsigned int max_raw_size;
|
|
||||||
unsigned int session_key;
|
|
||||||
unsigned int capabilities;
|
|
||||||
unsigned int system_time_low;
|
|
||||||
unsigned int system_time_high;
|
|
||||||
unsigned short server_time_zone;
|
|
||||||
unsigned char encryption_key_length;
|
|
||||||
unsigned short byte_count;
|
|
||||||
char bytes[1];
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct andx {
|
|
||||||
unsigned char command;
|
|
||||||
unsigned char pad;
|
|
||||||
unsigned short offset;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_setup {
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned short max_buffer_size;
|
|
||||||
unsigned short max_mpx_count;
|
|
||||||
unsigned short vc_number;
|
|
||||||
unsigned int session_key;
|
|
||||||
unsigned short lengths[2];
|
|
||||||
unsigned int pad;
|
|
||||||
unsigned int capabilities;
|
|
||||||
unsigned short byte_count;
|
|
||||||
char bytes[1024];
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_tree_connect {
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned short flags;
|
|
||||||
unsigned short pw_len;
|
|
||||||
unsigned short byte_count;
|
|
||||||
char bytes[1024];
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_nt_create {
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned char pad;
|
|
||||||
unsigned short name_length;
|
|
||||||
unsigned int flags;
|
|
||||||
unsigned int root_fid;
|
|
||||||
unsigned int access;
|
|
||||||
curl_off_t allocation_size;
|
|
||||||
unsigned int ext_file_attributes;
|
|
||||||
unsigned int share_access;
|
|
||||||
unsigned int create_disposition;
|
|
||||||
unsigned int create_options;
|
|
||||||
unsigned int impersonation_level;
|
|
||||||
unsigned char security_flags;
|
|
||||||
unsigned short byte_count;
|
|
||||||
char bytes[1024];
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_nt_create_response {
|
|
||||||
struct smb_header h;
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned char op_lock_level;
|
|
||||||
unsigned short fid;
|
|
||||||
unsigned int create_disposition;
|
|
||||||
|
|
||||||
curl_off_t create_time;
|
|
||||||
curl_off_t last_access_time;
|
|
||||||
curl_off_t last_write_time;
|
|
||||||
curl_off_t last_change_time;
|
|
||||||
unsigned int ext_file_attributes;
|
|
||||||
curl_off_t allocation_size;
|
|
||||||
curl_off_t end_of_file;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_read {
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned short fid;
|
|
||||||
unsigned int offset;
|
|
||||||
unsigned short max_bytes;
|
|
||||||
unsigned short min_bytes;
|
|
||||||
unsigned int timeout;
|
|
||||||
unsigned short remaining;
|
|
||||||
unsigned int offset_high;
|
|
||||||
unsigned short byte_count;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_write {
|
|
||||||
struct smb_header h;
|
|
||||||
unsigned char word_count;
|
|
||||||
struct andx andx;
|
|
||||||
unsigned short fid;
|
|
||||||
unsigned int offset;
|
|
||||||
unsigned int timeout;
|
|
||||||
unsigned short write_mode;
|
|
||||||
unsigned short remaining;
|
|
||||||
unsigned short pad;
|
|
||||||
unsigned short data_length;
|
|
||||||
unsigned short data_offset;
|
|
||||||
unsigned int offset_high;
|
|
||||||
unsigned short byte_count;
|
|
||||||
unsigned char pad2;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_close {
|
|
||||||
unsigned char word_count;
|
|
||||||
unsigned short fid;
|
|
||||||
unsigned int last_mtime;
|
|
||||||
unsigned short byte_count;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
struct smb_tree_disconnect {
|
|
||||||
unsigned char word_count;
|
|
||||||
unsigned short byte_count;
|
|
||||||
} PACK;
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__ILEC400__)
|
|
||||||
# pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BUILDING_CURL_SMB_C */
|
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
|
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \
|
||||||
(SIZEOF_CURL_OFF_T > 4)
|
(SIZEOF_CURL_OFF_T > 4)
|
||||||
|
|
||||||
|
|
44
lib/smtp.c
44
lib/smtp.c
|
@ -281,11 +281,11 @@ static CURLcode smtp_get_message(struct Curl_easy *data, struct bufref *out)
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* smtp_state()
|
||||||
*
|
*
|
||||||
* This is the ONLY way to change SMTP state!
|
* This is the ONLY way to change SMTP state!
|
||||||
*/
|
*/
|
||||||
static void state(struct Curl_easy *data, smtpstate newstate)
|
static void smtp_state(struct Curl_easy *data, smtpstate newstate)
|
||||||
{
|
{
|
||||||
struct smtp_conn *smtpc = &data->conn->proto.smtpc;
|
struct smtp_conn *smtpc = &data->conn->proto.smtpc;
|
||||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
|
@ -338,7 +338,7 @@ static CURLcode smtp_perform_ehlo(struct Curl_easy *data)
|
||||||
result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain);
|
result = Curl_pp_sendf(data, &smtpc->pp, "EHLO %s", smtpc->domain);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_EHLO);
|
smtp_state(data, SMTP_EHLO);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ static CURLcode smtp_perform_helo(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain);
|
result = Curl_pp_sendf(data, &smtpc->pp, "HELO %s", smtpc->domain);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_HELO);
|
smtp_state(data, SMTP_HELO);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ static CURLcode smtp_perform_starttls(struct Curl_easy *data,
|
||||||
"%s", "STARTTLS");
|
"%s", "STARTTLS");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_STARTTLS);
|
smtp_state(data, SMTP_STARTTLS);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -410,7 +410,7 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data)
|
||||||
if(!result) {
|
if(!result) {
|
||||||
smtpc->ssldone = ssldone;
|
smtpc->ssldone = ssldone;
|
||||||
if(smtpc->state != SMTP_UPGRADETLS)
|
if(smtpc->state != SMTP_UPGRADETLS)
|
||||||
state(data, SMTP_UPGRADETLS);
|
smtp_state(data, SMTP_UPGRADETLS);
|
||||||
|
|
||||||
if(smtpc->ssldone) {
|
if(smtpc->ssldone) {
|
||||||
smtp_to_smtps(conn);
|
smtp_to_smtps(conn);
|
||||||
|
@ -499,7 +499,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
|
||||||
server supports authentication, and end the connect phase if not */
|
server supports authentication, and end the connect phase if not */
|
||||||
if(!smtpc->auth_supported ||
|
if(!smtpc->auth_supported ||
|
||||||
!Curl_sasl_can_authenticate(&smtpc->sasl, data)) {
|
!Curl_sasl_can_authenticate(&smtpc->sasl, data)) {
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data)
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
if(progress == SASL_INPROGRESS)
|
if(progress == SASL_INPROGRESS)
|
||||||
state(data, SMTP_AUTH);
|
smtp_state(data, SMTP_AUTH);
|
||||||
else {
|
else {
|
||||||
/* Other mechanisms not supported */
|
/* Other mechanisms not supported */
|
||||||
infof(data, "No known authentication mechanisms supported");
|
infof(data, "No known authentication mechanisms supported");
|
||||||
|
@ -586,7 +586,7 @@ static CURLcode smtp_perform_command(struct Curl_easy *data)
|
||||||
smtp->custom : "HELP");
|
smtp->custom : "HELP");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_COMMAND);
|
smtp_state(data, SMTP_COMMAND);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -771,7 +771,7 @@ static CURLcode smtp_perform_mail(struct Curl_easy *data)
|
||||||
free(size);
|
free(size);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_MAIL);
|
smtp_state(data, SMTP_MAIL);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -812,7 +812,7 @@ static CURLcode smtp_perform_rcpt_to(struct Curl_easy *data)
|
||||||
free(address);
|
free(address);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_RCPT);
|
smtp_state(data, SMTP_RCPT);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -830,7 +830,7 @@ static CURLcode smtp_perform_quit(struct Curl_easy *data,
|
||||||
CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "QUIT");
|
CURLcode result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "QUIT");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_QUIT);
|
smtp_state(data, SMTP_QUIT);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -996,7 +996,7 @@ static CURLcode smtp_state_helo_resp(struct Curl_easy *data, int smtpcode,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of connect phase */
|
/* End of connect phase */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1017,7 @@ static CURLcode smtp_state_auth_resp(struct Curl_easy *data,
|
||||||
if(!result)
|
if(!result)
|
||||||
switch(progress) {
|
switch(progress) {
|
||||||
case SASL_DONE:
|
case SASL_DONE:
|
||||||
state(data, SMTP_STOP); /* Authenticated */
|
smtp_state(data, SMTP_STOP); /* Authenticated */
|
||||||
break;
|
break;
|
||||||
case SASL_IDLE: /* No mechanism left after cancellation */
|
case SASL_IDLE: /* No mechanism left after cancellation */
|
||||||
failf(data, "Authentication cancelled");
|
failf(data, "Authentication cancelled");
|
||||||
|
@ -1064,11 +1064,11 @@ static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,7 +1145,7 @@ static CURLcode smtp_state_rcpt_resp(struct Curl_easy *data,
|
||||||
result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "DATA");
|
result = Curl_pp_sendf(data, &conn->proto.smtpc.pp, "%s", "DATA");
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(data, SMTP_DATA);
|
smtp_state(data, SMTP_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1172,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data, int smtpcode,
|
||||||
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
|
||||||
|
|
||||||
/* End of DO phase */
|
/* End of DO phase */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1192,7 +1192,7 @@ static CURLcode smtp_state_postdata_resp(struct Curl_easy *data,
|
||||||
result = CURLE_WEIRD_SERVER_REPLY;
|
result = CURLE_WEIRD_SERVER_REPLY;
|
||||||
|
|
||||||
/* End of DONE phase */
|
/* End of DONE phase */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1274,7 +1274,7 @@ static CURLcode smtp_statemachine(struct Curl_easy *data,
|
||||||
/* fallthrough, just stop! */
|
/* fallthrough, just stop! */
|
||||||
default:
|
default:
|
||||||
/* internal error */
|
/* internal error */
|
||||||
state(data, SMTP_STOP);
|
smtp_state(data, SMTP_STOP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
|
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
|
||||||
|
@ -1379,7 +1379,7 @@ static CURLcode smtp_connect(struct Curl_easy *data, bool *done)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* Start off waiting for the server greeting response */
|
/* Start off waiting for the server greeting response */
|
||||||
state(data, SMTP_SERVERGREET);
|
smtp_state(data, SMTP_SERVERGREET);
|
||||||
|
|
||||||
result = smtp_multi_statemach(data, done);
|
result = smtp_multi_statemach(data, done);
|
||||||
|
|
||||||
|
@ -1461,7 +1461,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
|
||||||
free(eob);
|
free(eob);
|
||||||
}
|
}
|
||||||
|
|
||||||
state(data, SMTP_POSTDATA);
|
smtp_state(data, SMTP_POSTDATA);
|
||||||
|
|
||||||
/* Run the state-machine */
|
/* Run the state-machine */
|
||||||
result = smtp_block_statemach(data, conn, FALSE);
|
result = smtp_block_statemach(data, conn, FALSE);
|
||||||
|
|
|
@ -161,7 +161,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
|
||||||
enum connect_t oldstate = sx->state;
|
enum connect_t oldstate = sx->state;
|
||||||
#ifdef DEBUG_AND_VERBOSE
|
#ifdef DEBUG_AND_VERBOSE
|
||||||
/* synced with the state list in urldata.h */
|
/* synced with the state list in urldata.h */
|
||||||
static const char * const statename[] = {
|
static const char * const socks_statename[] = {
|
||||||
"INIT",
|
"INIT",
|
||||||
"SOCKS_INIT",
|
"SOCKS_INIT",
|
||||||
"SOCKS_SEND",
|
"SOCKS_SEND",
|
||||||
|
@ -193,7 +193,7 @@ static void socksstate(struct socks_state *sx, struct Curl_easy *data,
|
||||||
#ifdef DEBUG_AND_VERBOSE
|
#ifdef DEBUG_AND_VERBOSE
|
||||||
infof(data,
|
infof(data,
|
||||||
"SXSTATE: %s => %s; line %d",
|
"SXSTATE: %s => %s; line %d",
|
||||||
statename[oldstate], statename[sx->state],
|
socks_statename[oldstate], socks_statename[sx->state],
|
||||||
lineno);
|
lineno);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,7 +300,7 @@ char *curl_version(void)
|
||||||
protocol line has its own #if line to make things easier on the eye.
|
protocol line has its own #if line to make things easier on the eye.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char * const protocols[] = {
|
static const char * const supported_protocols[] = {
|
||||||
#ifndef CURL_DISABLE_DICT
|
#ifndef CURL_DISABLE_DICT
|
||||||
"dict",
|
"dict",
|
||||||
#endif
|
#endif
|
||||||
|
@ -535,7 +535,7 @@ static curl_version_info_data version_info = {
|
||||||
NULL, /* ssl_version */
|
NULL, /* ssl_version */
|
||||||
0, /* ssl_version_num, this is kept at zero */
|
0, /* ssl_version_num, this is kept at zero */
|
||||||
NULL, /* zlib_version */
|
NULL, /* zlib_version */
|
||||||
protocols,
|
supported_protocols,
|
||||||
NULL, /* c-ares version */
|
NULL, /* c-ares version */
|
||||||
0, /* c-ares version numerical */
|
0, /* c-ares version numerical */
|
||||||
NULL, /* libidn version */
|
NULL, /* libidn version */
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct cf_msh3_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How to access `call_data` from a cf_msh3 filter */
|
/* How to access `call_data` from a cf_msh3 filter */
|
||||||
|
#undef CF_CTX_CALL_DATA
|
||||||
#define CF_CTX_CALL_DATA(cf) \
|
#define CF_CTX_CALL_DATA(cf) \
|
||||||
((struct cf_msh3_ctx *)(cf)->ctx)->call_data
|
((struct cf_msh3_ctx *)(cf)->ctx)->call_data
|
||||||
|
|
||||||
|
|
|
@ -165,13 +165,14 @@ struct cf_ngtcp2_ctx {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How to access `call_data` from a cf_ngtcp2 filter */
|
/* How to access `call_data` from a cf_ngtcp2 filter */
|
||||||
|
#undef CF_CTX_CALL_DATA
|
||||||
#define CF_CTX_CALL_DATA(cf) \
|
#define CF_CTX_CALL_DATA(cf) \
|
||||||
((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
|
((struct cf_ngtcp2_ctx *)(cf)->ctx)->call_data
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All about the H3 internals of a stream
|
* All about the H3 internals of a stream
|
||||||
*/
|
*/
|
||||||
struct stream_ctx {
|
struct h3_stream_ctx {
|
||||||
int64_t id; /* HTTP/3 protocol identifier */
|
int64_t id; /* HTTP/3 protocol identifier */
|
||||||
struct bufq sendbuf; /* h3 request body */
|
struct bufq sendbuf; /* h3 request body */
|
||||||
struct bufq recvbuf; /* h3 response body */
|
struct bufq recvbuf; /* h3 response body */
|
||||||
|
@ -186,7 +187,7 @@ struct stream_ctx {
|
||||||
bool send_closed; /* stream is local closed */
|
bool send_closed; /* stream is local closed */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define H3_STREAM_CTX(d) ((struct stream_ctx *)(((d) && (d)->req.p.http)? \
|
#define H3_STREAM_CTX(d) ((struct h3_stream_ctx *)(((d) && (d)->req.p.http)? \
|
||||||
((struct HTTP *)(d)->req.p.http)->h3_ctx \
|
((struct HTTP *)(d)->req.p.http)->h3_ctx \
|
||||||
: NULL))
|
: NULL))
|
||||||
#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
|
#define H3_STREAM_LCTX(d) ((struct HTTP *)(d)->req.p.http)->h3_ctx
|
||||||
|
@ -197,7 +198,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
|
|
||||||
if(!data || !data->req.p.http) {
|
if(!data || !data->req.p.http) {
|
||||||
failf(data, "initialization failure, transfer not http initialized");
|
failf(data, "initialization failure, transfer not http initialized");
|
||||||
|
@ -229,7 +230,7 @@ static CURLcode h3_data_setup(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void h3_data_done(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
|
|
||||||
(void)cf;
|
(void)cf;
|
||||||
if(stream) {
|
if(stream) {
|
||||||
|
@ -686,7 +687,7 @@ static void report_consumed_data(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
size_t consumed)
|
size_t consumed)
|
||||||
{
|
{
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
|
|
||||||
if(!stream)
|
if(!stream)
|
||||||
|
@ -969,7 +970,7 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
struct SingleRequest *k = &data->req;
|
struct SingleRequest *k = &data->req;
|
||||||
int rv = GETSOCK_BLANK;
|
int rv = GETSOCK_BLANK;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
struct cf_call_data save;
|
struct cf_call_data save;
|
||||||
|
|
||||||
CF_DATA_SAVE(save, cf, data);
|
CF_DATA_SAVE(save, cf, data);
|
||||||
|
@ -991,10 +992,10 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drain_stream(struct Curl_cfilter *cf,
|
static void h3_drain_stream(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
unsigned char bits;
|
unsigned char bits;
|
||||||
|
|
||||||
(void)cf;
|
(void)cf;
|
||||||
|
@ -1013,7 +1014,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = user_data;
|
struct Curl_cfilter *cf = user_data;
|
||||||
struct Curl_easy *data = stream_user_data;
|
struct Curl_easy *data = stream_user_data;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)stream_id;
|
(void)stream_id;
|
||||||
(void)app_error_code;
|
(void)app_error_code;
|
||||||
|
@ -1031,7 +1032,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
|
||||||
stream->reset = TRUE;
|
stream->reset = TRUE;
|
||||||
stream->send_closed = TRUE;
|
stream->send_closed = TRUE;
|
||||||
}
|
}
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,7 +1046,7 @@ static CURLcode write_resp_raw(struct Curl_cfilter *cf,
|
||||||
const void *mem, size_t memlen,
|
const void *mem, size_t memlen,
|
||||||
bool flow)
|
bool flow)
|
||||||
{
|
{
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
|
|
||||||
|
@ -1085,7 +1086,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
|
||||||
(void)stream3_id;
|
(void)stream3_id;
|
||||||
|
|
||||||
result = write_resp_raw(cf, data, buf, buflen, TRUE);
|
result = write_resp_raw(cf, data, buf, buflen, TRUE);
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
return result? -1 : 0;
|
return result? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,7 +1111,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = user_data;
|
struct Curl_cfilter *cf = user_data;
|
||||||
struct Curl_easy *data = stream_user_data;
|
struct Curl_easy *data = stream_user_data;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)stream_id;
|
(void)stream_id;
|
||||||
|
@ -1130,7 +1131,7 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id,
|
||||||
if(stream->status_code / 100 != 1) {
|
if(stream->status_code / 100 != 1) {
|
||||||
stream->resp_hds_complete = TRUE;
|
stream->resp_hds_complete = TRUE;
|
||||||
}
|
}
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,7 +1144,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id,
|
||||||
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
|
nghttp3_vec h3name = nghttp3_rcbuf_get_buf(name);
|
||||||
nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
|
nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value);
|
||||||
struct Curl_easy *data = stream_user_data;
|
struct Curl_easy *data = stream_user_data;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
(void)conn;
|
(void)conn;
|
||||||
(void)stream_id;
|
(void)stream_id;
|
||||||
|
@ -1314,7 +1315,7 @@ fail:
|
||||||
|
|
||||||
static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
|
static ssize_t recv_closed_stream(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
struct stream_ctx *stream,
|
struct h3_stream_ctx *stream,
|
||||||
CURLcode *err)
|
CURLcode *err)
|
||||||
{
|
{
|
||||||
ssize_t nread = -1;
|
ssize_t nread = -1;
|
||||||
|
@ -1364,7 +1365,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
char *buf, size_t len, CURLcode *err)
|
char *buf, size_t len, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
ssize_t nread = -1;
|
ssize_t nread = -1;
|
||||||
struct cf_call_data save;
|
struct cf_call_data save;
|
||||||
|
|
||||||
|
@ -1410,7 +1411,7 @@ static ssize_t cf_ngtcp2_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nread > 0) {
|
if(nread > 0) {
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(stream->closed) {
|
if(stream->closed) {
|
||||||
|
@ -1438,7 +1439,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = user_data;
|
struct Curl_cfilter *cf = user_data;
|
||||||
struct Curl_easy *data = stream_user_data;
|
struct Curl_easy *data = stream_user_data;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
size_t skiplen;
|
size_t skiplen;
|
||||||
|
|
||||||
(void)cf;
|
(void)cf;
|
||||||
|
@ -1465,7 +1466,7 @@ static int cb_h3_acked_req_body(nghttp3_conn *conn, int64_t stream_id,
|
||||||
if((data->req.keepon & KEEP_SEND_HOLD) &&
|
if((data->req.keepon & KEEP_SEND_HOLD) &&
|
||||||
(data->req.keepon & KEEP_SEND)) {
|
(data->req.keepon & KEEP_SEND)) {
|
||||||
data->req.keepon &= ~KEEP_SEND_HOLD;
|
data->req.keepon &= ~KEEP_SEND_HOLD;
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] unpausing acks",
|
DEBUGF(LOG_CF(data, cf, "[h3sid=%" PRId64 "] unpausing acks",
|
||||||
stream_id));
|
stream_id));
|
||||||
}
|
}
|
||||||
|
@ -1481,7 +1482,7 @@ cb_h3_read_req_body(nghttp3_conn *conn, int64_t stream_id,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = user_data;
|
struct Curl_cfilter *cf = user_data;
|
||||||
struct Curl_easy *data = stream_user_data;
|
struct Curl_easy *data = stream_user_data;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
ssize_t nwritten = 0;
|
ssize_t nwritten = 0;
|
||||||
size_t nvecs = 0;
|
size_t nvecs = 0;
|
||||||
(void)cf;
|
(void)cf;
|
||||||
|
@ -1547,7 +1548,7 @@ static ssize_t h3_stream_open(struct Curl_cfilter *cf,
|
||||||
CURLcode *err)
|
CURLcode *err)
|
||||||
{
|
{
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
struct stream_ctx *stream = NULL;
|
struct h3_stream_ctx *stream = NULL;
|
||||||
struct h1_req_parser h1;
|
struct h1_req_parser h1;
|
||||||
struct dynhds h2_headers;
|
struct dynhds h2_headers;
|
||||||
size_t nheader;
|
size_t nheader;
|
||||||
|
@ -1658,7 +1659,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
const void *buf, size_t len, CURLcode *err)
|
const void *buf, size_t len, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
ssize_t sent = 0;
|
ssize_t sent = 0;
|
||||||
struct cf_call_data save;
|
struct cf_call_data save;
|
||||||
|
|
||||||
|
@ -2101,7 +2102,7 @@ out:
|
||||||
static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
|
static bool cf_ngtcp2_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
const struct stream_ctx *stream = H3_STREAM_CTX(data);
|
const struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
(void)cf;
|
(void)cf;
|
||||||
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
|
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
|
||||||
}
|
}
|
||||||
|
@ -2113,7 +2114,7 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
|
||||||
/* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
|
/* TODO: there seems right now no API in ngtcp2 to shrink/enlarge
|
||||||
* the streams windows. As we do in HTTP/2. */
|
* the streams windows. As we do in HTTP/2. */
|
||||||
if(!pause) {
|
if(!pause) {
|
||||||
drain_stream(cf, data);
|
h3_drain_stream(cf, data);
|
||||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
@ -2141,7 +2142,7 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CF_CTRL_DATA_DONE_SEND: {
|
case CF_CTRL_DATA_DONE_SEND: {
|
||||||
struct stream_ctx *stream = H3_STREAM_CTX(data);
|
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||||
if(stream && !stream->send_closed) {
|
if(stream && !stream->send_closed) {
|
||||||
stream->send_closed = TRUE;
|
stream->send_closed = TRUE;
|
||||||
stream->upload_left = Curl_bufq_len(&stream->sendbuf);
|
stream->upload_left = Curl_bufq_len(&stream->sendbuf);
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct x509_context {
|
||||||
int cert_num;
|
int cert_num;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct bearssl_ssl_backend_data {
|
||||||
br_ssl_client_context ctx;
|
br_ssl_client_context ctx;
|
||||||
struct x509_context x509;
|
struct x509_context x509;
|
||||||
unsigned char buf[BR_SSL_BUFSIZE_BIDI];
|
unsigned char buf[BR_SSL_BUFSIZE_BIDI];
|
||||||
|
@ -574,7 +574,8 @@ static CURLcode bearssl_connect_step1(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
|
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
|
||||||
|
@ -751,7 +752,8 @@ static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
|
||||||
unsigned target)
|
unsigned target)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
unsigned state;
|
unsigned state;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -820,7 +822,8 @@ static CURLcode bearssl_connect_step2(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
CURLcode ret;
|
CURLcode ret;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -842,7 +845,8 @@ static CURLcode bearssl_connect_step3(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
CURLcode ret;
|
CURLcode ret;
|
||||||
|
|
||||||
|
@ -889,7 +893,8 @@ static ssize_t bearssl_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
const void *buf, size_t len, CURLcode *err)
|
const void *buf, size_t len, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
unsigned char *app;
|
unsigned char *app;
|
||||||
size_t applen;
|
size_t applen;
|
||||||
|
|
||||||
|
@ -923,7 +928,8 @@ static ssize_t bearssl_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
char *buf, size_t len, CURLcode *err)
|
char *buf, size_t len, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
unsigned char *app;
|
unsigned char *app;
|
||||||
size_t applen;
|
size_t applen;
|
||||||
|
|
||||||
|
@ -1050,10 +1056,12 @@ static bool bearssl_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct bearssl_ssl_backend_data *backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
return br_ssl_engine_current_state(&ctx->backend->ctx.eng) & BR_SSL_RECVAPP;
|
backend = (struct bearssl_ssl_backend_data *)ctx->backend;
|
||||||
|
return br_ssl_engine_current_state(&backend->ctx.eng) & BR_SSL_RECVAPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
|
static CURLcode bearssl_random(struct Curl_easy *data UNUSED_PARAM,
|
||||||
|
@ -1101,7 +1109,8 @@ static CURLcode bearssl_connect_nonblocking(struct Curl_cfilter *cf,
|
||||||
static void *bearssl_get_internals(struct ssl_connect_data *connssl,
|
static void *bearssl_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return &backend->ctx;
|
return &backend->ctx;
|
||||||
}
|
}
|
||||||
|
@ -1109,7 +1118,8 @@ static void *bearssl_get_internals(struct ssl_connect_data *connssl,
|
||||||
static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void bearssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct bearssl_ssl_backend_data *backend =
|
||||||
|
(struct bearssl_ssl_backend_data *)connssl->backend;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -1147,7 +1157,7 @@ static CURLcode bearssl_sha256sum(const unsigned char *input,
|
||||||
const struct Curl_ssl Curl_ssl_bearssl = {
|
const struct Curl_ssl Curl_ssl_bearssl = {
|
||||||
{ CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
|
{ CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */
|
||||||
SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_CAINFO_BLOB | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY,
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct bearssl_ssl_backend_data),
|
||||||
|
|
||||||
Curl_none_init, /* init */
|
Curl_none_init, /* init */
|
||||||
Curl_none_cleanup, /* cleanup */
|
Curl_none_cleanup, /* cleanup */
|
||||||
|
|
|
@ -103,14 +103,14 @@
|
||||||
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
|
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
|
||||||
#define CURL_GSKPROTO_LAST 5
|
#define CURL_GSKPROTO_LAST 5
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct gskit_ssl_backend_data {
|
||||||
gsk_handle handle;
|
gsk_handle handle;
|
||||||
int iocport;
|
int iocport;
|
||||||
int localfd;
|
int localfd;
|
||||||
int remotefd;
|
int remotefd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BACKEND connssl->backend
|
#define BACKEND ((struct gskit_ssl_backend_data *)connssl->backend)
|
||||||
|
|
||||||
/* Supported ciphers. */
|
/* Supported ciphers. */
|
||||||
struct gskit_cipher {
|
struct gskit_cipher {
|
||||||
|
@ -518,6 +518,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
|
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
|
||||||
struct ssl_connect_data *connssl_next = cf_ssl_next?
|
struct ssl_connect_data *connssl_next = cf_ssl_next?
|
||||||
cf_ssl_next->ctx : NULL;
|
cf_ssl_next->ctx : NULL;
|
||||||
|
struct gskit_ssl_backend_data *backend_next;
|
||||||
struct pollfd fds[2];
|
struct pollfd fds[2];
|
||||||
int n;
|
int n;
|
||||||
int m;
|
int m;
|
||||||
|
@ -531,6 +532,8 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
return 0; /* No SSL over SSL: OK. */
|
return 0; /* No SSL over SSL: OK. */
|
||||||
|
|
||||||
DEBUGASSERT(connssl_next->backend);
|
DEBUGASSERT(connssl_next->backend);
|
||||||
|
backend_next = (struct gskit_ssl_backend_data *)connssl_next->backend;
|
||||||
|
|
||||||
n = 1;
|
n = 1;
|
||||||
fds[0].fd = BACKEND->remotefd;
|
fds[0].fd = BACKEND->remotefd;
|
||||||
fds[1].fd = Curl_conn_cf_get_socket(cf, data);
|
fds[1].fd = Curl_conn_cf_get_socket(cf, data);
|
||||||
|
@ -550,8 +553,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
if(fds[0].revents & POLLOUT) {
|
if(fds[0].revents & POLLOUT) {
|
||||||
/* Try getting data from HTTPS proxy and pipe it upstream. */
|
/* Try getting data from HTTPS proxy and pipe it upstream. */
|
||||||
n = 0;
|
n = 0;
|
||||||
i = gsk_secure_soc_read(connssl_next->backend->handle,
|
i = gsk_secure_soc_read(backend_next->handle, buf, sizeof(buf), &n);
|
||||||
buf, sizeof(buf), &n);
|
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case GSK_OK:
|
case GSK_OK:
|
||||||
if(n) {
|
if(n) {
|
||||||
|
@ -575,7 +577,7 @@ static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(n) {
|
if(n) {
|
||||||
i = gsk_secure_soc_write(connssl_next->backend->handle, buf, n, &m);
|
i = gsk_secure_soc_write(backend_next->handle, buf, n, &m);
|
||||||
if(i != GSK_OK || n != m)
|
if(i != GSK_OK || n != m)
|
||||||
return -1;
|
return -1;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -1294,7 +1296,7 @@ const struct Curl_ssl Curl_ssl_gskit = {
|
||||||
SSLSUPP_CERTINFO |
|
SSLSUPP_CERTINFO |
|
||||||
SSLSUPP_PINNEDPUBKEY,
|
SSLSUPP_PINNEDPUBKEY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct gskit_ssl_backend_data),
|
||||||
|
|
||||||
gskit_init, /* init */
|
gskit_init, /* init */
|
||||||
gskit_cleanup, /* cleanup */
|
gskit_cleanup, /* cleanup */
|
||||||
|
|
|
@ -76,7 +76,7 @@ static bool gtls_inited = FALSE;
|
||||||
|
|
||||||
# include <gnutls/ocsp.h>
|
# include <gnutls/ocsp.h>
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct gtls_ssl_backend_data {
|
||||||
struct gtls_instance gtls;
|
struct gtls_instance gtls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,7 +91,9 @@ static ssize_t gtls_push(void *s, const void *buf, size_t blen)
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
|
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
|
||||||
if(nwritten < 0) {
|
if(nwritten < 0) {
|
||||||
gnutls_transport_set_errno(connssl->backend->gtls.session,
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
|
gnutls_transport_set_errno(backend->gtls.session,
|
||||||
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
|
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
|
||||||
nwritten = -1;
|
nwritten = -1;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,9 @@ static ssize_t gtls_pull(void *s, void *buf, size_t blen)
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
|
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
|
||||||
if(nread < 0) {
|
if(nread < 0) {
|
||||||
gnutls_transport_set_errno(connssl->backend->gtls.session,
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
|
gnutls_transport_set_errno(backend->gtls.session,
|
||||||
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
|
(CURLE_AGAIN == result)? EAGAIN : EINVAL);
|
||||||
nread = -1;
|
nread = -1;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +216,8 @@ static CURLcode handshake(struct Curl_cfilter *cf,
|
||||||
bool nonblocking)
|
bool nonblocking)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
gnutls_session_t session;
|
gnutls_session_t session;
|
||||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||||
|
|
||||||
|
@ -679,7 +684,8 @@ static CURLcode
|
||||||
gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
gtls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
long * const pverifyresult = &ssl_config->certverifyresult;
|
long * const pverifyresult = &ssl_config->certverifyresult;
|
||||||
|
@ -1346,7 +1352,8 @@ gtls_connect_common(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
/* Finish connecting once the handshake is done */
|
/* Finish connecting once the handshake is done */
|
||||||
if(ssl_connect_1 == connssl->connecting_state) {
|
if(ssl_connect_1 == connssl->connecting_state) {
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
gnutls_session_t session;
|
gnutls_session_t session;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
session = backend->gtls.session;
|
session = backend->gtls.session;
|
||||||
|
@ -1390,11 +1397,13 @@ static bool gtls_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct gtls_ssl_backend_data *backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
if(ctx->backend->gtls.session &&
|
backend = (struct gtls_ssl_backend_data *)ctx->backend;
|
||||||
0 != gnutls_record_check_pending(ctx->backend->gtls.session))
|
if(backend->gtls.session &&
|
||||||
|
0 != gnutls_record_check_pending(backend->gtls.session))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1406,7 +1415,8 @@ static ssize_t gtls_send(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -1428,7 +1438,8 @@ static void gtls_close(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void) data;
|
(void) data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -1463,7 +1474,8 @@ static int gtls_shutdown(struct Curl_cfilter *cf,
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -1541,7 +1553,8 @@ static ssize_t gtls_recv(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -1620,7 +1633,8 @@ static bool gtls_cert_status_request(void)
|
||||||
static void *gtls_get_internals(struct ssl_connect_data *connssl,
|
static void *gtls_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct gtls_ssl_backend_data *backend =
|
||||||
|
(struct gtls_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return backend->gtls.session;
|
return backend->gtls.session;
|
||||||
|
@ -1634,7 +1648,7 @@ const struct Curl_ssl Curl_ssl_gnutls = {
|
||||||
SSLSUPP_PINNEDPUBKEY |
|
SSLSUPP_PINNEDPUBKEY |
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct gtls_ssl_backend_data),
|
||||||
|
|
||||||
gtls_init, /* init */
|
gtls_init, /* init */
|
||||||
gtls_cleanup, /* cleanup */
|
gtls_cleanup, /* cleanup */
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct mbed_ssl_backend_data {
|
||||||
mbedtls_ctr_drbg_context ctr_drbg;
|
mbedtls_ctr_drbg_context ctr_drbg;
|
||||||
mbedtls_entropy_context entropy;
|
mbedtls_entropy_context entropy;
|
||||||
mbedtls_ssl_context ssl;
|
mbedtls_ssl_context ssl;
|
||||||
|
@ -255,7 +255,8 @@ static CURLcode
|
||||||
set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data)
|
set_ssl_version_min_max(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
|
||||||
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3;
|
int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||||
|
@ -307,7 +308,8 @@ static CURLcode
|
||||||
mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
|
const struct curl_blob *ca_info_blob = conn_config->ca_info_blob;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
|
@ -697,7 +699,8 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
const mbedtls_x509_crt *peercert;
|
const mbedtls_x509_crt *peercert;
|
||||||
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
|
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
|
||||||
|
@ -860,7 +863,8 @@ mbed_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
CURLcode retcode = CURLE_OK;
|
CURLcode retcode = CURLE_OK;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
|
|
||||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||||
|
@ -915,7 +919,8 @@ static ssize_t mbed_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -939,7 +944,8 @@ static void mbedtls_close_all(struct Curl_easy *data)
|
||||||
static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void mbedtls_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -968,7 +974,8 @@ static ssize_t mbed_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
ssize_t len = -1;
|
ssize_t len = -1;
|
||||||
|
|
||||||
|
@ -1204,10 +1211,12 @@ static bool mbedtls_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct mbed_ssl_backend_data *backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
return mbedtls_ssl_get_bytes_avail(&ctx->backend->ssl) != 0;
|
backend = (struct mbed_ssl_backend_data *)ctx->backend;
|
||||||
|
return mbedtls_ssl_get_bytes_avail(&backend->ssl) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode mbedtls_sha256sum(const unsigned char *input,
|
static CURLcode mbedtls_sha256sum(const unsigned char *input,
|
||||||
|
@ -1234,7 +1243,8 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input,
|
||||||
static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
|
static void *mbedtls_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct mbed_ssl_backend_data *backend =
|
||||||
|
(struct mbed_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return &backend->ssl;
|
return &backend->ssl;
|
||||||
|
@ -1249,7 +1259,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
|
||||||
SSLSUPP_SSL_CTX |
|
SSLSUPP_SSL_CTX |
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct mbed_ssl_backend_data),
|
||||||
|
|
||||||
mbedtls_init, /* init */
|
mbedtls_init, /* init */
|
||||||
mbedtls_cleanup, /* cleanup */
|
mbedtls_cleanup, /* cleanup */
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
/* enough to fit the string "PEM Token #[0|1]" */
|
/* enough to fit the string "PEM Token #[0|1]" */
|
||||||
#define SLOTSIZE 13
|
#define SLOTSIZE 13
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct nss_ssl_backend_data {
|
||||||
PRFileDesc *handle;
|
PRFileDesc *handle;
|
||||||
char *client_nickname;
|
char *client_nickname;
|
||||||
struct Curl_easy *data;
|
struct Curl_easy *data;
|
||||||
|
@ -489,7 +489,8 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
|
||||||
|
|
||||||
const int slot_id = (cacert) ? 0 : 1;
|
const int slot_id = (cacert) ? 0 : 1;
|
||||||
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -806,7 +807,9 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
|
||||||
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct Curl_easy *data = connssl->backend->data;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
struct Curl_easy *data = backend->data;
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||||
|
@ -851,7 +854,9 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct Curl_easy *data = connssl->backend->data;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
struct Curl_easy *data = backend->data;
|
||||||
unsigned int buflenmax = 50;
|
unsigned int buflenmax = 50;
|
||||||
unsigned char buf[50];
|
unsigned char buf[50];
|
||||||
unsigned int buflen;
|
unsigned int buflen;
|
||||||
|
@ -1055,7 +1060,9 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
struct Curl_cfilter *cf = (struct Curl_cfilter *)arg;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct Curl_easy *data = connssl->backend->data;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
struct Curl_easy *data = backend->data;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config;
|
struct ssl_config_data *ssl_config;
|
||||||
PRErrorCode err = PR_GetError();
|
PRErrorCode err = PR_GetError();
|
||||||
|
@ -1117,7 +1124,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
|
||||||
const char *pinnedpubkey)
|
const char *pinnedpubkey)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = NULL;
|
struct Curl_easy *data = NULL;
|
||||||
CERTCertificate *cert;
|
CERTCertificate *cert;
|
||||||
|
|
||||||
|
@ -1173,7 +1181,8 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
||||||
struct SECKEYPrivateKeyStr **pRetKey)
|
struct SECKEYPrivateKeyStr **pRetKey)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = NULL;
|
struct Curl_easy *data = NULL;
|
||||||
const char *nickname = NULL;
|
const char *nickname = NULL;
|
||||||
static const char pem_slotname[] = "PEM Token #1";
|
static const char pem_slotname[] = "PEM Token #1";
|
||||||
|
@ -1538,7 +1547,8 @@ static void nss_cleanup(void)
|
||||||
static void close_one(struct ssl_connect_data *connssl)
|
static void close_one(struct ssl_connect_data *connssl)
|
||||||
{
|
{
|
||||||
/* before the cleanup, check whether we are using a client certificate */
|
/* before the cleanup, check whether we are using a client certificate */
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
bool client_cert = true;
|
bool client_cert = true;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -1580,7 +1590,8 @@ static void close_one(struct ssl_connect_data *connssl)
|
||||||
static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void nss_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -1796,7 +1807,8 @@ static CURLcode nss_fail_connect(struct Curl_cfilter *cf,
|
||||||
CURLcode curlerr)
|
CURLcode curlerr)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -1826,7 +1838,8 @@ static CURLcode nss_set_blocking(struct Curl_cfilter *cf,
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
PRSocketOptionData sock_opt;
|
PRSocketOptionData sock_opt;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -1849,7 +1862,8 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
|
||||||
PRBool ssl_cbc_random_iv;
|
PRBool ssl_cbc_random_iv;
|
||||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
|
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
|
||||||
|
@ -2031,14 +2045,16 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
|
||||||
/* Is there an SSL filter "in front" of us or are we writing directly
|
/* Is there an SSL filter "in front" of us or are we writing directly
|
||||||
* to the socket? */
|
* to the socket? */
|
||||||
if(connssl_next) {
|
if(connssl_next) {
|
||||||
|
struct nss_ssl_backend_data *backend_next =
|
||||||
|
(struct nss_ssl_backend_data *)connssl_next->backend;
|
||||||
/* The filter should be connected by now, with full handshake */
|
/* The filter should be connected by now, with full handshake */
|
||||||
DEBUGASSERT(connssl_next->backend->handle);
|
DEBUGASSERT(backend_next->handle);
|
||||||
DEBUGASSERT(ssl_connection_complete == connssl_next->state);
|
DEBUGASSERT(ssl_connection_complete == connssl_next->state);
|
||||||
/* We tell our NSS instance to use do IO with the 'next' NSS
|
/* We tell our NSS instance to use do IO with the 'next' NSS
|
||||||
* instance. This NSS instance will take ownership of the next
|
* instance. This NSS instance will take ownership of the next
|
||||||
* one, including its destruction. We therefore need to `disown`
|
* one, including its destruction. We therefore need to `disown`
|
||||||
* the next filter's handle, once import succeeds. */
|
* the next filter's handle, once import succeeds. */
|
||||||
nspr_io = connssl_next->backend->handle;
|
nspr_io = backend->handle;
|
||||||
second_layer = TRUE;
|
second_layer = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2077,8 +2093,11 @@ static CURLcode nss_setup_connect(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
PR_Close(model); /* We don't need this any more */
|
PR_Close(model); /* We don't need this any more */
|
||||||
model = NULL;
|
model = NULL;
|
||||||
if(connssl_next) /* steal the NSS handle we just imported successfully */
|
if(connssl_next) { /* steal the NSS handle we just imported successfully */
|
||||||
connssl_next->backend->handle = NULL;
|
struct nss_ssl_backend_data *backend_next =
|
||||||
|
(struct nss_ssl_backend_data *)connssl_next->backend;
|
||||||
|
backend_next->handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is the password associated with the cert that we're using */
|
/* This is the password associated with the cert that we're using */
|
||||||
if(ssl_config->key_passwd) {
|
if(ssl_config->key_passwd) {
|
||||||
|
@ -2154,7 +2173,8 @@ static CURLcode nss_do_connect(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
||||||
|
@ -2299,7 +2319,8 @@ static ssize_t nss_send(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -2337,7 +2358,9 @@ static bool
|
||||||
nss_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
|
nss_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
PRFileDesc *fd = connssl->backend->handle->lower;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
PRFileDesc *fd = backend->handle->lower;
|
||||||
char buf;
|
char buf;
|
||||||
|
|
||||||
(void) data;
|
(void) data;
|
||||||
|
@ -2353,7 +2376,8 @@ static ssize_t nss_recv(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -2455,7 +2479,8 @@ static bool nss_false_start(void)
|
||||||
static void *nss_get_internals(struct ssl_connect_data *connssl,
|
static void *nss_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return backend->handle;
|
return backend->handle;
|
||||||
|
@ -2465,9 +2490,11 @@ static bool nss_attach_data(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
if(!connssl->backend->data)
|
if(!backend->data)
|
||||||
connssl->backend->data = data;
|
backend->data = data;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2475,9 +2502,11 @@ static void nss_detach_data(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct nss_ssl_backend_data *backend =
|
||||||
|
(struct nss_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
if(connssl->backend->data == data)
|
if(backend->data == data)
|
||||||
connssl->backend->data = NULL;
|
backend->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct Curl_ssl Curl_ssl_nss = {
|
const struct Curl_ssl Curl_ssl_nss = {
|
||||||
|
@ -2488,7 +2517,7 @@ const struct Curl_ssl Curl_ssl_nss = {
|
||||||
SSLSUPP_PINNEDPUBKEY |
|
SSLSUPP_PINNEDPUBKEY |
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct nss_ssl_backend_data),
|
||||||
|
|
||||||
nss_init, /* init */
|
nss_init, /* init */
|
||||||
nss_cleanup, /* cleanup */
|
nss_cleanup, /* cleanup */
|
||||||
|
|
|
@ -288,7 +288,7 @@ typedef unsigned long sslerr_t;
|
||||||
#define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
#define USE_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||||
#endif /* !LIBRESSL_VERSION_NUMBER */
|
#endif /* !LIBRESSL_VERSION_NUMBER */
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct ossl_ssl_backend_data {
|
||||||
/* these ones requires specific SSL-types */
|
/* these ones requires specific SSL-types */
|
||||||
SSL_CTX* ctx;
|
SSL_CTX* ctx;
|
||||||
SSL* handle;
|
SSL* handle;
|
||||||
|
@ -714,6 +714,8 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = BIO_get_data(bio);
|
struct Curl_cfilter *cf = BIO_get_data(bio);
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
CURLcode result = CURLE_SEND_ERROR;
|
CURLcode result = CURLE_SEND_ERROR;
|
||||||
|
@ -723,7 +725,7 @@ static int bio_cf_out_write(BIO *bio, const char *buf, int blen)
|
||||||
DEBUGF(LOG_CF(data, cf, "bio_cf_out_write(len=%d) -> %d, err=%d",
|
DEBUGF(LOG_CF(data, cf, "bio_cf_out_write(len=%d) -> %d, err=%d",
|
||||||
blen, (int)nwritten, result));
|
blen, (int)nwritten, result));
|
||||||
BIO_clear_retry_flags(bio);
|
BIO_clear_retry_flags(bio);
|
||||||
connssl->backend->io_result = result;
|
backend->io_result = result;
|
||||||
if(nwritten < 0) {
|
if(nwritten < 0) {
|
||||||
if(CURLE_AGAIN == result)
|
if(CURLE_AGAIN == result)
|
||||||
BIO_set_retry_write(bio);
|
BIO_set_retry_write(bio);
|
||||||
|
@ -735,6 +737,8 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = BIO_get_data(bio);
|
struct Curl_cfilter *cf = BIO_get_data(bio);
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
CURLcode result = CURLE_RECV_ERROR;
|
CURLcode result = CURLE_RECV_ERROR;
|
||||||
|
@ -748,7 +752,7 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
|
||||||
DEBUGF(LOG_CF(data, cf, "bio_cf_in_read(len=%d) -> %d, err=%d",
|
DEBUGF(LOG_CF(data, cf, "bio_cf_in_read(len=%d) -> %d, err=%d",
|
||||||
blen, (int)nread, result));
|
blen, (int)nread, result));
|
||||||
BIO_clear_retry_flags(bio);
|
BIO_clear_retry_flags(bio);
|
||||||
connssl->backend->io_result = result;
|
backend->io_result = result;
|
||||||
if(nread < 0) {
|
if(nread < 0) {
|
||||||
if(CURLE_AGAIN == result)
|
if(CURLE_AGAIN == result)
|
||||||
BIO_set_retry_read(bio);
|
BIO_set_retry_read(bio);
|
||||||
|
@ -756,13 +760,13 @@ static int bio_cf_in_read(BIO *bio, char *buf, int blen)
|
||||||
|
|
||||||
/* Before returning server replies to the SSL instance, we need
|
/* Before returning server replies to the SSL instance, we need
|
||||||
* to have setup the x509 store or verification will fail. */
|
* to have setup the x509 store or verification will fail. */
|
||||||
if(!connssl->backend->x509_store_setup) {
|
if(!backend->x509_store_setup) {
|
||||||
result = Curl_ssl_setup_x509_store(cf, data, connssl->backend->ctx);
|
result = Curl_ssl_setup_x509_store(cf, data, backend->ctx);
|
||||||
if(result) {
|
if(result) {
|
||||||
connssl->backend->io_result = result;
|
backend->io_result = result;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
connssl->backend->x509_store_setup = TRUE;
|
backend->x509_store_setup = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)nread;
|
return (int)nread;
|
||||||
|
@ -1877,7 +1881,8 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data)
|
||||||
static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void ossl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -1923,7 +1928,8 @@ static int ossl_shutdown(struct Curl_cfilter *cf,
|
||||||
int buffsize;
|
int buffsize;
|
||||||
int err;
|
int err;
|
||||||
bool done = FALSE;
|
bool done = FALSE;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
int loop = 10;
|
int loop = 10;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -2321,7 +2327,8 @@ static CURLcode verifystatus(struct Curl_cfilter *cf,
|
||||||
OCSP_BASICRESP *br = NULL;
|
OCSP_BASICRESP *br = NULL;
|
||||||
X509_STORE *st = NULL;
|
X509_STORE *st = NULL;
|
||||||
STACK_OF(X509) *ch = NULL;
|
STACK_OF(X509) *ch = NULL;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
OCSP_CERTID *id = NULL;
|
OCSP_CERTID *id = NULL;
|
||||||
int cert_status, crl_reason;
|
int cert_status, crl_reason;
|
||||||
|
@ -2713,7 +2720,7 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
|
||||||
static CURLcode
|
static CURLcode
|
||||||
set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
|
ossl_set_ssl_version_min_max(struct Curl_cfilter *cf, SSL_CTX *ctx)
|
||||||
{
|
{
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
/* first, TLS min version... */
|
/* first, TLS min version... */
|
||||||
|
@ -2810,7 +2817,7 @@ typedef long ctx_option_t;
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
|
||||||
static CURLcode
|
static CURLcode
|
||||||
set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
|
ossl_set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
|
||||||
struct Curl_cfilter *cf,
|
struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
|
@ -2825,8 +2832,10 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
|
||||||
#ifdef TLS1_3_VERSION
|
#ifdef TLS1_3_VERSION
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
DEBUGASSERT(connssl->backend);
|
struct ossl_ssl_backend_data *backend =
|
||||||
SSL_CTX_set_max_proto_version(connssl->backend->ctx, TLS1_3_VERSION);
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
DEBUGASSERT(backend);
|
||||||
|
SSL_CTX_set_max_proto_version(backend->ctx, TLS1_3_VERSION);
|
||||||
*ctx_options |= SSL_OP_NO_TLSv1_2;
|
*ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -3431,7 +3440,8 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
|
||||||
const char * const ssl_cert_type = ssl_config->cert_type;
|
const char * const ssl_cert_type = ssl_config->cert_type;
|
||||||
const bool verifypeer = conn_config->verifypeer;
|
const bool verifypeer = conn_config->verifypeer;
|
||||||
char error_buffer[256];
|
char error_buffer[256];
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
|
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -3573,9 +3583,9 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf,
|
||||||
ctx_options |= SSL_OP_NO_SSLv3;
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
|
||||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
|
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
|
||||||
result = set_ssl_version_min_max(cf, backend->ctx);
|
result = ossl_set_ssl_version_min_max(cf, backend->ctx);
|
||||||
#else
|
#else
|
||||||
result = set_ssl_version_min_max_legacy(&ctx_options, cf, data);
|
result = ossl_set_ssl_version_min_max_legacy(&ctx_options, cf, data);
|
||||||
#endif
|
#endif
|
||||||
if(result != CURLE_OK)
|
if(result != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
|
@ -3804,7 +3814,8 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|
||||||
|| ssl_connect_2_reading == connssl->connecting_state
|
|| ssl_connect_2_reading == connssl->connecting_state
|
||||||
|
@ -3967,7 +3978,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
|
||||||
* Heavily modified from:
|
* Heavily modified from:
|
||||||
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
|
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
|
||||||
*/
|
*/
|
||||||
static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
|
static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
|
||||||
const char *pinnedpubkey)
|
const char *pinnedpubkey)
|
||||||
{
|
{
|
||||||
/* Scratch */
|
/* Scratch */
|
||||||
|
@ -4046,7 +4057,8 @@ static CURLcode servercert(struct Curl_cfilter *cf,
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
BIO *mem = BIO_new(BIO_s_mem());
|
BIO *mem = BIO_new(BIO_s_mem());
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -4061,7 +4073,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
|
||||||
|
|
||||||
if(data->set.ssl.certinfo)
|
if(data->set.ssl.certinfo)
|
||||||
/* asked to gather certificate info */
|
/* asked to gather certificate info */
|
||||||
(void)Curl_ossl_certchain(data, connssl->backend->handle);
|
(void)Curl_ossl_certchain(data, backend->handle);
|
||||||
|
|
||||||
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
|
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
|
||||||
if(!backend->server_cert) {
|
if(!backend->server_cert) {
|
||||||
|
@ -4229,7 +4241,7 @@ static CURLcode servercert(struct Curl_cfilter *cf,
|
||||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
||||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
||||||
if(!result && ptr) {
|
if(!result && ptr) {
|
||||||
result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
|
result = ossl_pkp_pin_peer_pubkey(data, backend->server_cert, ptr);
|
||||||
if(result)
|
if(result)
|
||||||
failf(data, "SSL: public key does not match pinned public key");
|
failf(data, "SSL: public key does not match pinned public key");
|
||||||
}
|
}
|
||||||
|
@ -4398,11 +4410,13 @@ static CURLcode ossl_connect(struct Curl_cfilter *cf,
|
||||||
static bool ossl_data_pending(struct Curl_cfilter *cf,
|
static bool ossl_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(connssl && backend);
|
||||||
if(ctx->backend->handle && SSL_pending(ctx->backend->handle))
|
if(backend->handle && SSL_pending(backend->handle))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -4421,7 +4435,8 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
|
||||||
int memlen;
|
int memlen;
|
||||||
int rc;
|
int rc;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -4517,7 +4532,8 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
|
||||||
int buffsize;
|
int buffsize;
|
||||||
struct connectdata *conn = cf->conn;
|
struct connectdata *conn = cf->conn;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
@ -4740,7 +4756,8 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info)
|
CURLINFO info)
|
||||||
{
|
{
|
||||||
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
|
/* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct ossl_ssl_backend_data *backend =
|
||||||
|
(struct ossl_ssl_backend_data *)connssl->backend;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return info == CURLINFO_TLS_SESSION ?
|
return info == CURLINFO_TLS_SESSION ?
|
||||||
(void *)backend->ctx : (void *)backend->handle;
|
(void *)backend->ctx : (void *)backend->handle;
|
||||||
|
@ -4773,7 +4790,7 @@ const struct Curl_ssl Curl_ssl_openssl = {
|
||||||
#endif
|
#endif
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct ossl_ssl_backend_data),
|
||||||
|
|
||||||
ossl_init, /* init */
|
ossl_init, /* init */
|
||||||
ossl_cleanup, /* cleanup */
|
ossl_cleanup, /* cleanup */
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
|
|
||||||
struct ssl_backend_data
|
struct rustls_ssl_backend_data
|
||||||
{
|
{
|
||||||
const struct rustls_client_config *config;
|
const struct rustls_client_config *config;
|
||||||
struct rustls_connection *conn;
|
struct rustls_connection *conn;
|
||||||
|
@ -67,10 +67,12 @@ static bool
|
||||||
cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
|
cr_data_pending(struct Curl_cfilter *cf, const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct rustls_ssl_backend_data *backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
return ctx->backend->data_pending;
|
backend = (struct rustls_ssl_backend_data *)ctx->backend;
|
||||||
|
return backend->data_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
|
@ -136,7 +138,8 @@ static ssize_t tls_recv_more(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data, CURLcode *err)
|
struct Curl_easy *data, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *const connssl = cf->ctx;
|
struct ssl_connect_data *const connssl = cf->ctx;
|
||||||
struct ssl_backend_data *const backend = connssl->backend;
|
struct rustls_ssl_backend_data *const backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
struct io_ctx io_ctx;
|
struct io_ctx io_ctx;
|
||||||
size_t tls_bytes_read = 0;
|
size_t tls_bytes_read = 0;
|
||||||
rustls_io_result io_error;
|
rustls_io_result io_error;
|
||||||
|
@ -191,7 +194,8 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
char *plainbuf, size_t plainlen, CURLcode *err)
|
char *plainbuf, size_t plainlen, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *const connssl = cf->ctx;
|
struct ssl_connect_data *const connssl = cf->ctx;
|
||||||
struct ssl_backend_data *const backend = connssl->backend;
|
struct rustls_ssl_backend_data *const backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
struct rustls_connection *rconn = NULL;
|
struct rustls_connection *rconn = NULL;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
size_t plain_bytes_copied = 0;
|
size_t plain_bytes_copied = 0;
|
||||||
|
@ -283,7 +287,8 @@ cr_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
const void *plainbuf, size_t plainlen, CURLcode *err)
|
const void *plainbuf, size_t plainlen, CURLcode *err)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *const connssl = cf->ctx;
|
struct ssl_connect_data *const connssl = cf->ctx;
|
||||||
struct ssl_backend_data *const backend = connssl->backend;
|
struct rustls_ssl_backend_data *const backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
struct rustls_connection *rconn = NULL;
|
struct rustls_connection *rconn = NULL;
|
||||||
struct io_ctx io_ctx;
|
struct io_ctx io_ctx;
|
||||||
size_t plainwritten = 0;
|
size_t plainwritten = 0;
|
||||||
|
@ -373,7 +378,7 @@ cr_hostname_is_ip(const char *hostname)
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
|
cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
struct ssl_backend_data *const backend)
|
struct rustls_ssl_backend_data *const backend)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
|
@ -491,7 +496,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *const connssl = cf->ctx;
|
struct ssl_connect_data *const connssl = cf->ctx;
|
||||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||||
struct ssl_backend_data *const backend = connssl->backend;
|
struct rustls_ssl_backend_data *const backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
struct rustls_connection *rconn = NULL;
|
struct rustls_connection *rconn = NULL;
|
||||||
CURLcode tmperr = CURLE_OK;
|
CURLcode tmperr = CURLE_OK;
|
||||||
int result;
|
int result;
|
||||||
|
@ -504,7 +510,8 @@ cr_connect_nonblocking(struct Curl_cfilter *cf,
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(ssl_connection_none == connssl->state) {
|
if(ssl_connection_none == connssl->state) {
|
||||||
result = cr_init_backend(cf, data, connssl->backend);
|
result = cr_init_backend(cf, data,
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend);
|
||||||
if(result != CURLE_OK) {
|
if(result != CURLE_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +601,8 @@ cr_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *const connssl = cf->ctx;
|
struct ssl_connect_data *const connssl = cf->ctx;
|
||||||
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
|
||||||
struct ssl_backend_data *const backend = connssl->backend;
|
struct rustls_ssl_backend_data *const backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
struct rustls_connection *rconn = NULL;
|
struct rustls_connection *rconn = NULL;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
@ -617,7 +625,8 @@ static void *
|
||||||
cr_get_internals(struct ssl_connect_data *connssl,
|
cr_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct rustls_ssl_backend_data *backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return &backend->conn;
|
return &backend->conn;
|
||||||
}
|
}
|
||||||
|
@ -626,7 +635,8 @@ static void
|
||||||
cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
cr_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct rustls_ssl_backend_data *backend =
|
||||||
|
(struct rustls_ssl_backend_data *)connssl->backend;
|
||||||
CURLcode tmperr = CURLE_OK;
|
CURLcode tmperr = CURLE_OK;
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
|
|
||||||
|
@ -659,7 +669,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
|
||||||
SSLSUPP_CAINFO_BLOB | /* supports */
|
SSLSUPP_CAINFO_BLOB | /* supports */
|
||||||
SSLSUPP_TLS13_CIPHERSUITES |
|
SSLSUPP_TLS13_CIPHERSUITES |
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct rustls_ssl_backend_data),
|
||||||
|
|
||||||
Curl_none_init, /* init */
|
Curl_none_init, /* init */
|
||||||
Curl_none_cleanup, /* cleanup */
|
Curl_none_cleanup, /* cleanup */
|
||||||
|
|
|
@ -33,13 +33,12 @@
|
||||||
|
|
||||||
#ifdef USE_SCHANNEL
|
#ifdef USE_SCHANNEL
|
||||||
|
|
||||||
#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
|
|
||||||
|
|
||||||
#ifndef USE_WINDOWS_SSPI
|
#ifndef USE_WINDOWS_SSPI
|
||||||
# error "Can't compile SCHANNEL support without SSPI."
|
# error "Can't compile SCHANNEL support without SSPI."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "schannel.h"
|
#include "schannel.h"
|
||||||
|
#include "schannel_int.h"
|
||||||
#include "vtls.h"
|
#include "vtls.h"
|
||||||
#include "vtls_int.h"
|
#include "vtls_int.h"
|
||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
|
@ -186,7 +185,7 @@
|
||||||
#define PKCS12_NO_PERSIST_KEY 0x00008000
|
#define PKCS12_NO_PERSIST_KEY 0x00008000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
|
static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
const char *pinnedpubkey);
|
const char *pinnedpubkey);
|
||||||
|
|
||||||
|
@ -207,7 +206,7 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode
|
static CURLcode
|
||||||
set_ssl_version_min_max(DWORD *enabled_protocols,
|
schannel_set_ssl_version_min_max(DWORD *enabled_protocols,
|
||||||
struct Curl_cfilter *cf,
|
struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
|
@ -500,7 +499,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
|
||||||
DWORD flags = 0;
|
DWORD flags = 0;
|
||||||
DWORD enabled_protocols = 0;
|
DWORD enabled_protocols = 0;
|
||||||
|
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)(connssl->backend);
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
|
||||||
case CURL_SSLVERSION_TLSv1_2:
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
case CURL_SSLVERSION_TLSv1_3:
|
case CURL_SSLVERSION_TLSv1_3:
|
||||||
{
|
{
|
||||||
result = set_ssl_version_min_max(&enabled_protocols, cf, data);
|
result = schannel_set_ssl_version_min_max(&enabled_protocols, cf, data);
|
||||||
if(result != CURLE_OK)
|
if(result != CURLE_OK)
|
||||||
return result;
|
return result;
|
||||||
break;
|
break;
|
||||||
|
@ -1075,7 +1075,8 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
ssize_t written = -1;
|
ssize_t written = -1;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
SecBuffer outbuf;
|
SecBuffer outbuf;
|
||||||
|
@ -1349,7 +1350,8 @@ static CURLcode
|
||||||
schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
int i;
|
int i;
|
||||||
ssize_t nread = -1, written = -1;
|
ssize_t nread = -1, written = -1;
|
||||||
|
@ -1607,7 +1609,7 @@ schannel_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
||||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
|
||||||
if(pubkey_ptr) {
|
if(pubkey_ptr) {
|
||||||
result = pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
|
result = schannel_pkp_pin_peer_pubkey(cf, data, pubkey_ptr);
|
||||||
if(result) {
|
if(result) {
|
||||||
failf(data, "SSL: public key does not match pinned public key");
|
failf(data, "SSL: public key does not match pinned public key");
|
||||||
return result;
|
return result;
|
||||||
|
@ -1686,7 +1688,8 @@ static CURLcode
|
||||||
schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
|
schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||||
|
@ -1931,7 +1934,8 @@ schannel_connect_common(struct Curl_cfilter *cf,
|
||||||
* Available on Windows 7 or later.
|
* Available on Windows 7 or later.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
cf->conn->sslContext = &backend->ctxt->ctxt_handle;
|
cf->conn->sslContext = &backend->ctxt->ctxt_handle;
|
||||||
}
|
}
|
||||||
|
@ -1960,7 +1964,8 @@ schannel_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
SecBufferDesc outbuf_desc;
|
SecBufferDesc outbuf_desc;
|
||||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -2110,7 +2115,8 @@ schannel_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
/* we want the length of the encrypted buffer to be at least large enough
|
/* we want the length of the encrypted buffer to be at least large enough
|
||||||
that it can hold all the bytes requested and some TLS record overhead. */
|
that it can hold all the bytes requested and some TLS record overhead. */
|
||||||
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
@ -2443,12 +2449,13 @@ static bool schannel_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
const struct ssl_connect_data *connssl = cf->ctx;
|
const struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(connssl->backend->ctxt) /* SSL/TLS is in use */
|
if(backend->ctxt) /* SSL/TLS is in use */
|
||||||
return (backend->decdata_offset > 0 ||
|
return (backend->decdata_offset > 0 ||
|
||||||
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
|
(backend->encdata_offset > 0 && !backend->encdata_is_incomplete));
|
||||||
else
|
else
|
||||||
|
@ -2486,12 +2493,13 @@ static int schannel_shutdown(struct Curl_cfilter *cf,
|
||||||
* Shutting Down an Schannel Connection
|
* Shutting Down an Schannel Connection
|
||||||
*/
|
*/
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(connssl->backend->ctxt) {
|
if(backend->ctxt) {
|
||||||
infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
|
infof(data, "schannel: shutting down SSL/TLS connection with %s port %d",
|
||||||
connssl->hostname, connssl->port);
|
connssl->hostname, connssl->port);
|
||||||
}
|
}
|
||||||
|
@ -2611,12 +2619,13 @@ static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM,
|
||||||
return Curl_win32_random(entropy, length);
|
return Curl_win32_random(entropy, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
|
static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
const char *pinnedpubkey)
|
const char *pinnedpubkey)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
CERT_CONTEXT *pCertContextServer = NULL;
|
CERT_CONTEXT *pCertContextServer = NULL;
|
||||||
|
|
||||||
/* Result is returned to caller */
|
/* Result is returned to caller */
|
||||||
|
@ -2742,7 +2751,8 @@ static CURLcode schannel_sha256sum(const unsigned char *input,
|
||||||
static void *schannel_get_internals(struct ssl_connect_data *connssl,
|
static void *schannel_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct schannel_ssl_backend_data *backend =
|
||||||
|
(struct schannel_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return &backend->ctxt->ctxt_handle;
|
return &backend->ctxt->ctxt_handle;
|
||||||
|
@ -2759,7 +2769,7 @@ const struct Curl_ssl Curl_ssl_schannel = {
|
||||||
SSLSUPP_TLS13_CIPHERSUITES |
|
SSLSUPP_TLS13_CIPHERSUITES |
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct schannel_ssl_backend_data),
|
||||||
|
|
||||||
schannel_init, /* init */
|
schannel_init, /* init */
|
||||||
schannel_cleanup, /* cleanup */
|
schannel_cleanup, /* cleanup */
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
#ifdef USE_SCHANNEL
|
#ifdef USE_SCHANNEL
|
||||||
|
|
||||||
#define SCHANNEL_USE_BLACKLISTS 1
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4201)
|
#pragma warning(disable: 4201)
|
||||||
|
@ -81,119 +79,5 @@ extern const struct Curl_ssl Curl_ssl_schannel;
|
||||||
CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
|
CURLcode Curl_verify_certificate(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data);
|
struct Curl_easy *data);
|
||||||
|
|
||||||
/* structs to expose only in schannel.c and schannel_verify.c */
|
|
||||||
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
|
||||||
#ifdef __MINGW64_VERSION_MAJOR
|
|
||||||
#define HAS_MANUAL_VERIFY_API
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
|
|
||||||
#define HAS_MANUAL_VERIFY_API
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
|
|
||||||
&& !defined(DISABLE_SCHANNEL_CLIENT_CERT)
|
|
||||||
#define HAS_CLIENT_CERT_PATH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SCH_CREDENTIALS_VERSION
|
|
||||||
|
|
||||||
#define SCH_CREDENTIALS_VERSION 0x00000005
|
|
||||||
|
|
||||||
typedef enum _eTlsAlgorithmUsage
|
|
||||||
{
|
|
||||||
TlsParametersCngAlgUsageKeyExchange,
|
|
||||||
TlsParametersCngAlgUsageSignature,
|
|
||||||
TlsParametersCngAlgUsageCipher,
|
|
||||||
TlsParametersCngAlgUsageDigest,
|
|
||||||
TlsParametersCngAlgUsageCertSig
|
|
||||||
} eTlsAlgorithmUsage;
|
|
||||||
|
|
||||||
typedef struct _CRYPTO_SETTINGS
|
|
||||||
{
|
|
||||||
eTlsAlgorithmUsage eAlgorithmUsage;
|
|
||||||
UNICODE_STRING strCngAlgId;
|
|
||||||
DWORD cChainingModes;
|
|
||||||
PUNICODE_STRING rgstrChainingModes;
|
|
||||||
DWORD dwMinBitLength;
|
|
||||||
DWORD dwMaxBitLength;
|
|
||||||
} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
|
|
||||||
|
|
||||||
typedef struct _TLS_PARAMETERS
|
|
||||||
{
|
|
||||||
DWORD cAlpnIds;
|
|
||||||
PUNICODE_STRING rgstrAlpnIds;
|
|
||||||
DWORD grbitDisabledProtocols;
|
|
||||||
DWORD cDisabledCrypto;
|
|
||||||
PCRYPTO_SETTINGS pDisabledCrypto;
|
|
||||||
DWORD dwFlags;
|
|
||||||
} TLS_PARAMETERS, * PTLS_PARAMETERS;
|
|
||||||
|
|
||||||
typedef struct _SCH_CREDENTIALS
|
|
||||||
{
|
|
||||||
DWORD dwVersion;
|
|
||||||
DWORD dwCredFormat;
|
|
||||||
DWORD cCreds;
|
|
||||||
PCCERT_CONTEXT* paCred;
|
|
||||||
HCERTSTORE hRootStore;
|
|
||||||
|
|
||||||
DWORD cMappers;
|
|
||||||
struct _HMAPPER **aphMappers;
|
|
||||||
|
|
||||||
DWORD dwSessionLifespan;
|
|
||||||
DWORD dwFlags;
|
|
||||||
DWORD cTlsParameters;
|
|
||||||
PTLS_PARAMETERS pTlsParameters;
|
|
||||||
} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
|
|
||||||
|
|
||||||
#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
|
|
||||||
#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
|
|
||||||
#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
|
|
||||||
#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Curl_schannel_cred {
|
|
||||||
CredHandle cred_handle;
|
|
||||||
TimeStamp time_stamp;
|
|
||||||
TCHAR *sni_hostname;
|
|
||||||
#ifdef HAS_CLIENT_CERT_PATH
|
|
||||||
HCERTSTORE client_cert_store;
|
|
||||||
#endif
|
|
||||||
int refcount;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Curl_schannel_ctxt {
|
|
||||||
CtxtHandle ctxt_handle;
|
|
||||||
TimeStamp time_stamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ssl_backend_data {
|
|
||||||
struct Curl_schannel_cred *cred;
|
|
||||||
struct Curl_schannel_ctxt *ctxt;
|
|
||||||
SecPkgContext_StreamSizes stream_sizes;
|
|
||||||
size_t encdata_length, decdata_length;
|
|
||||||
size_t encdata_offset, decdata_offset;
|
|
||||||
unsigned char *encdata_buffer, *decdata_buffer;
|
|
||||||
/* encdata_is_incomplete: if encdata contains only a partial record that
|
|
||||||
can't be decrypted without another recv() (that is, status is
|
|
||||||
SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
|
|
||||||
more bytes into encdata then set this back to false. */
|
|
||||||
bool encdata_is_incomplete;
|
|
||||||
unsigned long req_flags, ret_flags;
|
|
||||||
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
|
|
||||||
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
|
|
||||||
bool recv_connection_closed; /* true if connection closed, regardless how */
|
|
||||||
bool recv_renegotiating; /* true if recv is doing renegotiation */
|
|
||||||
bool use_alpn; /* true if ALPN is used for this connection */
|
|
||||||
#ifdef HAS_MANUAL_VERIFY_API
|
|
||||||
bool use_manual_cred_validation; /* true if manual cred validation is used */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
|
|
||||||
|
|
||||||
#endif /* USE_SCHANNEL */
|
#endif /* USE_SCHANNEL */
|
||||||
#endif /* HEADER_CURL_SCHANNEL_H */
|
#endif /* HEADER_CURL_SCHANNEL_H */
|
||||||
|
|
142
lib/vtls/schannel_int.h
Normal file
142
lib/vtls/schannel_int.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
#ifndef HEADER_CURL_SCHANNEL_INT_H
|
||||||
|
#define HEADER_CURL_SCHANNEL_INT_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) Marc Hoersken, <info@marc-hoersken.de>, et al.
|
||||||
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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.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.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: curl
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#ifdef USE_SCHANNEL
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#ifdef __MINGW64_VERSION_MAJOR
|
||||||
|
#define HAS_MANUAL_VERIFY_API
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN
|
||||||
|
#define HAS_MANUAL_VERIFY_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \
|
||||||
|
&& !defined(DISABLE_SCHANNEL_CLIENT_CERT)
|
||||||
|
#define HAS_CLIENT_CERT_PATH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SCH_CREDENTIALS_VERSION
|
||||||
|
|
||||||
|
#define SCH_CREDENTIALS_VERSION 0x00000005
|
||||||
|
|
||||||
|
typedef enum _eTlsAlgorithmUsage
|
||||||
|
{
|
||||||
|
TlsParametersCngAlgUsageKeyExchange,
|
||||||
|
TlsParametersCngAlgUsageSignature,
|
||||||
|
TlsParametersCngAlgUsageCipher,
|
||||||
|
TlsParametersCngAlgUsageDigest,
|
||||||
|
TlsParametersCngAlgUsageCertSig
|
||||||
|
} eTlsAlgorithmUsage;
|
||||||
|
|
||||||
|
typedef struct _CRYPTO_SETTINGS
|
||||||
|
{
|
||||||
|
eTlsAlgorithmUsage eAlgorithmUsage;
|
||||||
|
UNICODE_STRING strCngAlgId;
|
||||||
|
DWORD cChainingModes;
|
||||||
|
PUNICODE_STRING rgstrChainingModes;
|
||||||
|
DWORD dwMinBitLength;
|
||||||
|
DWORD dwMaxBitLength;
|
||||||
|
} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS;
|
||||||
|
|
||||||
|
typedef struct _TLS_PARAMETERS
|
||||||
|
{
|
||||||
|
DWORD cAlpnIds;
|
||||||
|
PUNICODE_STRING rgstrAlpnIds;
|
||||||
|
DWORD grbitDisabledProtocols;
|
||||||
|
DWORD cDisabledCrypto;
|
||||||
|
PCRYPTO_SETTINGS pDisabledCrypto;
|
||||||
|
DWORD dwFlags;
|
||||||
|
} TLS_PARAMETERS, * PTLS_PARAMETERS;
|
||||||
|
|
||||||
|
typedef struct _SCH_CREDENTIALS
|
||||||
|
{
|
||||||
|
DWORD dwVersion;
|
||||||
|
DWORD dwCredFormat;
|
||||||
|
DWORD cCreds;
|
||||||
|
PCCERT_CONTEXT* paCred;
|
||||||
|
HCERTSTORE hRootStore;
|
||||||
|
|
||||||
|
DWORD cMappers;
|
||||||
|
struct _HMAPPER **aphMappers;
|
||||||
|
|
||||||
|
DWORD dwSessionLifespan;
|
||||||
|
DWORD dwFlags;
|
||||||
|
DWORD cTlsParameters;
|
||||||
|
PTLS_PARAMETERS pTlsParameters;
|
||||||
|
} SCH_CREDENTIALS, * PSCH_CREDENTIALS;
|
||||||
|
|
||||||
|
#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16
|
||||||
|
#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16
|
||||||
|
#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16
|
||||||
|
#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16
|
||||||
|
|
||||||
|
#endif /* SCH_CREDENTIALS_VERSION */
|
||||||
|
|
||||||
|
struct Curl_schannel_cred {
|
||||||
|
CredHandle cred_handle;
|
||||||
|
TimeStamp time_stamp;
|
||||||
|
TCHAR *sni_hostname;
|
||||||
|
#ifdef HAS_CLIENT_CERT_PATH
|
||||||
|
HCERTSTORE client_cert_store;
|
||||||
|
#endif
|
||||||
|
int refcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Curl_schannel_ctxt {
|
||||||
|
CtxtHandle ctxt_handle;
|
||||||
|
TimeStamp time_stamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct schannel_ssl_backend_data {
|
||||||
|
struct Curl_schannel_cred *cred;
|
||||||
|
struct Curl_schannel_ctxt *ctxt;
|
||||||
|
SecPkgContext_StreamSizes stream_sizes;
|
||||||
|
size_t encdata_length, decdata_length;
|
||||||
|
size_t encdata_offset, decdata_offset;
|
||||||
|
unsigned char *encdata_buffer, *decdata_buffer;
|
||||||
|
/* encdata_is_incomplete: if encdata contains only a partial record that
|
||||||
|
can't be decrypted without another recv() (that is, status is
|
||||||
|
SEC_E_INCOMPLETE_MESSAGE) then set this true. after an recv() adds
|
||||||
|
more bytes into encdata then set this back to false. */
|
||||||
|
bool encdata_is_incomplete;
|
||||||
|
unsigned long req_flags, ret_flags;
|
||||||
|
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
|
||||||
|
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
|
||||||
|
bool recv_connection_closed; /* true if connection closed, regardless how */
|
||||||
|
bool recv_renegotiating; /* true if recv is doing renegotiation */
|
||||||
|
bool use_alpn; /* true if ALPN is used for this connection */
|
||||||
|
#ifdef HAS_MANUAL_VERIFY_API
|
||||||
|
bool use_manual_cred_validation; /* true if manual cred validation is used */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* USE_SCHANNEL */
|
||||||
|
#endif /* HEADER_CURL_SCHANNEL_INT_H */
|
|
@ -36,8 +36,8 @@
|
||||||
# error "Can't compile SCHANNEL support without SSPI."
|
# error "Can't compile SCHANNEL support without SSPI."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
|
|
||||||
#include "schannel.h"
|
#include "schannel.h"
|
||||||
|
#include "schannel_int.h"
|
||||||
|
|
||||||
#ifdef HAS_MANUAL_VERIFY_API
|
#ifdef HAS_MANUAL_VERIFY_API
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define BACKEND connssl->backend
|
#define BACKEND ((struct schannel_ssl_backend_data *)connssl->backend)
|
||||||
|
|
||||||
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
|
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
|
||||||
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
|
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----"
|
||||||
|
|
|
@ -146,7 +146,7 @@
|
||||||
#define ioErr -36
|
#define ioErr -36
|
||||||
#define paramErr -50
|
#define paramErr -50
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct st_ssl_backend_data {
|
||||||
SSLContextRef ssl_ctx;
|
SSLContextRef ssl_ctx;
|
||||||
bool ssl_direction; /* true if writing, false if reading */
|
bool ssl_direction; /* true if writing, false if reading */
|
||||||
size_t ssl_write_buffered_length;
|
size_t ssl_write_buffered_length;
|
||||||
|
@ -836,7 +836,8 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
|
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
@ -872,7 +873,8 @@ static OSStatus bio_cf_out_write(SSLConnectionRef connection,
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
|
struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
@ -1338,7 +1340,8 @@ static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
long ssl_version = conn_config->version;
|
long ssl_version = conn_config->version;
|
||||||
long ssl_version_max = conn_config->version_max;
|
long ssl_version_max = conn_config->version_max;
|
||||||
|
@ -1633,7 +1636,8 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
|
const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
|
||||||
|
@ -2515,7 +2519,8 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
SSLCipherSuite cipher;
|
SSLCipherSuite cipher;
|
||||||
|
@ -2896,7 +2901,8 @@ static CURLcode collect_server_cert(struct Curl_cfilter *cf,
|
||||||
CURLcode result = ssl_config->certinfo ?
|
CURLcode result = ssl_config->certinfo ?
|
||||||
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
|
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
CFArrayRef server_certs = NULL;
|
CFArrayRef server_certs = NULL;
|
||||||
SecCertificateRef server_cert;
|
SecCertificateRef server_cert;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
|
@ -3139,7 +3145,8 @@ static CURLcode sectransp_connect(struct Curl_cfilter *cf,
|
||||||
static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void) data;
|
(void) data;
|
||||||
|
|
||||||
|
@ -3166,7 +3173,8 @@ static int sectransp_shutdown(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
int what;
|
int what;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -3244,7 +3252,8 @@ static bool sectransp_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
const struct ssl_connect_data *connssl = cf->ctx;
|
const struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
size_t buffer;
|
size_t buffer;
|
||||||
|
|
||||||
|
@ -3308,7 +3317,8 @@ static ssize_t sectransp_send(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
size_t processed = 0UL;
|
size_t processed = 0UL;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
|
|
||||||
|
@ -3376,7 +3386,8 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
size_t processed = 0UL;
|
size_t processed = 0UL;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
|
@ -3434,7 +3445,8 @@ again:
|
||||||
static void *sectransp_get_internals(struct ssl_connect_data *connssl,
|
static void *sectransp_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct st_ssl_backend_data *backend =
|
||||||
|
(struct st_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return backend->ssl_ctx;
|
return backend->ssl_ctx;
|
||||||
|
@ -3450,7 +3462,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
|
||||||
#endif /* SECTRANSP_PINNEDPUBKEY */
|
#endif /* SECTRANSP_PINNEDPUBKEY */
|
||||||
SSLSUPP_HTTPS_PROXY,
|
SSLSUPP_HTTPS_PROXY,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct st_ssl_backend_data),
|
||||||
|
|
||||||
Curl_none_init, /* init */
|
Curl_none_init, /* init */
|
||||||
Curl_none_cleanup, /* cleanup */
|
Curl_none_cleanup, /* cleanup */
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct ssl_connect_data {
|
||||||
char *hostname; /* hostname for verification */
|
char *hostname; /* hostname for verification */
|
||||||
char *dispname; /* display version of hostname */
|
char *dispname; /* display version of hostname */
|
||||||
const struct alpn_spec *alpn; /* ALPN to use or NULL for none */
|
const struct alpn_spec *alpn; /* ALPN to use or NULL for none */
|
||||||
struct ssl_backend_data *backend; /* vtls backend specific props */
|
void *backend; /* vtls backend specific props */
|
||||||
struct cf_call_data call_data; /* data handle used in current call */
|
struct cf_call_data call_data; /* data handle used in current call */
|
||||||
struct curltime handshake_done; /* time when handshake finished */
|
struct curltime handshake_done; /* time when handshake finished */
|
||||||
int port; /* remote port at origin */
|
int port; /* remote port at origin */
|
||||||
|
@ -81,6 +81,7 @@ struct ssl_connect_data {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#undef CF_CTX_CALL_DATA
|
||||||
#define CF_CTX_CALL_DATA(cf) \
|
#define CF_CTX_CALL_DATA(cf) \
|
||||||
((struct ssl_connect_data *)(cf)->ctx)->call_data
|
((struct ssl_connect_data *)(cf)->ctx)->call_data
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
#undef USE_BIO_CHAIN
|
#undef USE_BIO_CHAIN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ssl_backend_data {
|
struct wolfssl_ssl_backend_data {
|
||||||
SSL_CTX* ctx;
|
SSL_CTX* ctx;
|
||||||
SSL* handle;
|
SSL* handle;
|
||||||
CURLcode io_result; /* result of last BIO cfilter operation */
|
CURLcode io_result; /* result of last BIO cfilter operation */
|
||||||
|
@ -281,13 +281,15 @@ static int bio_cf_out_write(WOLFSSL_BIO *bio, const char *buf, int blen)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
|
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
|
nwritten = Curl_conn_cf_send(cf->next, data, buf, blen, &result);
|
||||||
connssl->backend->io_result = result;
|
backend->io_result = result;
|
||||||
DEBUGF(LOG_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
|
DEBUGF(LOG_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
|
||||||
blen, nwritten, result));
|
blen, nwritten, result));
|
||||||
wolfSSL_BIO_clear_retry_flags(bio);
|
wolfSSL_BIO_clear_retry_flags(bio);
|
||||||
|
@ -300,6 +302,8 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
|
||||||
{
|
{
|
||||||
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
|
struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
struct Curl_easy *data = CF_DATA_CURRENT(cf);
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
@ -310,7 +314,7 @@ static int bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
|
nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
|
||||||
connssl->backend->io_result = result;
|
backend->io_result = result;
|
||||||
DEBUGF(LOG_CF(data, cf, "bio_read(len=%d) -> %zd, %d",
|
DEBUGF(LOG_CF(data, cf, "bio_read(len=%d) -> %zd, %d",
|
||||||
blen, nread, result));
|
blen, nread, result));
|
||||||
wolfSSL_BIO_clear_retry_flags(bio);
|
wolfSSL_BIO_clear_retry_flags(bio);
|
||||||
|
@ -352,7 +356,8 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
char *ciphers, *curves;
|
char *ciphers, *curves;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
SSL_METHOD* req_method = NULL;
|
SSL_METHOD* req_method = NULL;
|
||||||
|
@ -699,7 +704,8 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||||
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
|
const char * const pinnedpubkey = Curl_ssl_cf_is_proxy(cf)?
|
||||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
|
||||||
|
@ -892,7 +898,8 @@ wolfssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||||
|
|
||||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||||
|
@ -950,7 +957,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||||
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -992,7 +1000,8 @@ static ssize_t wolfssl_send(struct Curl_cfilter *cf,
|
||||||
static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
static void wolfssl_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
|
|
||||||
(void) data;
|
(void) data;
|
||||||
|
|
||||||
|
@ -1019,7 +1028,8 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
|
||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
char error_buffer[WOLFSSL_MAX_ERROR_SZ];
|
||||||
int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
|
int buffsize = (blen > (size_t)INT_MAX) ? INT_MAX : (int)blen;
|
||||||
int nread;
|
int nread;
|
||||||
|
@ -1108,11 +1118,14 @@ static bool wolfssl_data_pending(struct Curl_cfilter *cf,
|
||||||
const struct Curl_easy *data)
|
const struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct wolfssl_ssl_backend_data *backend;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
if(ctx->backend->handle) /* SSL is in use */
|
|
||||||
return (0 != SSL_pending(ctx->backend->handle)) ? TRUE : FALSE;
|
backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
|
||||||
|
if(backend->handle) /* SSL is in use */
|
||||||
|
return (0 != SSL_pending(backend->handle)) ? TRUE : FALSE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1126,15 +1139,17 @@ static int wolfssl_shutdown(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *ctx = cf->ctx;
|
struct ssl_connect_data *ctx = cf->ctx;
|
||||||
|
struct wolfssl_ssl_backend_data *backend;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
DEBUGASSERT(ctx && ctx->backend);
|
DEBUGASSERT(ctx && ctx->backend);
|
||||||
|
|
||||||
if(ctx->backend->handle) {
|
backend = (struct wolfssl_ssl_backend_data *)ctx->backend;
|
||||||
|
if(backend->handle) {
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
SSL_free(ctx->backend->handle);
|
SSL_free(backend->handle);
|
||||||
ctx->backend->handle = NULL;
|
backend->handle = NULL;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1305,7 +1320,8 @@ static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */
|
||||||
static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
|
static void *wolfssl_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
struct ssl_backend_data *backend = connssl->backend;
|
struct wolfssl_ssl_backend_data *backend =
|
||||||
|
(struct wolfssl_ssl_backend_data *)connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
return backend->handle;
|
return backend->handle;
|
||||||
|
@ -1322,7 +1338,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
|
||||||
#endif
|
#endif
|
||||||
SSLSUPP_SSL_CTX,
|
SSLSUPP_SSL_CTX,
|
||||||
|
|
||||||
sizeof(struct ssl_backend_data),
|
sizeof(struct wolfssl_ssl_backend_data),
|
||||||
|
|
||||||
wolfssl_init, /* init */
|
wolfssl_init, /* init */
|
||||||
wolfssl_cleanup, /* cleanup */
|
wolfssl_cleanup, /* cleanup */
|
||||||
|
|
|
@ -35,10 +35,13 @@
|
||||||
|
|
||||||
#endif /* __INTEL_COMPILER && __unix__ */
|
#endif /* __INTEL_COMPILER && __unix__ */
|
||||||
|
|
||||||
#define BUILDING_WARNLESS_C 1
|
|
||||||
|
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#undef read
|
||||||
|
#undef write
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#define CURL_MASK_UCHAR ((unsigned char)~0)
|
#define CURL_MASK_UCHAR ((unsigned char)~0)
|
||||||
|
@ -376,6 +379,9 @@ ssize_t curlx_write(int fd, const void *buf, size_t count)
|
||||||
return (ssize_t)write(fd, buf, curlx_uztoui(count));
|
return (ssize_t)write(fd, buf, curlx_uztoui(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ensure that warnless.h continues to have an effect in "unity" builds. */
|
||||||
|
#undef HEADER_CURL_WARNLESS_H
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
#if defined(__INTEL_COMPILER) && defined(__unix__)
|
||||||
|
|
|
@ -75,12 +75,10 @@ ssize_t curlx_read(int fd, void *buf, size_t count);
|
||||||
|
|
||||||
ssize_t curlx_write(int fd, const void *buf, size_t count);
|
ssize_t curlx_write(int fd, const void *buf, size_t count);
|
||||||
|
|
||||||
#ifndef BUILDING_WARNLESS_C
|
#undef read
|
||||||
# undef read
|
#define read(fd, buf, count) curlx_read(fd, buf, count)
|
||||||
# define read(fd, buf, count) curlx_read(fd, buf, count)
|
#undef write
|
||||||
# undef write
|
#define write(fd, buf, count) curlx_write(fd, buf, count)
|
||||||
# define write(fd, buf, count) curlx_write(fd, buf, count)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
|
|
@ -58,13 +58,17 @@ transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.
|
||||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
|
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND CURL_FILES curl.rc)
|
list(APPEND CURL_CFILES curl.rc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# CURL_CFILES, CURLX_CFILES, CURL_HFILES come from Makefile.inc
|
||||||
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
|
set(CURLX_CFILES ../lib/dynbuf.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# CURL_FILES comes from Makefile.inc
|
|
||||||
add_executable(
|
add_executable(
|
||||||
${EXE_NAME}
|
${EXE_NAME}
|
||||||
${CURL_FILES}
|
${CURL_CFILES} ${CURLX_CFILES} ${CURL_HFILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct finder {
|
||||||
|
|
||||||
/* The order of the variables below is important, as the index number is used
|
/* The order of the variables below is important, as the index number is used
|
||||||
in the findfile() function */
|
in the findfile() function */
|
||||||
static const struct finder list[] = {
|
static const struct finder conf_list[] = {
|
||||||
{ "CURL_HOME", NULL, FALSE },
|
{ "CURL_HOME", NULL, FALSE },
|
||||||
{ "XDG_CONFIG_HOME", NULL, FALSE }, /* index == 1, used in the code */
|
{ "XDG_CONFIG_HOME", NULL, FALSE }, /* index == 1, used in the code */
|
||||||
{ "HOME", NULL, FALSE },
|
{ "HOME", NULL, FALSE },
|
||||||
|
@ -109,8 +109,8 @@ char *findfile(const char *fname, int dotscore)
|
||||||
if(!fname[0])
|
if(!fname[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for(i = 0; list[i].env; i++) {
|
for(i = 0; conf_list[i].env; i++) {
|
||||||
char *home = curl_getenv(list[i].env);
|
char *home = curl_getenv(conf_list[i].env);
|
||||||
if(home) {
|
if(home) {
|
||||||
char *path;
|
char *path;
|
||||||
const char *filename = fname;
|
const char *filename = fname;
|
||||||
|
@ -120,14 +120,14 @@ char *findfile(const char *fname, int dotscore)
|
||||||
curl_free(home);
|
curl_free(home);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(list[i].append) {
|
if(conf_list[i].append) {
|
||||||
char *c = curl_maprintf("%s%s", home, list[i].append);
|
char *c = curl_maprintf("%s%s", home, conf_list[i].append);
|
||||||
curl_free(home);
|
curl_free(home);
|
||||||
if(!c)
|
if(!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
home = c;
|
home = c;
|
||||||
}
|
}
|
||||||
if(list[i].withoutdot) {
|
if(conf_list[i].withoutdot) {
|
||||||
if(!dotscore || xdg) {
|
if(!dotscore || xdg) {
|
||||||
/* this is not looking for .curlrc, or the XDG_CONFIG_HOME was
|
/* this is not looking for .curlrc, or the XDG_CONFIG_HOME was
|
||||||
defined so we skip the extended check */
|
defined so we skip the extended check */
|
||||||
|
|
|
@ -78,6 +78,7 @@ int vms_show = 0;
|
||||||
* when command-line argument globbing is enabled under the MSYS shell, so turn
|
* when command-line argument globbing is enabled under the MSYS shell, so turn
|
||||||
* it off.
|
* it off.
|
||||||
*/
|
*/
|
||||||
|
extern int _CRT_glob;
|
||||||
int _CRT_glob = 0;
|
int _CRT_glob = 0;
|
||||||
#endif /* __MINGW32__ */
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
|
|
@ -73,4 +73,10 @@ extern FILE *tool_stderr;
|
||||||
# include "tool_strdup.h"
|
# include "tool_strdup.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) && !defined(MSDOS)
|
||||||
|
/* set in win32_init() */
|
||||||
|
extern LARGE_INTEGER tool_freq;
|
||||||
|
extern bool tool_isVistaOrGreater;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* HEADER_CURL_TOOL_SETUP_H */
|
#endif /* HEADER_CURL_TOOL_SETUP_H */
|
||||||
|
|
|
@ -33,10 +33,6 @@
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(MSDOS)
|
#if defined(WIN32) && !defined(MSDOS)
|
||||||
|
|
||||||
/* set in win32_init() */
|
|
||||||
extern LARGE_INTEGER tool_freq;
|
|
||||||
extern bool tool_isVistaOrGreater;
|
|
||||||
|
|
||||||
/* In case of bug fix this function has a counterpart in timeval.c */
|
/* In case of bug fix this function has a counterpart in timeval.c */
|
||||||
struct timeval tvnow(void)
|
struct timeval tvnow(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
# SPDX-License-Identifier: curl
|
# SPDX-License-Identifier: curl
|
||||||
#
|
#
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
set(CMAKE_UNITY_BUILD OFF)
|
||||||
|
|
||||||
add_custom_target(testdeps)
|
add_custom_target(testdeps)
|
||||||
add_subdirectory(data)
|
add_subdirectory(data)
|
||||||
add_subdirectory(libtest)
|
add_subdirectory(libtest)
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
set(TARGET_LABEL_PREFIX "Test ")
|
set(TARGET_LABEL_PREFIX "Test ")
|
||||||
|
|
||||||
function(setup_test TEST_NAME) # ARGN are the files in the test
|
function(setup_test TEST_NAME) # ARGN are the files in the test
|
||||||
|
|
||||||
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
|
# These are part of the libcurl static lib. Do not compile/link them again.
|
||||||
|
list(REMOVE_ITEM ARGN ${WARNLESS} ${MULTIBYTE} ${TIMEDIFF})
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN})
|
add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN})
|
||||||
add_dependencies(testdeps ${TEST_NAME})
|
add_dependencies(testdeps ${TEST_NAME})
|
||||||
string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME)
|
string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME)
|
||||||
|
|
|
@ -34,7 +34,8 @@ WARNLESS = ../../lib/warnless.c ../../lib/warnless.h
|
||||||
MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h
|
MULTIBYTE = ../../lib/curl_multibyte.c ../../lib/curl_multibyte.h
|
||||||
|
|
||||||
# these files are used in every single test program below
|
# these files are used in every single test program below
|
||||||
SUPPORTFILES = ../../lib/timediff.c ../../lib/timediff.h first.c test.h
|
TIMEDIFF = ../../lib/timediff.c ../../lib/timediff.h
|
||||||
|
SUPPORTFILES = $(TIMEDIFF) first.c test.h
|
||||||
|
|
||||||
# These are all libcurl test programs
|
# These are all libcurl test programs
|
||||||
noinst_PROGRAMS = chkhostname libauthretry libntlmconnect libprereq \
|
noinst_PROGRAMS = chkhostname libauthretry libntlmconnect libprereq \
|
||||||
|
|
Loading…
Reference in New Issue
Block a user