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:
Viktor Szakats 2023-05-09 10:10:40 +00:00
parent e812473d1e
commit 3f8fc25720
No known key found for this signature in database
GPG Key ID: B5ABD165E2AEF201
57 changed files with 1188 additions and 899 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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 \

View File

@ -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')

View File

@ -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);
} }
/* /*

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
} }

View File

@ -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

View File

@ -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();
} }

View File

@ -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
View File

@ -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);
} }

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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! \

View File

@ -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;

View File

@ -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);

View File

@ -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
View File

@ -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
View File

@ -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)

View File

@ -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);

View File

@ -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
} }

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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
View 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 */

View File

@ -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-----"

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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__)

View File

@ -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 */

View File

@ -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(

View File

@ -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 */

View File

@ -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__ */

View File

@ -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 */

View File

@ -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)
{ {

View File

@ -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)

View File

@ -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)

View File

@ -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 \