Compare commits
246 Commits
curl-7_33_
...
curl-7_34_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0966b324d9 | ||
|
|
c0ef05e675 | ||
|
|
1dc43de0dc | ||
|
|
8a8f9a5d57 | ||
|
|
be28223f35 | ||
|
|
8e2d73bbde | ||
|
|
dd4d9ea542 | ||
|
|
169fedbdce | ||
|
|
32b9c30e67 | ||
|
|
75cd7fd667 | ||
|
|
7246dffff5 | ||
|
|
41d21e460f | ||
|
|
aadca7f418 | ||
|
|
3905bd637d | ||
|
|
c4f46e97ca | ||
|
|
bd3ca6630a | ||
|
|
92e607abfa | ||
|
|
ef118c13ba | ||
|
|
1cf71bd76e | ||
|
|
2c0ecac9d3 | ||
|
|
b0b5b51193 | ||
|
|
ff9b66a8d4 | ||
|
|
e221b55f67 | ||
|
|
865666afca | ||
|
|
7fc9325a52 | ||
|
|
4fb8241add | ||
|
|
30e7e7552b | ||
|
|
f58f843f66 | ||
|
|
d92de3a7e9 | ||
|
|
fe7fc61c6e | ||
|
|
ad3836448e | ||
|
|
f3ee587775 | ||
|
|
c92c30edbd | ||
|
|
4d10f48629 | ||
|
|
dc68120e63 | ||
|
|
0db811b69b | ||
|
|
d81cbbcc2c | ||
|
|
0dd6522036 | ||
|
|
889cb9c982 | ||
|
|
26ff1ea6c3 | ||
|
|
59f1209fad | ||
|
|
7b9365c65f | ||
|
|
a900d45489 | ||
|
|
e64f91feb7 | ||
|
|
b2a55c8106 | ||
|
|
030a2b8cb8 | ||
|
|
edce855943 | ||
|
|
35e476a3f6 | ||
|
|
0434a19431 | ||
|
|
2ff0c6f5f3 | ||
|
|
8a94aedbd6 | ||
|
|
95877cf8ae | ||
|
|
d3325ae40a | ||
|
|
23fabf8dea | ||
|
|
7a36b2abc0 | ||
|
|
e1c255f388 | ||
|
|
6d3c832a30 | ||
|
|
7935478397 | ||
|
|
5ee64be9c6 | ||
|
|
9f18cf15d5 | ||
|
|
bf05da183e | ||
|
|
2c04e8d80c | ||
|
|
925df53580 | ||
|
|
8191800a0c | ||
|
|
2165298fe6 | ||
|
|
e885dc85a1 | ||
|
|
df58084695 | ||
|
|
3c8c9b2779 | ||
|
|
b27dc009cf | ||
|
|
2c7a5578e1 | ||
|
|
b56d7cda74 | ||
|
|
8896b56488 | ||
|
|
0d735c29f9 | ||
|
|
3d50e91aee | ||
|
|
0cbfe5a7d5 | ||
|
|
eedca5055e | ||
|
|
5d040632ac | ||
|
|
314c3b8480 | ||
|
|
d630e1f389 | ||
|
|
0ea4a80bb2 | ||
|
|
ed4ce23c23 | ||
|
|
168aa59705 | ||
|
|
f71b1ad908 | ||
|
|
dac01ff6d7 | ||
|
|
4a9fe26837 | ||
|
|
90ec8763a5 | ||
|
|
796333bc5e | ||
|
|
f16c0de4e9 | ||
|
|
786cba1ada | ||
|
|
ed1662c374 | ||
|
|
1f0616ea1a | ||
|
|
55250d2d02 | ||
|
|
c5d73167a6 | ||
|
|
bde901ad89 | ||
|
|
79c77f7c31 | ||
|
|
986c249f2f | ||
|
|
3b8c3eb911 | ||
|
|
b29217d0d6 | ||
|
|
534f90f9bf | ||
|
|
dbe228353d | ||
|
|
bf77101e5c | ||
|
|
2ea9a125a6 | ||
|
|
58a00d6d9f | ||
|
|
57a27528e6 | ||
|
|
632c1edd06 | ||
|
|
434bc09263 | ||
|
|
f2584627c8 | ||
|
|
6901861fc9 | ||
|
|
d7d8a8f922 | ||
|
|
c19cfb79db | ||
|
|
65ce9b6d6c | ||
|
|
5f34a10445 | ||
|
|
fa1253aee1 | ||
|
|
f833f54979 | ||
|
|
e7d77fb3ef | ||
|
|
c8e63f247a | ||
|
|
7396ad6e09 | ||
|
|
6d295f8d7d | ||
|
|
5bd999d0c5 | ||
|
|
0f81fbe5da | ||
|
|
9b67960421 | ||
|
|
e10a26a9d6 | ||
|
|
7b68b58bc0 | ||
|
|
2d5455feac | ||
|
|
ac05c80f19 | ||
|
|
460adfef93 | ||
|
|
c876f6ae6d | ||
|
|
f49276bfcb | ||
|
|
d08ee3c83d | ||
|
|
cf7008670b | ||
|
|
558034ab70 | ||
|
|
27b7b1062f | ||
|
|
af82661dbd | ||
|
|
76f924131c | ||
|
|
98a5fdaf29 | ||
|
|
1ea05be46d | ||
|
|
c9d8c00a41 | ||
|
|
5aa290f0f2 | ||
|
|
f0831f7931 | ||
|
|
7fc3b2ce38 | ||
|
|
02fbc26d59 | ||
|
|
0074c9f5d1 | ||
|
|
90acbfd52e | ||
|
|
989b28fe97 | ||
|
|
aa61e14dc1 | ||
|
|
a84a09ad0b | ||
|
|
66b8557aff | ||
|
|
63cac69c2a | ||
|
|
f77d9b6584 | ||
|
|
2736b27df7 | ||
|
|
297644fa70 | ||
|
|
0177f28c51 | ||
|
|
732d10ed6c | ||
|
|
526a1c3b45 | ||
|
|
5b315a273e | ||
|
|
5094bb53f4 | ||
|
|
052f24c9b7 | ||
|
|
bce03fe144 | ||
|
|
9a1755264f | ||
|
|
3b59696a93 | ||
|
|
cdccb42267 | ||
|
|
753d44fa00 | ||
|
|
cfdfdcdd9d | ||
|
|
e232f5f3f9 | ||
|
|
43400b4086 | ||
|
|
8179354c2f | ||
|
|
f6c335d63f | ||
|
|
2bd72fa61c | ||
|
|
e17c1b25bc | ||
|
|
7d1eb66cd7 | ||
|
|
255826c40f | ||
|
|
1d0eead969 | ||
|
|
8005e58983 | ||
|
|
5d415815df | ||
|
|
f68559c086 | ||
|
|
08f97f3b1d | ||
|
|
b87ba2c942 | ||
|
|
e7a2ba41e3 | ||
|
|
6fe619be7a | ||
|
|
1e39b95682 | ||
|
|
8230af0b94 | ||
|
|
1709e5e966 | ||
|
|
7d7df83198 | ||
|
|
7de4cc35f8 | ||
|
|
aa0eaef483 | ||
|
|
9f503a254b | ||
|
|
d44b014271 | ||
|
|
469b423350 | ||
|
|
0adad07690 | ||
|
|
e4670a1029 | ||
|
|
1f0e50f2b9 | ||
|
|
2766262a68 | ||
|
|
bdb1f0e53d | ||
|
|
6e3613e6e6 | ||
|
|
1cb5150dba | ||
|
|
d24b7953c2 | ||
|
|
13db74ffc3 | ||
|
|
98905aa2c5 | ||
|
|
820ed48a00 | ||
|
|
973cc22529 | ||
|
|
2cc9246477 | ||
|
|
650036633f | ||
|
|
78aee26be6 | ||
|
|
947d431d50 | ||
|
|
58bd0148fb | ||
|
|
ca5c5be3e4 | ||
|
|
9bd37a6d27 | ||
|
|
1be69159f3 | ||
|
|
a3da0a96e3 | ||
|
|
626f8a85f0 | ||
|
|
867b52a7ac | ||
|
|
be31924f8c | ||
|
|
f70b2c77f4 | ||
|
|
ae495ffcc3 | ||
|
|
0fdfe82c6a | ||
|
|
dead10b1b8 | ||
|
|
41d820d2c3 | ||
|
|
5b31b38c27 | ||
|
|
39f4e4fafa | ||
|
|
587811c0a6 | ||
|
|
7f7fbe7fbd | ||
|
|
9b1eb2b421 | ||
|
|
1034aa6680 | ||
|
|
4be0af7f74 | ||
|
|
72f850571d | ||
|
|
e179d0eb12 | ||
|
|
ce61510127 | ||
|
|
86c64f3daf | ||
|
|
65e556d0ce | ||
|
|
6a1363128f | ||
|
|
75b9b26465 | ||
|
|
2c84ffe154 | ||
|
|
e7452415c5 | ||
|
|
87861c9b0e | ||
|
|
4d49ffe165 | ||
|
|
f63603dec4 | ||
|
|
0218a737fe | ||
|
|
18ca0aa984 | ||
|
|
c4e6c33b13 | ||
|
|
d774802eec | ||
|
|
69c0d3fbc8 | ||
|
|
076726f141 | ||
|
|
ad34a2d5c8 | ||
|
|
31e106c01c | ||
|
|
1dcc433661 | ||
|
|
a106abee62 |
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
language: c
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- ./buildconf
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
@@ -108,7 +108,11 @@ if(NOT UNIX)
|
|||||||
set(HAVE_IN_ADDR_T 0)
|
set(HAVE_IN_ADDR_T 0)
|
||||||
set(HAVE_INET_NTOA_R_DECL 0)
|
set(HAVE_INET_NTOA_R_DECL 0)
|
||||||
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
|
||||||
set(HAVE_GETADDRINFO 0)
|
if(ENABLE_IPV6)
|
||||||
|
set(HAVE_GETADDRINFO 1)
|
||||||
|
else()
|
||||||
|
set(HAVE_GETADDRINFO 0)
|
||||||
|
endif()
|
||||||
set(STDC_HEADERS 1)
|
set(STDC_HEADERS 1)
|
||||||
set(RETSIGTYPE_TEST 1)
|
set(RETSIGTYPE_TEST 1)
|
||||||
|
|
||||||
|
|||||||
@@ -783,6 +783,17 @@ else()
|
|||||||
set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT})
|
set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# TODO test which of these headers are required for the typedefs used in curlbuild.h
|
||||||
|
if(WIN32)
|
||||||
|
set(CURL_PULL_WS2TCPIP_H ${HAVE_WS2TCPIP_H})
|
||||||
|
else()
|
||||||
|
set(CURL_PULL_SYS_TYPES_H ${HAVE_SYS_TYPES_H})
|
||||||
|
set(CURL_PULL_SYS_SOCKET_H ${HAVE_SYS_SOCKET_H})
|
||||||
|
set(CURL_PULL_SYS_POLL_H ${HAVE_SYS_POLL_H})
|
||||||
|
endif()
|
||||||
|
set(CURL_PULL_STDINT_H ${HAVE_STDINT_H})
|
||||||
|
set(CURL_PULL_INTTYPES_H ${HAVE_INTTYPES_H})
|
||||||
|
|
||||||
include(CMake/OtherTests.cmake)
|
include(CMake/OtherTests.cmake)
|
||||||
|
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
|
|||||||
180
RELEASE-NOTES
180
RELEASE-NOTES
@@ -1,68 +1,71 @@
|
|||||||
Curl and libcurl 7.33.0
|
Curl and libcurl 7.34.0
|
||||||
|
|
||||||
Public curl releases: 135
|
Public curl releases: 136
|
||||||
Command line options: 161
|
Command line options: 161
|
||||||
curl_easy_setopt() options: 205
|
curl_easy_setopt() options: 206
|
||||||
Public functions in libcurl: 58
|
Public functions in libcurl: 58
|
||||||
Known libcurl bindings: 42
|
Known libcurl bindings: 42
|
||||||
Contributors: 1057
|
Contributors: 1104
|
||||||
|
|
||||||
|
This release includes the following security fix:
|
||||||
|
o gtls: respect *VERIFYHOST independently of *VERIFYPEER [26]
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o test code for testing the event based API [3]
|
o SSL: protocol version can be specified more precisely [1]
|
||||||
o CURLM_ADDED_ALREADY: new error code
|
o imap/pop3/smtp: Added graceful cancellation of SASL authentication
|
||||||
o test TFTP server: support "writedelay" within <servercmd>
|
o Add "Happy Eyeballs" for IPv4/IPv6 dual connect attempts
|
||||||
o krb4 support has been removed
|
o base64: Added validation of base64 input strings when decoding [8]
|
||||||
o imap/pop3/smtp: added basic SASL XOAUTH2 support [9]
|
o curl_easy_setopt: Added the ability to set the login options separately
|
||||||
o darwinssl: add support for PKCS#12 files for client authentication
|
o smtp: Added support for additional SMTP commands
|
||||||
o darwinssl: enable BEAST workaround on iOS 7 & later
|
o curl_easy_getinfo: Added CURLINFO_TLS_SESSION for accessing TLS internals
|
||||||
o Pass password to OpenSSL engine by user interface [15]
|
o nss: allow to use TLS > 1.0 if built against recent NSS [18]
|
||||||
o c-ares: Add support for various DNS binding options
|
o SECURITY: added this document to describe our security processes [22]
|
||||||
o cookies: add expiration
|
o parseconfig: warn if unquoted white spaces are detected
|
||||||
o curl: added --oauth2-bearer option
|
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o nss: make sure that NSS is initialized
|
o darwinssl: un-break iOS build after PKCS#12 feature added
|
||||||
o curl: make --no-[option] work properly for several options
|
o tool: use XFERFUNCTION to save some casts [2]
|
||||||
o FTP: with socket_action send better socket updates in active mode [1]
|
o usercertinmem: fix memory leaks
|
||||||
o curl: fix the --sasl-ir in the --help output
|
o ssh: Handle successful SSH_USERAUTH_NONE [3]
|
||||||
o tests 2032, 2033: Don't hardcode port in expected output
|
o NSS: acknowledge the --no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option [4]
|
||||||
o urlglob: better detect unclosed braces, empty lists and overflows [7]
|
o test906: Fixed failing test on some platforms [5]
|
||||||
o urlglob: error out on range overflow [8]
|
o sasl: initialize NSS before using NTLM crypto
|
||||||
o imap: Fixed response check for SEARCH, EXPUNGE, LSUB, UID and NOOP commands [10]
|
o sasl: Fixed memory leak in OAUTH2 message creation
|
||||||
o handle arbitrary-length username and password [2]
|
o imap/pop3/smtp: Fixed QUIT / LOGOUT being sent when SSL connect fails
|
||||||
o TFTP: make the CURLOPT_LOW_SPEED* options work [4]
|
o cmake: unbreak for non-Windows platforms [6]
|
||||||
o curl.h: name space pollution by "enum type" [5]
|
o ssh: initialize per-handle data in ssh_connect()
|
||||||
o multi: move on from STATE_DONE faster [6]
|
o glob: fix broken URLs
|
||||||
o FTP: 60 secs delay if aborted in the CURLOPT_HEADERFUNCTION callback [11]
|
o configure: check for long long when building with cyassl
|
||||||
o multi_socket: improved 100-continue timeout handling
|
o CURLOPT_RESOLVE: mention they don't time-out [7]
|
||||||
o curl_multi_remove_handle: allow multiple removes
|
o docs/examples/httpput.c: fix build for MSVC
|
||||||
o FTP: fix getsock during DO_MORE state [12]
|
o FTP: make the data connection work when going through proxy
|
||||||
o -x: rephrased the --proxy section somewhat
|
o NSS: support for CERTINFO feature
|
||||||
o acinclude: fix --without-ca-path when cross-compiling [13]
|
o curl_multi_wait: accept 0 from multi_timeout() as valid timeout
|
||||||
o LDAP: fix bad free() when URL parsing failed [14]
|
o glob_range: pass the closing bracket for a-z ranges
|
||||||
o --data: mention CRLF treatment when reading from file
|
o tool_help: Updated --list-only description to include POP3
|
||||||
o curl_easy_pause: suggest one way to unpause
|
o Curl_ssl_push_certinfo_len: don't %.*s non-zero-terminated string [9]
|
||||||
o imap: Fixed calculation of transfer when partial FETCH received [16]
|
o cmake: fix Windows build with IPv6 support [10]
|
||||||
o pingpong: Check SSL library buffers for already read data [16]
|
o ares: Fixed compilation under Visual Studio 2012 [11]
|
||||||
o imap/pop3/smtp: Speed up SSL connection initialization
|
o curl_easy_setopt.3: clarify CURLOPT_SSL_VERIFYHOST documentation [12]
|
||||||
o libcurl.3: for multi interface connections are held in the multi handle
|
o curl.1: mention that -O does no URL decoding [13]
|
||||||
o curl_easy_setopt.3: mention RTMP URL quirks [17]
|
o darwinssl: PKCS#12 import feature now requires Lion or later [14]
|
||||||
o curl.1: detail how short/long options work [18]
|
o darwinssl: check for SSLSetSessionOption() presence when toggling BEAST
|
||||||
o curl.1: Added information about optional login options to --user option
|
o configure: Fix test with -Werror=implicit-function-declaration [15]
|
||||||
o curl: Added clarification to the --mail options in the --help output
|
o sigpipe: factor out sigpipe_reset from easy.c
|
||||||
o curl_easy_setopt.3: clarify that TIMEOUT and TIMEOUT_MS set the same value
|
o curl_multi_cleanup: ignore SIGPIPE
|
||||||
o openssl: use correct port number in error message [19]
|
o globbing: curl glob counter mismatch with {} list use [16]
|
||||||
o darwinssl: block TLS_RSA_WITH_NULL_SHA256 cipher
|
o parseconfig: dash options can't specified with colon or equals [17]
|
||||||
o OpenSSL: acknowledge CURLOPT_SSL_VERIFYHOST without VERIFYPEER
|
o digest: fix CURLAUTH_DIGEST_IE [19]
|
||||||
o xattr: add support for FreeBSD xattr API
|
o curl.h: <sys/select.h> for OpenBSD [20]
|
||||||
o win32: fix Visual Studio 2010 build with WINVER >= 0x600 [22]
|
o darwinssl: Fix #if 10.6.0 for SecKeychainSearch
|
||||||
o configure: use icc options without space [21]
|
o TFTP: fix return codes for connect timeout [21]
|
||||||
o test1112: Increase the timeout from 7s to 16s [20]
|
o login options: remove the ;[options] support from CURLOPT_USERPWD [23]
|
||||||
o SCP: upload speed on a fast connection limited to 16384 B/s
|
o imap: Fixed incorrect fallback to clear text authentication
|
||||||
o curl_setup_once: fix errno access for lwip on Windows [24]
|
o parsedate: avoid integer overflow
|
||||||
o HTTP: Output http response 304 when modified time is too old [23]
|
o curl.1: document -J doesn't %-decode [25]
|
||||||
|
o multi: add timer inaccuracy margin to timeout/connecttimeout [24]
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@@ -71,41 +74,42 @@ This release includes the following known bugs:
|
|||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Alex McLellan, Bill Doyle, Colby Ranger, Fabian Keil, Gisle Vanem,
|
Alessandro Ghedini, Andreas Rieke, Björn Stenberg, Chris Conlon,
|
||||||
John E. Malmberg, Jonathan Nieder, Kamil Dudka, Shawn Landden,
|
Christian Grothoff, Christian Weisgerber, Dave Reisner, David Walser,
|
||||||
Tor Arntsen, Will Dietz, Yi Huang, Kyle L. Huff, Steve Holme, Mike Mio,
|
Dima Tisnek, Fabian Keil, Felix Yan, Gergely Nagy, Gisle Vanem,
|
||||||
Stefan Neis, Nick Zitzmann, Geoff Beier, John Dunn, Jiri Hruska,
|
Ishan SinghLevett, James Dury, Javier Barroso, Jeff King, Kamil Dudka,
|
||||||
Tomas Mlcoch, Kim Vandry, Ben Greear, Gorilla Maguila, Jerry Krinock,
|
Kim Vandry, Marcin Gryszkalis, Melissa Mears, Michael Osipov, Nick Zitzmann,
|
||||||
Yamada Yasuharu, Gordon Marler, Dave Thompson, D. Flinkmann,
|
Oliver Kuckertz, Patrick Monnerat, Paul Donohue, Paul Marks, Romulo A. Ceccon,
|
||||||
Benoit Sigoure, Clemens Gruber, Guenter Knauf, Petr Pisar, Elmira A Semenova,
|
Rémy Léone, Sergey Tatarincev, Steve Holme, Tomas Hoger, Tyler Hall,
|
||||||
Francois Charlier, Ishan SinghLevett, Marcel Raad, Ulf Samuelsson,
|
Yaakov Selkowitz, Eric Lubin, Petr Bahula, He Qin, Marc Deslauriers
|
||||||
Andrej E Baranov, Derek Higgins, Heinrich Schaefer
|
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
|
||||||
References to bug reports and discussions on issues:
|
References to bug reports and discussions on issues:
|
||||||
|
|
||||||
[1] = http://curl.haxx.se/mail/lib-2013-08/0043.html
|
[1] = https://github.com/bagder/curl/pull/79
|
||||||
[2] = http://bugs.debian.org/719856
|
[2] = http://curl.haxx.se/mail/lib-2013-10/0089.html
|
||||||
[3] = http://daniel.haxx.se/blog/2013/08/20/testing-curl_multi_socket_action/
|
[3] = http://curl.haxx.se/mail/lib-2013-10/0096.html
|
||||||
[4] = http://curl.haxx.se/bug/view.cgi?id=1269
|
[4] = http://curl.haxx.se/mail/lib-2013-10/0113.html
|
||||||
[5] = https://github.com/bagder/curl/pull/76
|
[5] = http://sourceforge.net/p/curl/bugs/1291
|
||||||
[6] = http://curl.haxx.se/mail/lib-2013-08/0211.html
|
[6] = http://sourceforge.net/p/curl/bugs/1292
|
||||||
[7] = http://curl.haxx.se/bug/view.cgi?id=1264
|
[7] = http://curl.haxx.se/mail/lib-2013-10/0062.html
|
||||||
[8] = http://curl.haxx.se/bug/view.cgi?id=1267
|
[8] = http://curl.haxx.se/mail/lib-2013-10/0242.html
|
||||||
[9] = http://curl.haxx.se/mail/lib-2013-08/0234.html
|
[9] = http://curl.haxx.se/bug/view.cgi?id=1295
|
||||||
[10] = http://curl.haxx.se/mail/lib-2013-08/0136.html
|
[10] = http://sourceforge.net/p/curl/bugs/1064
|
||||||
[11] = https://bugzilla.redhat.com/1005686
|
[11] = http://curl.haxx.se/mail/lib-2013-11/0057.html
|
||||||
[12] = http://curl.haxx.se/mail/lib-2013-08/0109.html
|
[12] = https://github.com/bagder/curl/pull/83
|
||||||
[13] = http://curl.haxx.se/bug/view.cgi?id=1273
|
[13] = http://sourceforge.net/p/curl/bugs/1299
|
||||||
[14] = http://curl.haxx.se/mail/lib-2013-08/0209.html
|
[14] = http://curl.haxx.se/mail/lib-2013-11/0076.html
|
||||||
[15] = http://curl.haxx.se/mail/lib-2013-08/0265.html
|
[15] = http://curl.haxx.se/bug/view.cgi?id=1304
|
||||||
[16] = http://curl.haxx.se/mail/lib-2013-08/0170.html
|
[16] = http://curl.haxx.se/bug/view.cgi?id=1305
|
||||||
[17] = http://curl.haxx.se/bug/view.cgi?id=1278
|
[17] = http://curl.haxx.se/bug/view.cgi?id=1297
|
||||||
[18] = http://curl.haxx.se/bug/view.cgi?id=1279
|
[18] = http://curl.haxx.se/mail/lib-2013-11/0162.html
|
||||||
[19] = http://curl.haxx.se/bug/view.cgi?id=1281
|
[19] = http://curl.haxx.se/bug/view.cgi?id=1308
|
||||||
[20] = http://curl.haxx.se/mail/lib-2010-02/0200.html
|
[20] = http://curl.haxx.se/mail/lib-2013-12/0017.html
|
||||||
[21] = http://curl.haxx.se/mail/lib-2013-09/0182.html
|
[21] = http://curl.haxx.se/bug/view.cgi?id=1310
|
||||||
[22] = http://curl.haxx.se/bug/view.cgi?id=1282
|
[22] = http://curl.haxx.se/dev/security.html
|
||||||
[23] = http://curl.haxx.se/bug/view.cgi?id=1288
|
[23] = http://curl.haxx.se/bug/view.cgi?id=1311
|
||||||
[24] = http://curl.haxx.se/mail/lib-2013-10/0048.html
|
[24] = http://curl.haxx.se/bug/view.cgi?id=1298
|
||||||
|
[25] = http://curl.haxx.se/bug/view.cgi?id=1294
|
||||||
|
[26] = http://curl.haxx.se/docs/adv_20131217.html
|
||||||
|
|||||||
16
configure.ac
16
configure.ac
@@ -1065,6 +1065,7 @@ AC_HELP_STRING([--disable-ipv6],[Disable ipv6 support]),
|
|||||||
AC_TRY_RUN([ /* is AF_INET6 available? */
|
AC_TRY_RUN([ /* is AF_INET6 available? */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <stdlib.h> /* for exit() */
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
|
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
|
||||||
@@ -1983,6 +1984,9 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
if test "x$USE_CYASSL" = "xyes"; then
|
if test "x$USE_CYASSL" = "xyes"; then
|
||||||
AC_MSG_NOTICE([detected CyaSSL])
|
AC_MSG_NOTICE([detected CyaSSL])
|
||||||
|
|
||||||
|
dnl cyassl/ctaocrypt/types.h needs SIZEOF_LONG_LONG defined!
|
||||||
|
AC_CHECK_SIZEOF(long long)
|
||||||
|
|
||||||
LIBS="-lcyassl -lm $LIBS"
|
LIBS="-lcyassl -lm $LIBS"
|
||||||
|
|
||||||
if test -n "$cyassllib"; then
|
if test -n "$cyassllib"; then
|
||||||
@@ -2067,8 +2071,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
CPPFLAGS="$CPPFLAGS $addcflags"
|
CPPFLAGS="$CPPFLAGS $addcflags"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl The function PK11_CreateGenericObject is needed to load libnsspem.so
|
dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
|
||||||
AC_CHECK_LIB(nss3, PK11_CreateGenericObject,
|
AC_CHECK_LIB(nss3, SSL_VersionRangeSet,
|
||||||
[
|
[
|
||||||
AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
|
AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
|
||||||
AC_SUBST(USE_NSS, [1])
|
AC_SUBST(USE_NSS, [1])
|
||||||
@@ -2084,14 +2088,6 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||||||
if test "x$USE_NSS" = "xyes"; then
|
if test "x$USE_NSS" = "xyes"; then
|
||||||
AC_MSG_NOTICE([detected NSS version $version])
|
AC_MSG_NOTICE([detected NSS version $version])
|
||||||
|
|
||||||
dnl NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent
|
|
||||||
dnl collisions on NSS initialization/shutdown with other libraries
|
|
||||||
AC_CHECK_FUNC(NSS_InitContext,
|
|
||||||
[
|
|
||||||
AC_DEFINE(HAVE_NSS_INITCONTEXT, 1, [if you have the NSS_InitContext function])
|
|
||||||
AC_SUBST(HAVE_NSS_INITCONTEXT, [1])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl when shared libs were found in a path that the run-time
|
dnl when shared libs were found in a path that the run-time
|
||||||
dnl linker doesn't search through, we need to add it to
|
dnl linker doesn't search through, we need to add it to
|
||||||
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Portability
|
|||||||
openldap 2.0
|
openldap 2.0
|
||||||
MIT krb5 lib 1.2.4
|
MIT krb5 lib 1.2.4
|
||||||
qsossl V5R3M0
|
qsossl V5R3M0
|
||||||
NSS 3.12.x
|
NSS 3.14.x
|
||||||
axTLS 1.2.7
|
axTLS 1.2.7
|
||||||
Heimdal ?
|
Heimdal ?
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,25 @@ join in and help us correct one or more of these! Also be sure to check the
|
|||||||
changelog of the current development status, as one or more of these problems
|
changelog of the current development status, as one or more of these problems
|
||||||
may have been fixed since this was written!
|
may have been fixed since this was written!
|
||||||
|
|
||||||
|
87. -J/--remote-header-name doesn't decode %-encoded file names. RFC6266
|
||||||
|
details how it should be done. The can of worm is basically that we have no
|
||||||
|
charset handling in curl and ascii >=128 is a challenge for us. Not to
|
||||||
|
mention that decoding also means that we need to check for nastyness that is
|
||||||
|
attempted, like "../" sequences and the like. Probably everything to the left
|
||||||
|
of any embedded slashes should be cut off.
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=1294
|
||||||
|
|
||||||
|
86. The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3
|
||||||
|
and SMTP if a failure occures during the authentication phase of a
|
||||||
|
connection.
|
||||||
|
|
||||||
|
85. Wrong STARTTRANSFER timer accounting for POST requests
|
||||||
|
Timer works fine with GET requests, but while using POST the time for
|
||||||
|
CURLINFO_STARTTRANSFER_TIME is wrong. While using POST
|
||||||
|
CURLINFO_STARTTRANSFER_TIME minus CURLINFO_PRETRANSFER_TIME is near to zero
|
||||||
|
every time.
|
||||||
|
http://curl.haxx.se/bug/view.cgi?id=1213
|
||||||
|
|
||||||
84. CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
|
84. CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
|
||||||
backends, so relying on this information in a generic app is flaky.
|
backends, so relying on this information in a generic app is flaky.
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
|
|||||||
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
|
||||||
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
|
||||||
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
|
||||||
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS
|
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS SECURITY
|
||||||
|
|
||||||
MAN2HTML= roffit < $< >$@
|
MAN2HTML= roffit < $< >$@
|
||||||
|
|
||||||
|
|||||||
91
docs/SECURITY
Normal file
91
docs/SECURITY
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
_ _ ____ _
|
||||||
|
___| | | | _ \| |
|
||||||
|
/ __| | | | |_) | |
|
||||||
|
| (__| |_| | _ <| |___
|
||||||
|
\___|\___/|_| \_\_____|
|
||||||
|
|
||||||
|
CURL SECURITY FOR DEVELOPERS
|
||||||
|
|
||||||
|
This document is intended to provide guidance to curl developers on how
|
||||||
|
security vulnerabilities should be handled.
|
||||||
|
|
||||||
|
PUBLISHING INFORMATION
|
||||||
|
|
||||||
|
All known and public curl or libcurl related vulnerabilities are listed at
|
||||||
|
http://curl.haxx.se/docs/security.html
|
||||||
|
|
||||||
|
Security vulnerabilities should not be entered in the project's public bug
|
||||||
|
tracker unless the necessary configuration is in place to limit access to the
|
||||||
|
issue to only the reporter and the project's security team.
|
||||||
|
|
||||||
|
VULNERABILITY HANDLING
|
||||||
|
|
||||||
|
The typical process for handling a new security vulnerability is as follows.
|
||||||
|
|
||||||
|
No information should be made public about a vulnerability until it is
|
||||||
|
formally announced at the end of this process. That means, for example that a
|
||||||
|
bug tracker entry must NOT be created to track the issue since that will make
|
||||||
|
the issue public and it should not be discussed on any of the project's public
|
||||||
|
mailing lists. Also messages associated with any commits should not make
|
||||||
|
any reference to the security nature of the commit if done prior to the public
|
||||||
|
announcement.
|
||||||
|
|
||||||
|
- The person discovering the issue, the reporter, reports the vulnerability
|
||||||
|
privately to curl-security@haxx.se. That's an email alias that reaches a
|
||||||
|
handful of selected and trusted people.
|
||||||
|
|
||||||
|
- Messages that do not relate to the reporting or managing of an undisclosed
|
||||||
|
security vulnerability in curl or libcurl are ignored and no further action
|
||||||
|
is required.
|
||||||
|
|
||||||
|
- A person in the security team sends an e-mail to the original reporter to
|
||||||
|
acknowledge the report.
|
||||||
|
|
||||||
|
- The security team investigates the report and either rejects it or accepts
|
||||||
|
it.
|
||||||
|
|
||||||
|
- If the report is rejected, the team writes to the reporter to explain why.
|
||||||
|
|
||||||
|
- If the report is accepted, the team writes to the reporter to let him/her
|
||||||
|
know it is accepted and that they are working on a fix.
|
||||||
|
|
||||||
|
- The security team discusses the problem, works out a fix, considers the
|
||||||
|
impact of the problem and suggests a release schedule. This discussion
|
||||||
|
should involve the reporter as much as possible.
|
||||||
|
|
||||||
|
- The release of the information should be "as soon as possible" and is most
|
||||||
|
often synced with an upcoming release that contains the fix. If the
|
||||||
|
reporter, or anyone else, thinks the next planned release is too far away
|
||||||
|
then a separate earlier release for security reasons should be considered.
|
||||||
|
|
||||||
|
- Write a security advisory draft about the problem that explains what the
|
||||||
|
problem is, its impact, which versions it affects, solutions or
|
||||||
|
work-arounds, when the release is out and make sure to credit all
|
||||||
|
contributors properly.
|
||||||
|
|
||||||
|
- Request a CVE number from distros@openwall.org[1] when also informing and
|
||||||
|
preparing them for the upcoming public security vulnerability announcement -
|
||||||
|
attach the advisory draft for information. Note that 'distros' won't accept
|
||||||
|
an embargo longer than 19 days.
|
||||||
|
|
||||||
|
- Update the "security advisory" with the CVE number.
|
||||||
|
|
||||||
|
- The security team commits the fix in a private branch. The commit message
|
||||||
|
should ideally contain the CVE number. This fix is usually also distributed
|
||||||
|
to the 'distros' mailing list to allow them to use the fix prior to the
|
||||||
|
public announcement.
|
||||||
|
|
||||||
|
- At the day of the next release, the private branch is merged into the master
|
||||||
|
branch and pushed. Once pushed, the information is accessible to the public
|
||||||
|
and the actual release should follow suit immediately afterwards.
|
||||||
|
|
||||||
|
- The project team creates a release that includes the fix.
|
||||||
|
|
||||||
|
- The project team announces the release and the vulnerability to the world in
|
||||||
|
the same manner we always announce releases. It gets sent to the
|
||||||
|
curl-announce, curl-library and curl-users mailing lists.
|
||||||
|
|
||||||
|
- The security web page on the web site should get the new vulernability
|
||||||
|
mentioned.
|
||||||
|
|
||||||
|
[1] = http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||||
47
docs/THANKS
47
docs/THANKS
@@ -27,6 +27,7 @@ Alessandro Vesely
|
|||||||
Alex Bligh
|
Alex Bligh
|
||||||
Alex Fishman
|
Alex Fishman
|
||||||
Alex Gruz
|
Alex Gruz
|
||||||
|
Alex McLellan
|
||||||
Alex Neblett
|
Alex Neblett
|
||||||
Alex Suykov
|
Alex Suykov
|
||||||
Alex Vinnik
|
Alex Vinnik
|
||||||
@@ -62,6 +63,7 @@ Andreas Schuldei
|
|||||||
Andreas Wurf
|
Andreas Wurf
|
||||||
Andrei Benea
|
Andrei Benea
|
||||||
Andrei Cipu
|
Andrei Cipu
|
||||||
|
Andrej E Baranov
|
||||||
Andres Garcia
|
Andres Garcia
|
||||||
Andrew Benham
|
Andrew Benham
|
||||||
Andrew Biggs
|
Andrew Biggs
|
||||||
@@ -109,9 +111,11 @@ Benbuck Nason
|
|||||||
Benjamin Gerard
|
Benjamin Gerard
|
||||||
Benjamin Gilbert
|
Benjamin Gilbert
|
||||||
Benjamin Johnson
|
Benjamin Johnson
|
||||||
|
Benoit Sigoure
|
||||||
Bernard Leak
|
Bernard Leak
|
||||||
Bernhard Reutner-Fischer
|
Bernhard Reutner-Fischer
|
||||||
Bertrand Demiddelaer
|
Bertrand Demiddelaer
|
||||||
|
Bill Doyle
|
||||||
Bill Egert
|
Bill Egert
|
||||||
Bill Hoffman
|
Bill Hoffman
|
||||||
Bill Middlecamp
|
Bill Middlecamp
|
||||||
@@ -154,6 +158,7 @@ Charles Kerr
|
|||||||
Chih-Chung Chang
|
Chih-Chung Chang
|
||||||
Chris "Bob Bob"
|
Chris "Bob Bob"
|
||||||
Chris Combes
|
Chris Combes
|
||||||
|
Chris Conlon
|
||||||
Chris Conroy
|
Chris Conroy
|
||||||
Chris Deidun
|
Chris Deidun
|
||||||
Chris Flerackers
|
Chris Flerackers
|
||||||
@@ -181,6 +186,7 @@ Clarence Gardner
|
|||||||
Clemens Gruber
|
Clemens Gruber
|
||||||
Clifford Wolf
|
Clifford Wolf
|
||||||
Cody Jones
|
Cody Jones
|
||||||
|
Colby Ranger
|
||||||
Colin Hogben
|
Colin Hogben
|
||||||
Colin Watson
|
Colin Watson
|
||||||
Colm Buckley
|
Colm Buckley
|
||||||
@@ -194,6 +200,7 @@ Cristian Rodríguez
|
|||||||
Curt Bogmine
|
Curt Bogmine
|
||||||
Cyrill Osterwalder
|
Cyrill Osterwalder
|
||||||
Cédric Deltheil
|
Cédric Deltheil
|
||||||
|
D. Flinkmann
|
||||||
Dag Ekengren
|
Dag Ekengren
|
||||||
Dagobert Michelsen
|
Dagobert Michelsen
|
||||||
Damien Adant
|
Damien Adant
|
||||||
@@ -221,6 +228,7 @@ Dave Halbakken
|
|||||||
Dave Hamilton
|
Dave Hamilton
|
||||||
Dave May
|
Dave May
|
||||||
Dave Reisner
|
Dave Reisner
|
||||||
|
Dave Thompson
|
||||||
Dave Vasilevsky
|
Dave Vasilevsky
|
||||||
David Bau
|
David Bau
|
||||||
David Binderman
|
David Binderman
|
||||||
@@ -244,13 +252,16 @@ David Shaw
|
|||||||
David Strauss
|
David Strauss
|
||||||
David Tarendash
|
David Tarendash
|
||||||
David Thiel
|
David Thiel
|
||||||
|
David Walser
|
||||||
David Wright
|
David Wright
|
||||||
David Yan
|
David Yan
|
||||||
Dengminwen
|
Dengminwen
|
||||||
|
Derek Higgins
|
||||||
Detlef Schmier
|
Detlef Schmier
|
||||||
Didier Brisebourg
|
Didier Brisebourg
|
||||||
Diego Casorran
|
Diego Casorran
|
||||||
Dima Barsky
|
Dima Barsky
|
||||||
|
Dima Tisnek
|
||||||
Dimitre Dimitrov
|
Dimitre Dimitrov
|
||||||
Dimitris Sarris
|
Dimitris Sarris
|
||||||
Dinar
|
Dinar
|
||||||
@@ -289,6 +300,7 @@ Eelco Dolstra
|
|||||||
Eetu Ojanen
|
Eetu Ojanen
|
||||||
Eldar Zaitov
|
Eldar Zaitov
|
||||||
Ellis Pritchard
|
Ellis Pritchard
|
||||||
|
Elmira A Semenova
|
||||||
Emanuele Bovisio
|
Emanuele Bovisio
|
||||||
Emil Romanus
|
Emil Romanus
|
||||||
Emiliano Ida
|
Emiliano Ida
|
||||||
@@ -298,6 +310,7 @@ Eric Cooper
|
|||||||
Eric Hu
|
Eric Hu
|
||||||
Eric Landes
|
Eric Landes
|
||||||
Eric Lavigne
|
Eric Lavigne
|
||||||
|
Eric Lubin
|
||||||
Eric Melville
|
Eric Melville
|
||||||
Eric Mertens
|
Eric Mertens
|
||||||
Eric Rautman
|
Eric Rautman
|
||||||
@@ -318,10 +331,12 @@ Fabian Hiernaux
|
|||||||
Fabian Keil
|
Fabian Keil
|
||||||
Fabrizio Ammollo
|
Fabrizio Ammollo
|
||||||
Fedor Karpelevitch
|
Fedor Karpelevitch
|
||||||
|
Felix Yan
|
||||||
Felix von Leitner
|
Felix von Leitner
|
||||||
Feng Tu
|
Feng Tu
|
||||||
Florian Schoppmann
|
Florian Schoppmann
|
||||||
Forrest Cahoon
|
Forrest Cahoon
|
||||||
|
Francois Charlier
|
||||||
Frank Hempel
|
Frank Hempel
|
||||||
Frank Keeney
|
Frank Keeney
|
||||||
Frank McGeough
|
Frank McGeough
|
||||||
@@ -342,11 +357,13 @@ Gautam Kachroo
|
|||||||
Gautam Mani
|
Gautam Mani
|
||||||
Gavrie Philipson
|
Gavrie Philipson
|
||||||
Gaz Iqbal
|
Gaz Iqbal
|
||||||
|
Geoff Beier
|
||||||
Georg Horn
|
Georg Horn
|
||||||
Georg Huettenegger
|
Georg Huettenegger
|
||||||
Georg Lippitsch
|
Georg Lippitsch
|
||||||
Georg Wicherski
|
Georg Wicherski
|
||||||
Gerd v. Egidy
|
Gerd v. Egidy
|
||||||
|
Gergely Nagy
|
||||||
Gerhard Herre
|
Gerhard Herre
|
||||||
Gerrit Bruchhäuser
|
Gerrit Bruchhäuser
|
||||||
Ghennadi Procopciuc
|
Ghennadi Procopciuc
|
||||||
@@ -362,6 +379,8 @@ Giuseppe D'Ambrosio
|
|||||||
Glen Nakamura
|
Glen Nakamura
|
||||||
Glen Scott
|
Glen Scott
|
||||||
Gokhan Sengun
|
Gokhan Sengun
|
||||||
|
Gordon Marler
|
||||||
|
Gorilla Maguila
|
||||||
Grant Erickson
|
Grant Erickson
|
||||||
Greg Hewgill
|
Greg Hewgill
|
||||||
Greg Morse
|
Greg Morse
|
||||||
@@ -384,8 +403,10 @@ Hans-Jurgen May
|
|||||||
Hardeep Singh
|
Hardeep Singh
|
||||||
Harshal Pradhan
|
Harshal Pradhan
|
||||||
Hauke Duden
|
Hauke Duden
|
||||||
|
He Qin
|
||||||
Heikki Korpela
|
Heikki Korpela
|
||||||
Heinrich Ko
|
Heinrich Ko
|
||||||
|
Heinrich Schaefer
|
||||||
Hendrik Visage
|
Hendrik Visage
|
||||||
Henrik Storner
|
Henrik Storner
|
||||||
Henry Ludemann
|
Henry Ludemann
|
||||||
@@ -422,6 +443,7 @@ James Bursa
|
|||||||
James Cheng
|
James Cheng
|
||||||
James Clancy
|
James Clancy
|
||||||
James Cone
|
James Cone
|
||||||
|
James Dury
|
||||||
James Gallagher
|
James Gallagher
|
||||||
James Griffiths
|
James Griffiths
|
||||||
James Housley
|
James Housley
|
||||||
@@ -441,6 +463,7 @@ Jason Glasgow
|
|||||||
Jason Liu
|
Jason Liu
|
||||||
Jason McDonald
|
Jason McDonald
|
||||||
Jason S. Priebe
|
Jason S. Priebe
|
||||||
|
Javier Barroso
|
||||||
Jay Austin
|
Jay Austin
|
||||||
Jayesh A Shah
|
Jayesh A Shah
|
||||||
Jaz Fresh
|
Jaz Fresh
|
||||||
@@ -453,6 +476,7 @@ Jean-Noel Rouvignac
|
|||||||
Jean-Philippe Barrette-LaPierre
|
Jean-Philippe Barrette-LaPierre
|
||||||
Jeff Connelly
|
Jeff Connelly
|
||||||
Jeff Johnson
|
Jeff Johnson
|
||||||
|
Jeff King
|
||||||
Jeff Lawson
|
Jeff Lawson
|
||||||
Jeff Phillips
|
Jeff Phillips
|
||||||
Jeff Pohlmeyer
|
Jeff Pohlmeyer
|
||||||
@@ -462,6 +486,7 @@ Jeremy Friesner
|
|||||||
Jeremy Huddleston
|
Jeremy Huddleston
|
||||||
Jerome Muffat-Meridol
|
Jerome Muffat-Meridol
|
||||||
Jerome Vouillon
|
Jerome Vouillon
|
||||||
|
Jerry Krinock
|
||||||
Jerry Wu
|
Jerry Wu
|
||||||
Jes Badwal
|
Jes Badwal
|
||||||
Jesper Jensen
|
Jesper Jensen
|
||||||
@@ -486,6 +511,7 @@ Johannes Bauer
|
|||||||
John Bradshaw
|
John Bradshaw
|
||||||
John Crow
|
John Crow
|
||||||
John Dennis
|
John Dennis
|
||||||
|
John Dunn
|
||||||
John E. Malmberg
|
John E. Malmberg
|
||||||
John Gardiner Myers
|
John Gardiner Myers
|
||||||
John Janssen
|
John Janssen
|
||||||
@@ -569,6 +595,7 @@ Krishnendu Majumdar
|
|||||||
Krister Johansen
|
Krister Johansen
|
||||||
Kristian Gunstone
|
Kristian Gunstone
|
||||||
Kristian Köhntopp
|
Kristian Köhntopp
|
||||||
|
Kyle L. Huff
|
||||||
Kyle Sallee
|
Kyle Sallee
|
||||||
Lachlan O'Dea
|
Lachlan O'Dea
|
||||||
Larry Campbell
|
Larry Campbell
|
||||||
@@ -611,6 +638,7 @@ Mandy Wu
|
|||||||
Manfred Schwarb
|
Manfred Schwarb
|
||||||
Manuel Massing
|
Manuel Massing
|
||||||
Marc Boucher
|
Marc Boucher
|
||||||
|
Marc Deslauriers
|
||||||
Marc Doughty
|
Marc Doughty
|
||||||
Marc Hoersken
|
Marc Hoersken
|
||||||
Marc Kleine-Budde
|
Marc Kleine-Budde
|
||||||
@@ -618,6 +646,7 @@ Marcel Raad
|
|||||||
Marcel Roelofs
|
Marcel Roelofs
|
||||||
Marcelo Juchem
|
Marcelo Juchem
|
||||||
Marcin Adamski
|
Marcin Adamski
|
||||||
|
Marcin Gryszkalis
|
||||||
Marcin Konicki
|
Marcin Konicki
|
||||||
Marco G. Salvagno
|
Marco G. Salvagno
|
||||||
Marco Maggi
|
Marco Maggi
|
||||||
@@ -672,6 +701,7 @@ Maxim Prohorov
|
|||||||
Maxime Larocque
|
Maxime Larocque
|
||||||
Mehmet Bozkurt
|
Mehmet Bozkurt
|
||||||
Mekonikum
|
Mekonikum
|
||||||
|
Melissa Mears
|
||||||
Mettgut Jamalla
|
Mettgut Jamalla
|
||||||
Michael Benedict
|
Michael Benedict
|
||||||
Michael Calmer
|
Michael Calmer
|
||||||
@@ -683,6 +713,7 @@ Michael Jahn
|
|||||||
Michael Jerris
|
Michael Jerris
|
||||||
Michael Mealling
|
Michael Mealling
|
||||||
Michael Mueller
|
Michael Mueller
|
||||||
|
Michael Osipov
|
||||||
Michael Smith
|
Michael Smith
|
||||||
Michael Stillwell
|
Michael Stillwell
|
||||||
Michael Wallner
|
Michael Wallner
|
||||||
@@ -700,6 +731,7 @@ Mike Crowe
|
|||||||
Mike Dobbs
|
Mike Dobbs
|
||||||
Mike Giancola
|
Mike Giancola
|
||||||
Mike Hommey
|
Mike Hommey
|
||||||
|
Mike Mio
|
||||||
Mike Power
|
Mike Power
|
||||||
Mike Protts
|
Mike Protts
|
||||||
Mike Revi
|
Mike Revi
|
||||||
@@ -744,6 +776,7 @@ Olaf Flebbe
|
|||||||
Olaf Stueben
|
Olaf Stueben
|
||||||
Olaf Stüben
|
Olaf Stüben
|
||||||
Oliver Gondža
|
Oliver Gondža
|
||||||
|
Oliver Kuckertz
|
||||||
Olivier Berger
|
Olivier Berger
|
||||||
Oren Tirosh
|
Oren Tirosh
|
||||||
Ori Avtalion
|
Ori Avtalion
|
||||||
@@ -762,8 +795,10 @@ Patrick Scott
|
|||||||
Patrick Smith
|
Patrick Smith
|
||||||
Patrik Thunstrom
|
Patrik Thunstrom
|
||||||
Pau Garcia i Quiles
|
Pau Garcia i Quiles
|
||||||
|
Paul Donohue
|
||||||
Paul Harrington
|
Paul Harrington
|
||||||
Paul Howarth
|
Paul Howarth
|
||||||
|
Paul Marks
|
||||||
Paul Marquis
|
Paul Marquis
|
||||||
Paul Moore
|
Paul Moore
|
||||||
Paul Nolan
|
Paul Nolan
|
||||||
@@ -792,6 +827,8 @@ Peter Todd
|
|||||||
Peter Verhas
|
Peter Verhas
|
||||||
Peter Wullinger
|
Peter Wullinger
|
||||||
Peteris Krumins
|
Peteris Krumins
|
||||||
|
Petr Bahula
|
||||||
|
Petr Pisar
|
||||||
Phil Blundell
|
Phil Blundell
|
||||||
Phil Karn
|
Phil Karn
|
||||||
Phil Lisiecki
|
Phil Lisiecki
|
||||||
@@ -875,6 +912,7 @@ Roland Zimmermann
|
|||||||
Rolland Dudemaine
|
Rolland Dudemaine
|
||||||
Roman Koifman
|
Roman Koifman
|
||||||
Roman Mamedov
|
Roman Mamedov
|
||||||
|
Romulo A. Ceccon
|
||||||
Ron Zapp
|
Ron Zapp
|
||||||
Rosimildo da Silva
|
Rosimildo da Silva
|
||||||
Roy Shan
|
Roy Shan
|
||||||
@@ -884,6 +922,7 @@ Rutger Hofman
|
|||||||
Ryan Chan
|
Ryan Chan
|
||||||
Ryan Nelson
|
Ryan Nelson
|
||||||
Ryan Schmidt
|
Ryan Schmidt
|
||||||
|
Rémy Léone
|
||||||
S. Moonesamy
|
S. Moonesamy
|
||||||
Salvador Dávila
|
Salvador Dávila
|
||||||
Salvatore Sorrentino
|
Salvatore Sorrentino
|
||||||
@@ -909,11 +948,13 @@ Sebastian Rasmussen
|
|||||||
Sebastien Willemijns
|
Sebastien Willemijns
|
||||||
Senthil Raja Velu
|
Senthil Raja Velu
|
||||||
Sergei Nikulov
|
Sergei Nikulov
|
||||||
|
Sergey Tatarincev
|
||||||
Sergio Ballestrero
|
Sergio Ballestrero
|
||||||
Seshubabu Pasam
|
Seshubabu Pasam
|
||||||
Sh Diao
|
Sh Diao
|
||||||
Sharad Gupta
|
Sharad Gupta
|
||||||
Shard
|
Shard
|
||||||
|
Shawn Landden
|
||||||
Shawn Poulson
|
Shawn Poulson
|
||||||
Shmulik Regev
|
Shmulik Regev
|
||||||
Siddhartha Prakash Jain
|
Siddhartha Prakash Jain
|
||||||
@@ -997,6 +1038,7 @@ Tom Mueller
|
|||||||
Tom Regner
|
Tom Regner
|
||||||
Tom Wright
|
Tom Wright
|
||||||
Tom Zerucha
|
Tom Zerucha
|
||||||
|
Tomas Hoger
|
||||||
Tomas Mlcoch
|
Tomas Mlcoch
|
||||||
Tomas Pospisek
|
Tomas Pospisek
|
||||||
Tomas Szepe
|
Tomas Szepe
|
||||||
@@ -1014,7 +1056,9 @@ Traian Nicolescu
|
|||||||
Troels Walsted Hansen
|
Troels Walsted Hansen
|
||||||
Troy Engel
|
Troy Engel
|
||||||
Tupone Alfredo
|
Tupone Alfredo
|
||||||
|
Tyler Hall
|
||||||
Ulf Härnhammar
|
Ulf Härnhammar
|
||||||
|
Ulf Samuelsson
|
||||||
Ulrich Doehner
|
Ulrich Doehner
|
||||||
Ulrich Zadow
|
Ulrich Zadow
|
||||||
Venkat Akella
|
Venkat Akella
|
||||||
@@ -1041,15 +1085,18 @@ Wesley Laxton
|
|||||||
Wesley Miaw
|
Wesley Miaw
|
||||||
Wez Furlong
|
Wez Furlong
|
||||||
Wilfredo Sanchez
|
Wilfredo Sanchez
|
||||||
|
Will Dietz
|
||||||
Willem Sparreboom
|
Willem Sparreboom
|
||||||
Wojciech Zwiefka
|
Wojciech Zwiefka
|
||||||
Wouter Van Rooy
|
Wouter Van Rooy
|
||||||
Wu Yongzheng
|
Wu Yongzheng
|
||||||
Xavier Bouchoux
|
Xavier Bouchoux
|
||||||
|
Yaakov Selkowitz
|
||||||
Yamada Yasuharu
|
Yamada Yasuharu
|
||||||
Yang Tse
|
Yang Tse
|
||||||
Yarram Sunil
|
Yarram Sunil
|
||||||
Yehoshua Hershberg
|
Yehoshua Hershberg
|
||||||
|
Yi Huang
|
||||||
Yukihiro Kawada
|
Yukihiro Kawada
|
||||||
Yuriy Sosov
|
Yuriy Sosov
|
||||||
Yves Arrouye
|
Yves Arrouye
|
||||||
|
|||||||
65
docs/TODO
65
docs/TODO
@@ -16,8 +16,7 @@
|
|||||||
1.3 struct lifreq
|
1.3 struct lifreq
|
||||||
1.4 signal-based resolver timeouts
|
1.4 signal-based resolver timeouts
|
||||||
1.5 get rid of PATH_MAX
|
1.5 get rid of PATH_MAX
|
||||||
1.6 Happy Eyeball dual stack connect
|
1.6 Modified buffer size approach
|
||||||
1.7 Modified buffer size approach
|
|
||||||
|
|
||||||
2. libcurl - multi interface
|
2. libcurl - multi interface
|
||||||
2.1 More non-blocking
|
2.1 More non-blocking
|
||||||
@@ -39,6 +38,7 @@
|
|||||||
5.2 support FF3 sqlite cookie files
|
5.2 support FF3 sqlite cookie files
|
||||||
5.3 Rearrange request header order
|
5.3 Rearrange request header order
|
||||||
5.4 HTTP2/SPDY
|
5.4 HTTP2/SPDY
|
||||||
|
5.5 auth= in URLs
|
||||||
|
|
||||||
6. TELNET
|
6. TELNET
|
||||||
6.1 ditch stdin
|
6.1 ditch stdin
|
||||||
@@ -48,17 +48,14 @@
|
|||||||
|
|
||||||
7. SMTP
|
7. SMTP
|
||||||
7.1 Pipelining
|
7.1 Pipelining
|
||||||
7.2 Graceful base64 decoding failure
|
7.2 Enhanced capability support
|
||||||
7.3 Enhanced capability support
|
|
||||||
|
|
||||||
8. POP3
|
8. POP3
|
||||||
8.1 Pipelining
|
8.1 Pipelining
|
||||||
8.2 Graceful base64 decoding failure
|
8.2 Enhanced capability support
|
||||||
8.3 Enhanced capability support
|
|
||||||
|
|
||||||
9. IMAP
|
9. IMAP
|
||||||
9.1 Graceful base64 decoding failure
|
9.1 Enhanced capability support
|
||||||
9.2 Enhanced capability support
|
|
||||||
|
|
||||||
10. LDAP
|
10. LDAP
|
||||||
10.1 SASL based authentication mechanisms
|
10.1 SASL based authentication mechanisms
|
||||||
@@ -157,19 +154,7 @@
|
|||||||
we need libssh2 to properly tell us when we pass in a too small buffer and
|
we need libssh2 to properly tell us when we pass in a too small buffer and
|
||||||
its current API (as of libssh2 1.2.7) doesn't.
|
its current API (as of libssh2 1.2.7) doesn't.
|
||||||
|
|
||||||
1.6 Happy Eyeball dual stack connect
|
1.6 Modified buffer size approach
|
||||||
|
|
||||||
In order to make alternative technologies not suffer when transitioning, like
|
|
||||||
when introducing IPv6 as an alternative to IPv4 and there are more than one
|
|
||||||
option existing simultaneously there are reasons to reconsider internal
|
|
||||||
choices.
|
|
||||||
|
|
||||||
To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs
|
|
||||||
to be addressed:
|
|
||||||
|
|
||||||
http://tools.ietf.org/html/rfc6555
|
|
||||||
|
|
||||||
1.7 Modified buffer size approach
|
|
||||||
|
|
||||||
Current libcurl allocates a fixed 16K size buffer for download and an
|
Current libcurl allocates a fixed 16K size buffer for download and an
|
||||||
additional 16K for upload. They are always unconditionally part of the easy
|
additional 16K for upload. They are always unconditionally part of the easy
|
||||||
@@ -300,6 +285,17 @@
|
|||||||
be a better option, either used directly or wrapped with a more spindly-like
|
be a better option, either used directly or wrapped with a more spindly-like
|
||||||
API.
|
API.
|
||||||
|
|
||||||
|
5.5 auth= in URLs
|
||||||
|
|
||||||
|
Add the ability to specify the preferred authentication mechanism to use by
|
||||||
|
using ;auth=<mech> in the login part of the URL.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
http://test:pass;auth=NTLM@example.com would be equivalent to specifing --user
|
||||||
|
test:pass;auth=NTLM or --user test:pass --ntlm from the command line.
|
||||||
|
|
||||||
|
Additionally this should be implemented for proxy base URLs as well.
|
||||||
|
|
||||||
6. TELNET
|
6. TELNET
|
||||||
|
|
||||||
@@ -331,14 +327,7 @@ to provide the data to send.
|
|||||||
|
|
||||||
Add support for pipelining emails.
|
Add support for pipelining emails.
|
||||||
|
|
||||||
7.2 Graceful base64 decoding failure
|
7.2 Enhanced capability support
|
||||||
|
|
||||||
Rather than shutting down the session and returning an error when the
|
|
||||||
decoding of a base64 encoded authentication response fails, we should
|
|
||||||
gracefully shutdown the authentication process by sending a * response to the
|
|
||||||
server as per RFC4954.
|
|
||||||
|
|
||||||
7.3 Enhanced capability support
|
|
||||||
|
|
||||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
capabilities returned from the EHLO command.
|
capabilities returned from the EHLO command.
|
||||||
@@ -349,28 +338,14 @@ to provide the data to send.
|
|||||||
|
|
||||||
Add support for pipelining commands.
|
Add support for pipelining commands.
|
||||||
|
|
||||||
8.2 Graceful base64 decoding failure
|
8.2 Enhanced capability support
|
||||||
|
|
||||||
Rather than shutting down the session and returning an error when the
|
|
||||||
decoding of a base64 encoded authentication response fails, we should
|
|
||||||
gracefully shutdown the authentication process by sending a * response to the
|
|
||||||
server as per RFC5034.
|
|
||||||
|
|
||||||
8.3 Enhanced capability support
|
|
||||||
|
|
||||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
capabilities returned from the CAPA command.
|
capabilities returned from the CAPA command.
|
||||||
|
|
||||||
9. IMAP
|
9. IMAP
|
||||||
|
|
||||||
9.1 Graceful base64 decoding failure
|
9.1 Enhanced capability support
|
||||||
|
|
||||||
Rather than shutting down the session and returning an error when the
|
|
||||||
decoding of a base64 encoded authentication response fails, we should
|
|
||||||
gracefully shutdown the authentication process by sending a * response to the
|
|
||||||
server as per RFC3501.
|
|
||||||
|
|
||||||
9.2 Enhanced capability support
|
|
||||||
|
|
||||||
Add the ability, for an application that uses libcurl, to obtain the list of
|
Add the ability, for an application that uses libcurl, to obtain the list of
|
||||||
capabilities returned from the CAPABILITY command.
|
capabilities returned from the CAPABILITY command.
|
||||||
|
|||||||
118
docs/curl.1
118
docs/curl.1
@@ -646,10 +646,10 @@ you can specify URLs that contain the letters {}[] without having them being
|
|||||||
interpreted by curl itself. Note that these letters are not normal legal URL
|
interpreted by curl itself. Note that these letters are not normal legal URL
|
||||||
contents but they should be encoded according to the URI standard.
|
contents but they should be encoded according to the URI standard.
|
||||||
.IP "-G, --get"
|
.IP "-G, --get"
|
||||||
When used, this option will make all data specified with \fI-d, --data\fP or
|
When used, this option will make all data specified with \fI-d, --data\fP,
|
||||||
\fI--data-binary\fP to be used in an HTTP GET request instead of the POST
|
\fI--data-binary\fP or \fI--data-urlencode\fP to be used in an HTTP GET
|
||||||
request that otherwise would be used. The data will be appended to the URL
|
request instead of the POST request that otherwise would be used. The data
|
||||||
with a '?' separator.
|
will be appended to the URL with a '?' separator.
|
||||||
|
|
||||||
If used in combination with -I, the POST data will instead be appended to the
|
If used in combination with -I, the POST data will instead be appended to the
|
||||||
URL with a HEAD request.
|
URL with a HEAD request.
|
||||||
@@ -711,6 +711,9 @@ cookies when they're closed down.
|
|||||||
(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
|
(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
|
||||||
server-specified Content-Disposition filename instead of extracting a filename
|
server-specified Content-Disposition filename instead of extracting a filename
|
||||||
from the URL.
|
from the URL.
|
||||||
|
|
||||||
|
There's no attempt to decode %-sequences (yet) in the provided file name, so
|
||||||
|
this option may provide you with rather unexpected file names.
|
||||||
.IP "-k, --insecure"
|
.IP "-k, --insecure"
|
||||||
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
||||||
and transfers. All SSL connections are attempted to be made secure by using
|
and transfers. All SSL connections are attempted to be made secure by using
|
||||||
@@ -722,16 +725,21 @@ See this online resource for further details:
|
|||||||
.IP "-K, --config <config file>"
|
.IP "-K, --config <config file>"
|
||||||
Specify which config file to read curl arguments from. The config file is a
|
Specify which config file to read curl arguments from. The config file is a
|
||||||
text file in which command line arguments can be written which then will be
|
text file in which command line arguments can be written which then will be
|
||||||
used as if they were written on the actual command line. Options and their
|
used as if they were written on the actual command line.
|
||||||
parameters must be specified on the same config file line, separated by
|
|
||||||
whitespace, colon, the equals sign or any combination thereof (however,
|
Options and their parameters must be specified on the same config file line,
|
||||||
the preferred separator is the equals sign). If the parameter is to contain
|
separated by whitespace, colon, or the equals sign. Long option names can
|
||||||
whitespace, the parameter must be enclosed within quotes. Within double
|
optionally be given in the config file without the initial double dashes and
|
||||||
quotes, the following escape sequences are available: \\\\, \\", \\t, \\n,
|
if so, the colon or equals characters can be used as separators. If the option
|
||||||
\\r and \\v. A backslash preceding any other letter is ignored. If the
|
is specified with one or two dashes, there can be no colon or equals character
|
||||||
first column of a config line is a '#' character, the rest of the line will be
|
between the option and its parameter.
|
||||||
treated as a comment. Only write one option per physical line in the config
|
|
||||||
file.
|
If the parameter is to contain whitespace, the parameter must be enclosed
|
||||||
|
within quotes. Within double quotes, the following escape sequences are
|
||||||
|
available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash preceding any other
|
||||||
|
letter is ignored. If the first column of a config line is a '#' character,
|
||||||
|
the rest of the line will be treated as a comment. Only write one option per
|
||||||
|
physical line in the config file.
|
||||||
|
|
||||||
Specify the filename to -K, --config as '-' to make curl read the file from
|
Specify the filename to -K, --config as '-' to make curl read the file from
|
||||||
stdin.
|
stdin.
|
||||||
@@ -742,9 +750,6 @@ line. So, it could look similar to this:
|
|||||||
|
|
||||||
url = "http://curl.haxx.se/docs/"
|
url = "http://curl.haxx.se/docs/"
|
||||||
|
|
||||||
Long option names can optionally be given in the config file without the
|
|
||||||
initial double dashes.
|
|
||||||
|
|
||||||
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
When curl is invoked, it always (unless \fI-q\fP is used) checks for a default
|
||||||
config file and uses it if found. The default config file is checked for in
|
config file and uses it if found. The default config file is checked for in
|
||||||
the following places in this order:
|
the following places in this order:
|
||||||
@@ -806,15 +811,23 @@ see if your curl supports it.
|
|||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-l, --list-only"
|
.IP "-l, --list-only"
|
||||||
(FTP)
|
(FTP)
|
||||||
When listing an FTP directory, this switch forces a name-only view.
|
When listing an FTP directory, this switch forces a name-only view. This is
|
||||||
Especially useful if you want to machine-parse the contents of an FTP
|
especially useful if the user wants to machine-parse the contents of an FTP
|
||||||
directory since the normal directory view doesn't use a standard look
|
directory since the normal directory view doesn't use a standard look or
|
||||||
or format.
|
format. When used like this, the option causes a NLST command to be sent to
|
||||||
|
the server instead of LIST.
|
||||||
|
|
||||||
This option causes an FTP NLST command to be sent. Some FTP servers
|
Note: Some FTP servers list only files in their response to NLST; they do not
|
||||||
list only files in their response to NLST; they do not include
|
include sub-directories and symbolic links.
|
||||||
subdirectories and symbolic links.
|
|
||||||
|
|
||||||
|
(POP3)
|
||||||
|
When retrieving a specific email from POP3, this switch forces a LIST command
|
||||||
|
to be performed instead of RETR. This is particularly useful if the user wants
|
||||||
|
to see if a specific message id exists on the server and what size it is.
|
||||||
|
|
||||||
|
Note: When combined with \fI-X, --request <command>\fP, this option can be used
|
||||||
|
to send an UIDL command instead, so the user may use the email's unique
|
||||||
|
identifier rather than it's message id to make the request. (Added in 7.21.5)
|
||||||
.IP "-L, --location"
|
.IP "-L, --location"
|
||||||
(HTTP/HTTPS) If the server reports that the requested page has moved to a
|
(HTTP/HTTPS) If the server reports that the requested page has moved to a
|
||||||
different location (indicated with a Location: header and a 3XX response code),
|
different location (indicated with a Location: header and a 3XX response code),
|
||||||
@@ -894,10 +907,18 @@ return with exit code 63.
|
|||||||
files this option has no effect even if the file transfer ends up being larger
|
files this option has no effect even if the file transfer ends up being larger
|
||||||
than this given limit. This concerns both FTP and HTTP transfers.
|
than this given limit. This concerns both FTP and HTTP transfers.
|
||||||
.IP "--mail-rcpt <address>"
|
.IP "--mail-rcpt <address>"
|
||||||
(SMTP) Specify a single address that the given mail should get sent to. This
|
(SMTP) Specify a single address, user name or mailing list name.
|
||||||
option can be used multiple times to specify many recipients.
|
|
||||||
|
|
||||||
(Added in 7.20.0)
|
When performing a mail transfer, the recipient should specify a valid email
|
||||||
|
address to send the mail to. (Added in 7.20.0)
|
||||||
|
|
||||||
|
When performing an address verification (VRFY command), the recipient should be
|
||||||
|
specified as the user name or user name and domain (as per Section 3.5 of
|
||||||
|
RFC5321). (Added in 7.34.0)
|
||||||
|
|
||||||
|
When performing a mailing list expand (EXPN command), the recipient should be
|
||||||
|
specified using the mailing list name, such as "Friends" or "London-Office".
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP "--max-redirs <num>"
|
.IP "--max-redirs <num>"
|
||||||
Set maximum number of redirection-followings allowed. If \fI-L, --location\fP
|
Set maximum number of redirection-followings allowed. If \fI-L, --location\fP
|
||||||
is used, this option can be used to prevent curl from following redirections
|
is used, this option can be used to prevent curl from following redirections
|
||||||
@@ -1053,11 +1074,15 @@ Consequentially, the file will be saved in the current working directory. If
|
|||||||
you want the file saved in a different directory, make sure you change current
|
you want the file saved in a different directory, make sure you change current
|
||||||
working directory before you invoke curl with the \fB-O, --remote-name\fP flag!
|
working directory before you invoke curl with the \fB-O, --remote-name\fP flag!
|
||||||
|
|
||||||
|
There is no URL decoding done on the file name. If it has %20 or other URL
|
||||||
|
encoded parts of the name, they will end up as-is as file name.
|
||||||
|
|
||||||
You may use this option as many times as the number of URLs you have.
|
You may use this option as many times as the number of URLs you have.
|
||||||
.IP "--oauth2-bearer"
|
.IP "--oauth2-bearer"
|
||||||
(IMAP/POP3/SMTP) Specify the Bearer Token for OAUTH 2.0 server authentication.
|
(IMAP, POP3, SMTP)
|
||||||
The Bearer Token is used in conjuction with the user name which can be
|
Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token
|
||||||
specified as part of the \fI--url\fP or \fI-u, --user\fP options.
|
is used in conjunction with the user name which can be specified as part of the
|
||||||
|
\fI--url\fP or \fI-u, --user\fP options.
|
||||||
|
|
||||||
The Bearer Token and user name are formatted according to RFC 6750.
|
The Bearer Token and user name are formatted according to RFC 6750.
|
||||||
|
|
||||||
@@ -1498,14 +1523,26 @@ Set TLS authentication type. Currently, the only supported option is "SRP",
|
|||||||
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
|
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
|
||||||
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
|
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
|
||||||
(Added in 7.21.4)
|
(Added in 7.21.4)
|
||||||
.IP "--tlsuser <user>"
|
|
||||||
Set username for use with the TLS authentication method specified with
|
|
||||||
\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
|
|
||||||
7.21.4)
|
|
||||||
.IP "--tlspassword <password>"
|
.IP "--tlspassword <password>"
|
||||||
Set password for use with the TLS authentication method specified with
|
Set password for use with the TLS authentication method specified with
|
||||||
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
|
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
|
||||||
7.21.4)
|
7.21.4)
|
||||||
|
.IP "--tlsuser <user>"
|
||||||
|
Set username for use with the TLS authentication method specified with
|
||||||
|
\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
|
||||||
|
7.21.4)
|
||||||
|
.IP "--tlsv1.0"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.0 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
|
.IP "--tlsv1.1"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.1 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
|
.IP "--tlsv1.2"
|
||||||
|
(SSL)
|
||||||
|
Forces curl to use TLS version 1.2 when negotiating with a remote TLS server.
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP "--tr-encoding"
|
.IP "--tr-encoding"
|
||||||
(HTTP) Request a compressed Transfer-Encoding response using one of the
|
(HTTP) Request a compressed Transfer-Encoding response using one of the
|
||||||
algorithms curl supports, and uncompress the data while receiving it.
|
algorithms curl supports, and uncompress the data while receiving it.
|
||||||
@@ -1761,8 +1798,17 @@ option.
|
|||||||
Specifies a custom FTP command to use instead of LIST when doing file lists
|
Specifies a custom FTP command to use instead of LIST when doing file lists
|
||||||
with FTP.
|
with FTP.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
(POP3)
|
||||||
|
Specifies a custom POP3 command to use instead of LIST or RETR. (Added in
|
||||||
|
7.26.0)
|
||||||
|
|
||||||
|
(IMAP)
|
||||||
|
Specifies a custom IMAP command to use insead of LIST. (Added in 7.30.0)
|
||||||
|
|
||||||
|
(SMTP)
|
||||||
|
Specifies a custom SMTP command to use instead of HELP or VRFY. (Added in 7.34.0)
|
||||||
|
|
||||||
|
If this option is used several times, the last one will be used.
|
||||||
.IP "--xattr"
|
.IP "--xattr"
|
||||||
When saving output to a file, this option tells curl to store certain file
|
When saving output to a file, this option tells curl to store certain file
|
||||||
metadata in extended file attributes. Currently, the URL is stored in the
|
metadata in extended file attributes. Currently, the URL is stored in the
|
||||||
@@ -2055,6 +2101,8 @@ RTSP: mismatch of Session Identifiers
|
|||||||
unable to parse FTP file list
|
unable to parse FTP file list
|
||||||
.IP 88
|
.IP 88
|
||||||
FTP chunk callback reported error
|
FTP chunk callback reported error
|
||||||
|
.IP 89
|
||||||
|
No connection available, the session will be queued
|
||||||
.IP XX
|
.IP XX
|
||||||
More error codes will appear here in future releases. The existing ones
|
More error codes will appear here in future releases. The existing ones
|
||||||
are meant to never change.
|
are meant to never change.
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
|
|||||||
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
||||||
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
|
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
|
||||||
multi-uv.c xmlstream.c usercertinmem.c
|
multi-uv.c xmlstream.c usercertinmem.c sessioninfo.c
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -59,7 +57,6 @@ int main(int argc, char **argv)
|
|||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
FILE * hd_src ;
|
FILE * hd_src ;
|
||||||
int hd ;
|
|
||||||
struct stat file_info;
|
struct stat file_info;
|
||||||
|
|
||||||
char *file;
|
char *file;
|
||||||
@@ -72,9 +69,7 @@ int main(int argc, char **argv)
|
|||||||
url = argv[2];
|
url = argv[2];
|
||||||
|
|
||||||
/* get the file size of the local file */
|
/* get the file size of the local file */
|
||||||
hd = open(file, O_RDONLY) ;
|
stat(file, &file_info);
|
||||||
fstat(hd, &file_info);
|
|
||||||
close(hd) ;
|
|
||||||
|
|
||||||
/* get a FILE * of the same file, could also be made with
|
/* get a FILE * of the same file, could also be made with
|
||||||
fdopen() from the previous descriptor, but hey this is just
|
fdopen() from the previous descriptor, but hey this is just
|
||||||
|
|||||||
105
docs/examples/sessioninfo.c
Normal file
105
docs/examples/sessioninfo.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2013, 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 http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* Note that this example currently requires cURL to be linked against
|
||||||
|
GnuTLS (and this program must also be linked against -lgnutls). */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
|
||||||
|
static CURL *curl;
|
||||||
|
|
||||||
|
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
|
{
|
||||||
|
const struct curl_tlssessioninfo *info;
|
||||||
|
unsigned int cert_list_size;
|
||||||
|
const gnutls_datum_t *chainp;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
(void)stream;
|
||||||
|
(void)ptr;
|
||||||
|
|
||||||
|
res = curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &info);
|
||||||
|
|
||||||
|
if(!res) {
|
||||||
|
switch(info->backend) {
|
||||||
|
case CURLSSLBACKEND_GNUTLS:
|
||||||
|
/* info->internals is now the gnutls_session_t */
|
||||||
|
chainp = gnutls_certificate_get_peers(info->internals, &cert_list_size);
|
||||||
|
if((chainp) && (cert_list_size)) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for(i = 0; i < cert_list_size; i++) {
|
||||||
|
gnutls_x509_crt_t cert;
|
||||||
|
gnutls_datum_t dn;
|
||||||
|
|
||||||
|
if(GNUTLS_E_SUCCESS == gnutls_x509_crt_init(&cert)) {
|
||||||
|
if(GNUTLS_E_SUCCESS ==
|
||||||
|
gnutls_x509_crt_import(cert, &chainp[i], GNUTLS_X509_FMT_DER)) {
|
||||||
|
if(GNUTLS_E_SUCCESS ==
|
||||||
|
gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &dn)) {
|
||||||
|
fprintf(stderr, "Certificate #%d: %.*s", i, dn.size, dn.data);
|
||||||
|
|
||||||
|
gnutls_free(dn.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CURLSSLBACKEND_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
if(curl) {
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||||
|
|
||||||
|
(void) curl_easy_perform(curl);
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -22,8 +22,9 @@
|
|||||||
/* Example using an in memory PEM user certificate and RSA key to retrieve an
|
/* Example using an in memory PEM user certificate and RSA key to retrieve an
|
||||||
* https page.
|
* https page.
|
||||||
* Written by Ishan SinghLevett, based on Theo Borm's cacertinmem.c.
|
* Written by Ishan SinghLevett, based on Theo Borm's cacertinmem.c.
|
||||||
* Note this example does not use a CA certificate, however one should be used
|
* Note that to maintain simplicity this example does not use a CA certificate
|
||||||
* if you want a properly secure connection
|
* for peer verification. However, some form of peer verification
|
||||||
|
* must be used in real circumstances when a secure connection is required.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
@@ -152,6 +153,18 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
|
|||||||
printf("Use Key failed\n");
|
printf("Use Key failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free resources that have been allocated by openssl functions */
|
||||||
|
if (bio)
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
if (kbio)
|
||||||
|
BIO_free(kbio);
|
||||||
|
|
||||||
|
if (rsa)
|
||||||
|
RSA_free(rsa);
|
||||||
|
|
||||||
|
if (cert)
|
||||||
|
X509_free(cert);
|
||||||
|
|
||||||
/* all set to go */
|
/* all set to go */
|
||||||
return CURLE_OK ;
|
return CURLE_OK ;
|
||||||
|
|||||||
@@ -79,9 +79,12 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
|||||||
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
||||||
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
|
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
|
||||||
|
|
||||||
|
m4macrodir = $(datadir)/aclocal
|
||||||
|
dist_m4macro_DATA = libcurl.m4
|
||||||
|
|
||||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||||
|
|
||||||
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \
|
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) ABI \
|
||||||
symbols-in-versions symbols.pl
|
symbols-in-versions symbols.pl
|
||||||
MAN2HTML= roffit --mandir=. < $< >$@
|
MAN2HTML= roffit --mandir=. < $< >$@
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
.\" * | (__| |_| | _ <| |___
|
.\" * | (__| |_| | _ <| |___
|
||||||
.\" * \___|\___/|_| \_\_____|
|
.\" * \___|\___/|_| \_\_____|
|
||||||
.\" *
|
.\" *
|
||||||
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
.\" * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
.\" *
|
.\" *
|
||||||
.\" * This software is licensed as described in the file COPYING, which
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
.\" * you should have received as part of this distribution. The terms
|
.\" * you should have received as part of this distribution. The terms
|
||||||
@@ -219,8 +219,20 @@ done. The struct reports how many certs it found and then you can extract info
|
|||||||
for each of those certs by following the linked lists. The info chain is
|
for each of those certs by following the linked lists. The info chain is
|
||||||
provided in a series of data in the format "name:content" where the content is
|
provided in a series of data in the format "name:content" where the content is
|
||||||
for the specific named data. See also the certinfo.c example. NOTE: this
|
for the specific named data. See also the certinfo.c example. NOTE: this
|
||||||
option is only available in libcurl built with OpenSSL support. (Added in
|
option is only available in libcurl built with OpenSSL, NSS, GSKit or QsoSSL
|
||||||
7.19.1)
|
support. (Added in 7.19.1)
|
||||||
|
.IP CURLINFO_TLS_SESSION
|
||||||
|
Pass a pointer to a 'struct curl_tlsinfo *'. The pointer will be initialized
|
||||||
|
to refer to a 'struct curl_tlsinfo *' that will contain an enum indicating the
|
||||||
|
SSL library used for the handshake and the respective internal TLS session
|
||||||
|
structure of this underlying SSL library.
|
||||||
|
|
||||||
|
This may then be used to extract certificate information in a format
|
||||||
|
convenient for further processing, such as manual validation. NOTE: this
|
||||||
|
option may not be available for all SSL backends; unsupported SSL backends
|
||||||
|
will return 'CURLSSLBACKEND_NONE' to indicate that they are not supported;
|
||||||
|
this does not mean that no SSL backend was used. (Added in 7.34.0)
|
||||||
|
|
||||||
.IP CURLINFO_CONDITION_UNMET
|
.IP CURLINFO_CONDITION_UNMET
|
||||||
Pass a pointer to a long to receive the number 1 if the condition provided in
|
Pass a pointer to a long to receive the number 1 if the condition provided in
|
||||||
the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
|
the previous request didn't match (see \fICURLOPT_TIMECONDITION\fP). Alas, if
|
||||||
|
|||||||
@@ -1131,7 +1131,7 @@ option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to
|
|||||||
find a .netrc file in the current user's home directory. (Added in 7.10.9)
|
find a .netrc file in the current user's home directory. (Added in 7.10.9)
|
||||||
.IP CURLOPT_USERPWD
|
.IP CURLOPT_USERPWD
|
||||||
Pass a char * as parameter, pointing to a zero terminated login details string
|
Pass a char * as parameter, pointing to a zero terminated login details string
|
||||||
for the connection. The format of which is: [user name]:[password];[options].
|
for the connection. The format of which is: [user name]:[password].
|
||||||
|
|
||||||
When using NTLM, you can set the domain by prepending it to the user name and
|
When using NTLM, you can set the domain by prepending it to the user name and
|
||||||
separating the domain and name with a forward (/) or backward slash (\\). Like
|
separating the domain and name with a forward (/) or backward slash (\\). Like
|
||||||
@@ -1145,15 +1145,18 @@ and password information to hosts using the initial host name (unless
|
|||||||
other hosts it will not send the user and password to those. This is enforced
|
other hosts it will not send the user and password to those. This is enforced
|
||||||
to prevent accidental information leakage.
|
to prevent accidental information leakage.
|
||||||
|
|
||||||
At present only IMAP, POP3 and SMTP support login options as part of the
|
|
||||||
details string. For more information about the login options please see
|
|
||||||
RFC2384, RFC5092 and IETF draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
|
|
||||||
|
|
||||||
Use \fICURLOPT_HTTPAUTH\fP to specify the authentication method for HTTP based
|
Use \fICURLOPT_HTTPAUTH\fP to specify the authentication method for HTTP based
|
||||||
connections.
|
connections or \fICURLOPT_LOGIN_OPTIONS\fP to control IMAP, POP3 and SMTP
|
||||||
|
options.
|
||||||
|
|
||||||
|
The user and password strings are not URL decoded, so there's no way to send
|
||||||
|
in a user name containing a colon using this option. Use \fCURLOPT_USERNAME\fP
|
||||||
|
for that, or include it in the URL.
|
||||||
.IP CURLOPT_PROXYUSERPWD
|
.IP CURLOPT_PROXYUSERPWD
|
||||||
Pass a char * as parameter, which should be [user name]:[password] to use for
|
Pass a char * as parameter, which should be [user name]:[password] to use for
|
||||||
the connection to the HTTP proxy.
|
the connection to the HTTP proxy. Both the name and the password will be URL
|
||||||
|
decoded before use, so to include for example a colon in the user name you
|
||||||
|
should encode it as %3A.
|
||||||
|
|
||||||
Use \fICURLOPT_PROXYAUTH\fP to specify the authentication method.
|
Use \fICURLOPT_PROXYAUTH\fP to specify the authentication method.
|
||||||
.IP CURLOPT_USERNAME
|
.IP CURLOPT_USERNAME
|
||||||
@@ -1164,14 +1167,26 @@ user name to use for the transfer.
|
|||||||
authentication. You should not use this option together with the (older)
|
authentication. You should not use this option together with the (older)
|
||||||
CURLOPT_USERPWD option.
|
CURLOPT_USERPWD option.
|
||||||
|
|
||||||
In order to specify the password to be used in conjunction with the user name
|
To specify the password and login options, along with the user name, use the
|
||||||
use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1)
|
\fICURLOPT_PASSWORD\fP and \fICURLOPT_LOGIN_OPTIONS\fP options. (Added in
|
||||||
|
7.19.1)
|
||||||
.IP CURLOPT_PASSWORD
|
.IP CURLOPT_PASSWORD
|
||||||
Pass a char * as parameter, which should be pointing to the zero terminated
|
Pass a char * as parameter, which should be pointing to the zero terminated
|
||||||
password to use for the transfer.
|
password to use for the transfer.
|
||||||
|
|
||||||
The CURLOPT_PASSWORD option should be used in conjunction with
|
The CURLOPT_PASSWORD option should be used in conjunction with the
|
||||||
the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
|
\fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
|
||||||
|
.IP CURLOPT_LOGIN_OPTIONS
|
||||||
|
(Added in 7.34.0) Pass a char * as parameter, which should be pointing to the
|
||||||
|
zero terminated options string to use for the transfer.
|
||||||
|
|
||||||
|
At present only IMAP, POP3 and SMTP support login options. For more
|
||||||
|
information about the login options please see RFC2384, RFC5092 and IETF draft
|
||||||
|
draft-earhart-url-smtp-00.txt
|
||||||
|
|
||||||
|
\CURLOPT_LOGIN_OPTIONS\fP can be used to set protocol specific login options,
|
||||||
|
such as the preferred authentication mechanism via "AUTH=NTLM" or "AUTH=*",
|
||||||
|
and should be used in conjunction with the \fICURLOPT_USERNAME\fP option.
|
||||||
.IP CURLOPT_PROXYUSERNAME
|
.IP CURLOPT_PROXYUSERNAME
|
||||||
Pass a char * as parameter, which should be pointing to the zero terminated
|
Pass a char * as parameter, which should be pointing to the zero terminated
|
||||||
user name to use for the transfer while connecting to Proxy.
|
user name to use for the transfer while connecting to Proxy.
|
||||||
@@ -1651,12 +1666,18 @@ SMTP mail request. The linked list should be a fully valid list of \fBstruct
|
|||||||
curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
|
curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
|
||||||
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire list.
|
||||||
|
|
||||||
Each recipient should be specified within a pair of angled brackets (<>),
|
When performing a mail transfer, each recipient should be specified within a
|
||||||
however, should you not use an angled bracket as the first character libcurl
|
pair of angled brackets (<>), however, should you not use an angled bracket as
|
||||||
will assume you provided a single email address and enclose that address
|
the first character libcurl will assume you provided a single email address and
|
||||||
within brackets for you.
|
enclose that address within brackets for you. (Added in 7.20.0)
|
||||||
|
|
||||||
(Added in 7.20.0)
|
When performing an address verification (VRFY command), each recipient should
|
||||||
|
be specified as the user name or user name and domain (as per Section 3.5 of
|
||||||
|
RFC5321). (Added in 7.34.0)
|
||||||
|
|
||||||
|
When performing a mailing list expand (EXPN command), each recipient should be
|
||||||
|
specified using the mailing list name, such as "Friends" or "London-Office".
|
||||||
|
(Added in 7.34.0)
|
||||||
.IP CURLOPT_MAIL_AUTH
|
.IP CURLOPT_MAIL_AUTH
|
||||||
Pass a pointer to a zero terminated string as parameter. This will be used
|
Pass a pointer to a zero terminated string as parameter. This will be used
|
||||||
to specify the authentication address (identity) of a submitted message that
|
to specify the authentication address (identity) of a submitted message that
|
||||||
@@ -2028,35 +2049,32 @@ source file to the remote target file.
|
|||||||
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
Pass a curl_off_t as parameter. It contains the offset in number of bytes that
|
||||||
you want the transfer to start from. (Added in 7.11.0)
|
you want the transfer to start from. (Added in 7.11.0)
|
||||||
.IP CURLOPT_CUSTOMREQUEST
|
.IP CURLOPT_CUSTOMREQUEST
|
||||||
Pass a pointer to a zero terminated string as parameter. It can be used to
|
Pass a pointer to a zero terminated string as parameter.
|
||||||
specify the request instead of GET or HEAD when performing HTTP based
|
|
||||||
requests, instead of LIST and NLST when performing FTP directory listings and
|
|
||||||
instead of LIST and RETR when issuing POP3 based commands. This is
|
|
||||||
particularly useful, for example, for performing a HTTP DELETE request or a
|
|
||||||
POP3 DELE command.
|
|
||||||
|
|
||||||
Please don't perform this at will, on HTTP based requests, by making sure
|
|
||||||
your server supports the command you are sending first.
|
|
||||||
|
|
||||||
When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
|
When you change the request method by setting \fBCURLOPT_CUSTOMREQUEST\fP to
|
||||||
something, you don't actually change how libcurl behaves or acts in regards
|
something, you don't actually change how libcurl behaves or acts in regards
|
||||||
to the particular request method, it will only change the actual string sent
|
to the particular request method, it will only change the actual string sent
|
||||||
in the request.
|
in the request.
|
||||||
|
|
||||||
|
Restore to the internal default by setting this to NULL.
|
||||||
|
|
||||||
|
This option can be used to specify the request:
|
||||||
|
|
||||||
|
.B HTTP
|
||||||
|
|
||||||
|
Instead of GET or HEAD when performing HTTP based requests. This is
|
||||||
|
particularly useful, for example, for performing a HTTP DELETE request.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
With the HTTP protocol when you tell libcurl to do a HEAD request, but then
|
When you tell libcurl to do a HEAD request, but then specify a GET though a
|
||||||
specify a GET though a custom request libcurl will still act as if it sent a
|
custom request libcurl will still act as if it sent a HEAD. To switch to a
|
||||||
HEAD. To switch to a proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a
|
proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a proper POST use
|
||||||
proper POST use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch
|
\fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch to a proper GET
|
||||||
to a proper GET use CURLOPT_HTTPGET.
|
use CURLOPT_HTTPGET.
|
||||||
|
|
||||||
With the POP3 protocol when you tell libcurl to use a custom request it will
|
Please don't perform this at will, on HTTP based requests, by making sure
|
||||||
behave like a LIST or RETR command was sent where it expects data to be
|
your server supports the command you are sending first.
|
||||||
returned by the server. As such \fICURLOPT_NOBODY\fP should be used when
|
|
||||||
specifying commands such as DELE and NOOP for example.
|
|
||||||
|
|
||||||
Restore to the internal default by setting this to NULL.
|
|
||||||
|
|
||||||
Many people have wrongly used this option to replace the entire request with
|
Many people have wrongly used this option to replace the entire request with
|
||||||
their own, including multiple headers and POST contents. While that might
|
their own, including multiple headers and POST contents. While that might
|
||||||
@@ -2066,7 +2084,35 @@ could possibly confuse the remote server badly. Use \fICURLOPT_POST\fP and
|
|||||||
replace or extend the set of headers sent by libcurl. Use
|
replace or extend the set of headers sent by libcurl. Use
|
||||||
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
\fICURLOPT_HTTP_VERSION\fP to change HTTP version.
|
||||||
|
|
||||||
(Support for POP3 added in 7.26.0)
|
.B FTP
|
||||||
|
|
||||||
|
Instead of LIST and NLST when performing FTP directory listings.
|
||||||
|
|
||||||
|
.B IMAP
|
||||||
|
|
||||||
|
Instead of LIST when issuing IMAP based requests. (Added in 7.30.0)
|
||||||
|
|
||||||
|
.B POP3
|
||||||
|
|
||||||
|
Instead of LIST and RETR when issuing POP3 based requests. (Added in 7.26.0)
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
When you tell libcurl to use a custom request it will behave like a LIST or
|
||||||
|
RETR command was sent where it expects data to be returned by the server. As
|
||||||
|
such \fICURLOPT_NOBODY\fP should be used when specifying commands such as
|
||||||
|
DELE and NOOP for example.
|
||||||
|
|
||||||
|
.B SMTP
|
||||||
|
|
||||||
|
Instead of a HELP or VRFY when issuing SMTP based requests. (Added in 7.34.0)
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
Normally a multiline response is returned which can be used, in conjuection with
|
||||||
|
\fICURLOPT_MAIL_RCPT\fP, to specify an EXPN request. If the \fICURLOPT_NOBODY\fP
|
||||||
|
option is specified then the request can be used to issue NOOP and RSET
|
||||||
|
commands.
|
||||||
.IP CURLOPT_FILETIME
|
.IP CURLOPT_FILETIME
|
||||||
Pass a long. If it is 1, libcurl will attempt to get the modification date of
|
Pass a long. If it is 1, libcurl will attempt to get the modification date of
|
||||||
the remote document in this operation. This requires that the remote server
|
the remote document in this operation. This requires that the remote server
|
||||||
@@ -2293,7 +2339,9 @@ ADDRESS can of course be either IPv4 or IPv6 style addressing.
|
|||||||
|
|
||||||
This option effectively pre-populates the DNS cache with entries for the
|
This option effectively pre-populates the DNS cache with entries for the
|
||||||
host+port pair so redirects and everything that operations against the
|
host+port pair so redirects and everything that operations against the
|
||||||
HOST+PORT will instead use your provided ADDRESS.
|
HOST+PORT will instead use your provided ADDRESS. Addresses to set with
|
||||||
|
\fICURL_RESOLVE\fP will not time-out from the DNS cache like ordindary
|
||||||
|
entries.
|
||||||
|
|
||||||
You can remove names from the DNS cache again, to stop providing these fake
|
You can remove names from the DNS cache again, to stop providing these fake
|
||||||
resolves, by including a string in the linked list that uses the format
|
resolves, by including a string in the linked list that uses the format
|
||||||
@@ -2364,7 +2412,7 @@ prefix, in order to avoid confusion with a nickname.
|
|||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||||
the format of your certificate. Supported formats are "PEM" and "DER", except
|
the format of your certificate. Supported formats are "PEM" and "DER", except
|
||||||
with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport
|
with Secure Transport. OpenSSL (versions 0.9.3 and later) and Secure Transport
|
||||||
(on iOS 5 or later, or OS X 10.6 or later) also support "P12" for
|
(on iOS 5 or later, or OS X 10.7 or later) also support "P12" for
|
||||||
PKCS#12-encoded files. (Added in 7.9.3)
|
PKCS#12-encoded files. (Added in 7.9.3)
|
||||||
.IP CURLOPT_SSLKEY
|
.IP CURLOPT_SSLKEY
|
||||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||||
@@ -2410,6 +2458,8 @@ Even though this option doesn't need any parameter, in some configurations
|
|||||||
arguments. Therefore, it's recommended to pass 1 as parameter to this option.
|
arguments. Therefore, it's recommended to pass 1 as parameter to this option.
|
||||||
.IP CURLOPT_SSLVERSION
|
.IP CURLOPT_SSLVERSION
|
||||||
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
Pass a long as parameter to control what version of SSL/TLS to attempt to use.
|
||||||
|
(Added in 7.9.2)
|
||||||
|
|
||||||
The available options are:
|
The available options are:
|
||||||
.RS
|
.RS
|
||||||
.IP CURL_SSLVERSION_DEFAULT
|
.IP CURL_SSLVERSION_DEFAULT
|
||||||
@@ -2417,11 +2467,17 @@ The default action. This will attempt to figure out the remote SSL protocol
|
|||||||
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
|
version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled
|
||||||
by default with 7.18.1).
|
by default with 7.18.1).
|
||||||
.IP CURL_SSLVERSION_TLSv1
|
.IP CURL_SSLVERSION_TLSv1
|
||||||
Force TLSv1
|
Force TLSv1.x
|
||||||
.IP CURL_SSLVERSION_SSLv2
|
.IP CURL_SSLVERSION_SSLv2
|
||||||
Force SSLv2
|
Force SSLv2
|
||||||
.IP CURL_SSLVERSION_SSLv3
|
.IP CURL_SSLVERSION_SSLv3
|
||||||
Force SSLv3
|
Force SSLv3
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_0
|
||||||
|
Force TLSv1.0 (Added in 7.34.0)
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_1
|
||||||
|
Force TLSv1.1 (Added in 7.34.0)
|
||||||
|
.IP CURL_SSLVERSION_TLSv1_2
|
||||||
|
Force TLSv1.2 (Added in 7.34.0)
|
||||||
.RE
|
.RE
|
||||||
.IP CURLOPT_SSL_VERIFYPEER
|
.IP CURLOPT_SSL_VERIFYPEER
|
||||||
Pass a long as parameter. By default, curl assumes a value of 1.
|
Pass a long as parameter. By default, curl assumes a value of 1.
|
||||||
@@ -2522,9 +2578,10 @@ Curl considers the server the intended one when the Common Name field or a
|
|||||||
Subject Alternate Name field in the certificate matches the host name in the
|
Subject Alternate Name field in the certificate matches the host name in the
|
||||||
URL to which you told Curl to connect.
|
URL to which you told Curl to connect.
|
||||||
|
|
||||||
When the value is 1, libcurl will return a failure. It was previously (in
|
When the value is 1, \fIcurl_easy_setopt\fP will return an error and the option
|
||||||
7.28.0 and earlier) a debug option of some sorts, but it is no longer
|
value will not be changed. It was previously (in 7.28.0 and earlier) a debug
|
||||||
supported due to frequently leading to programmer mistakes.
|
option of some sorts, but it is no longer supported due to frequently leading
|
||||||
|
to programmer mistakes.
|
||||||
|
|
||||||
When the value is 0, the connection succeeds regardless of the names in the
|
When the value is 0, the connection succeeds regardless of the names in the
|
||||||
certificate.
|
certificate.
|
||||||
@@ -2534,14 +2591,14 @@ The default value for this option is 2.
|
|||||||
This option controls checking the server's certificate's claimed identity.
|
This option controls checking the server's certificate's claimed identity.
|
||||||
The server could be lying. To control lying, see
|
The server could be lying. To control lying, see
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
|
\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
|
||||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP
|
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP is also set
|
||||||
is ignored.
|
to zero and cannot be overridden.
|
||||||
|
|
||||||
.IP CURLOPT_CERTINFO
|
.IP CURLOPT_CERTINFO
|
||||||
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
||||||
this enabled, libcurl (if built with OpenSSL) will extract lots of information
|
this enabled, libcurl (if built with OpenSSL, NSS, GSKit or QsoSSL) will
|
||||||
|
extract lots of information
|
||||||
and data about the certificates in the certificate chain used in the SSL
|
and data about the certificates in the certificate chain used in the SSL
|
||||||
connection. This data is then possible to extract after a transfer using
|
connection. This data may then be retrieved after a transfer using
|
||||||
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
||||||
7.19.1)
|
7.19.1)
|
||||||
.IP CURLOPT_RANDOM_FILE
|
.IP CURLOPT_RANDOM_FILE
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ CURLINFO_SSL_VERIFYRESULT 7.5
|
|||||||
CURLINFO_STARTTRANSFER_TIME 7.9.2
|
CURLINFO_STARTTRANSFER_TIME 7.9.2
|
||||||
CURLINFO_STRING 7.4.1
|
CURLINFO_STRING 7.4.1
|
||||||
CURLINFO_TEXT 7.9.6
|
CURLINFO_TEXT 7.9.6
|
||||||
|
CURLINFO_TLS_SESSION 7.34.0
|
||||||
CURLINFO_TOTAL_TIME 7.4.1
|
CURLINFO_TOTAL_TIME 7.4.1
|
||||||
CURLINFO_TYPEMASK 7.4.1
|
CURLINFO_TYPEMASK 7.4.1
|
||||||
CURLIOCMD_NOP 7.12.3
|
CURLIOCMD_NOP 7.12.3
|
||||||
@@ -394,6 +395,7 @@ CURLOPT_KRB4LEVEL 7.3 7.17.0
|
|||||||
CURLOPT_KRBLEVEL 7.16.4
|
CURLOPT_KRBLEVEL 7.16.4
|
||||||
CURLOPT_LOCALPORT 7.15.2
|
CURLOPT_LOCALPORT 7.15.2
|
||||||
CURLOPT_LOCALPORTRANGE 7.15.2
|
CURLOPT_LOCALPORTRANGE 7.15.2
|
||||||
|
CURLOPT_LOGIN_OPTIONS 7.34.0
|
||||||
CURLOPT_LOW_SPEED_LIMIT 7.1
|
CURLOPT_LOW_SPEED_LIMIT 7.1
|
||||||
CURLOPT_LOW_SPEED_TIME 7.1
|
CURLOPT_LOW_SPEED_TIME 7.1
|
||||||
CURLOPT_MAIL_AUTH 7.25.0
|
CURLOPT_MAIL_AUTH 7.25.0
|
||||||
@@ -593,6 +595,16 @@ CURLSSH_AUTH_KEYBOARD 7.16.1
|
|||||||
CURLSSH_AUTH_NONE 7.16.1
|
CURLSSH_AUTH_NONE 7.16.1
|
||||||
CURLSSH_AUTH_PASSWORD 7.16.1
|
CURLSSH_AUTH_PASSWORD 7.16.1
|
||||||
CURLSSH_AUTH_PUBLICKEY 7.16.1
|
CURLSSH_AUTH_PUBLICKEY 7.16.1
|
||||||
|
CURLSSLBACKEND_CYASSL 7.34.0
|
||||||
|
CURLSSLBACKEND_DARWINSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_GNUTLS 7.34.0
|
||||||
|
CURLSSLBACKEND_GSKIT 7.34.0
|
||||||
|
CURLSSLBACKEND_NONE 7.34.0
|
||||||
|
CURLSSLBACKEND_NSS 7.34.0
|
||||||
|
CURLSSLBACKEND_OPENSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_POLARSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_QSOSSL 7.34.0
|
||||||
|
CURLSSLBACKEND_SCHANNEL 7.34.0
|
||||||
CURLSSLOPT_ALLOW_BEAST 7.25.0
|
CURLSSLOPT_ALLOW_BEAST 7.25.0
|
||||||
CURLUSESSL_ALL 7.17.0
|
CURLUSESSL_ALL 7.17.0
|
||||||
CURLUSESSL_CONTROL 7.17.0
|
CURLUSESSL_CONTROL 7.17.0
|
||||||
@@ -695,6 +707,9 @@ CURL_SSLVERSION_DEFAULT 7.9.2
|
|||||||
CURL_SSLVERSION_SSLv2 7.9.2
|
CURL_SSLVERSION_SSLv2 7.9.2
|
||||||
CURL_SSLVERSION_SSLv3 7.9.2
|
CURL_SSLVERSION_SSLv3 7.9.2
|
||||||
CURL_SSLVERSION_TLSv1 7.9.2
|
CURL_SSLVERSION_TLSv1 7.9.2
|
||||||
|
CURL_SSLVERSION_TLSv1_0 7.34.0
|
||||||
|
CURL_SSLVERSION_TLSv1_1 7.34.0
|
||||||
|
CURL_SSLVERSION_TLSv1_2 7.34.0
|
||||||
CURL_TIMECOND_IFMODSINCE 7.9.7
|
CURL_TIMECOND_IFMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
||||||
CURL_TIMECOND_LASTMOD 7.9.7
|
CURL_TIMECOND_LASTMOD 7.9.7
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
require it! */
|
require it! */
|
||||||
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
||||||
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
||||||
defined(ANDROID) || defined(__ANDROID__) || \
|
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
|
||||||
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
|
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -827,10 +827,10 @@ typedef enum {
|
|||||||
/* Name of proxy to use. */
|
/* Name of proxy to use. */
|
||||||
CINIT(PROXY, OBJECTPOINT, 4),
|
CINIT(PROXY, OBJECTPOINT, 4),
|
||||||
|
|
||||||
/* "name:password" to use when fetching. */
|
/* "user:password;options" to use when fetching. */
|
||||||
CINIT(USERPWD, OBJECTPOINT, 5),
|
CINIT(USERPWD, OBJECTPOINT, 5),
|
||||||
|
|
||||||
/* "name:password" to use with proxy. */
|
/* "user:password" to use with proxy. */
|
||||||
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
|
||||||
|
|
||||||
/* Range to get, specified as an ASCII string. */
|
/* Range to get, specified as an ASCII string. */
|
||||||
@@ -1388,8 +1388,7 @@ typedef enum {
|
|||||||
CINIT(ADDRESS_SCOPE, LONG, 171),
|
CINIT(ADDRESS_SCOPE, LONG, 171),
|
||||||
|
|
||||||
/* Collect certificate chain info and allow it to get retrievable with
|
/* Collect certificate chain info and allow it to get retrievable with
|
||||||
CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
|
CURLINFO_CERTINFO after the transfer is complete. */
|
||||||
working with OpenSSL-powered builds. */
|
|
||||||
CINIT(CERTINFO, LONG, 172),
|
CINIT(CERTINFO, LONG, 172),
|
||||||
|
|
||||||
/* "name" and "pwd" to use when fetching. */
|
/* "name" and "pwd" to use when fetching. */
|
||||||
@@ -1569,6 +1568,9 @@ typedef enum {
|
|||||||
* Only supported by the c-ares DNS backend */
|
* Only supported by the c-ares DNS backend */
|
||||||
CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
|
CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
|
||||||
|
|
||||||
|
/* Set authentication options directly */
|
||||||
|
CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
@@ -1659,9 +1661,12 @@ enum CURL_NETRC_OPTION {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
CURL_SSLVERSION_DEFAULT,
|
CURL_SSLVERSION_DEFAULT,
|
||||||
CURL_SSLVERSION_TLSv1,
|
CURL_SSLVERSION_TLSv1, /* TLS 1.x */
|
||||||
CURL_SSLVERSION_SSLv2,
|
CURL_SSLVERSION_SSLv2,
|
||||||
CURL_SSLVERSION_SSLv3,
|
CURL_SSLVERSION_SSLv3,
|
||||||
|
CURL_SSLVERSION_TLSv1_0,
|
||||||
|
CURL_SSLVERSION_TLSv1_1,
|
||||||
|
CURL_SSLVERSION_TLSv1_2,
|
||||||
|
|
||||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||||
};
|
};
|
||||||
@@ -1980,6 +1985,28 @@ struct curl_certinfo {
|
|||||||
format "name: value" */
|
format "name: value" */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* enum for the different supported SSL backends */
|
||||||
|
typedef enum {
|
||||||
|
CURLSSLBACKEND_NONE = 0,
|
||||||
|
CURLSSLBACKEND_OPENSSL = 1,
|
||||||
|
CURLSSLBACKEND_GNUTLS = 2,
|
||||||
|
CURLSSLBACKEND_NSS = 3,
|
||||||
|
CURLSSLBACKEND_QSOSSL = 4,
|
||||||
|
CURLSSLBACKEND_GSKIT = 5,
|
||||||
|
CURLSSLBACKEND_POLARSSL = 6,
|
||||||
|
CURLSSLBACKEND_CYASSL = 7,
|
||||||
|
CURLSSLBACKEND_SCHANNEL = 8,
|
||||||
|
CURLSSLBACKEND_DARWINSSL = 9
|
||||||
|
} curl_sslbackend;
|
||||||
|
|
||||||
|
/* Information about the SSL library used and the respective internal SSL
|
||||||
|
handle, which can be used to obtain further information regarding the
|
||||||
|
connection. Asked for with CURLINFO_TLS_SESSION. */
|
||||||
|
struct curl_tlssessioninfo {
|
||||||
|
curl_sslbackend backend;
|
||||||
|
void *internals;
|
||||||
|
};
|
||||||
|
|
||||||
#define CURLINFO_STRING 0x100000
|
#define CURLINFO_STRING 0x100000
|
||||||
#define CURLINFO_LONG 0x200000
|
#define CURLINFO_LONG 0x200000
|
||||||
#define CURLINFO_DOUBLE 0x300000
|
#define CURLINFO_DOUBLE 0x300000
|
||||||
@@ -2031,9 +2058,10 @@ typedef enum {
|
|||||||
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
|
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
|
||||||
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
||||||
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
||||||
|
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
|
||||||
/* Fill in new entries below here! */
|
/* Fill in new entries below here! */
|
||||||
|
|
||||||
CURLINFO_LASTONE = 42
|
CURLINFO_LASTONE = 43
|
||||||
} CURLINFO;
|
} CURLINFO;
|
||||||
|
|
||||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||||
|
|||||||
@@ -58,51 +58,52 @@
|
|||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_LONG
|
#ifdef CURL_SIZEOF_LONG
|
||||||
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
|
||||||
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
|
||||||
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_TYPEOF_CURL_OFF_T
|
#ifdef CURL_TYPEOF_CURL_OFF_T
|
||||||
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_T
|
#ifdef CURL_FORMAT_CURL_OFF_T
|
||||||
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_CURL_OFF_TU
|
#ifdef CURL_FORMAT_CURL_OFF_TU
|
||||||
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_FORMAT_OFF_T
|
#ifdef CURL_FORMAT_OFF_T
|
||||||
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SIZEOF_CURL_OFF_T
|
#ifdef CURL_SIZEOF_CURL_OFF_T
|
||||||
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_T
|
#ifdef CURL_SUFFIX_CURL_OFF_T
|
||||||
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
#ifdef CURL_SUFFIX_CURL_OFF_TU
|
||||||
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
|
||||||
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -110,71 +111,87 @@
|
|||||||
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
|
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
|
||||||
/* ================================================================ */
|
/* ================================================================ */
|
||||||
|
|
||||||
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
|
/* header file ws2tcpip.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_WS2TCPIP_H
|
||||||
|
#ifdef CURL_PULL_WS2TCPIP_H
|
||||||
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# endif
|
||||||
|
# include <windows.h>
|
||||||
|
# include <winsock2.h>
|
||||||
|
# include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file sys/types.h must be included by the external interface. */
|
/* header file sys/types.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_SYS_TYPES_H ${CURL_PULL_SYS_TYPES_H}
|
#cmakedefine CURL_PULL_SYS_TYPES_H
|
||||||
#ifdef CURL_PULL_SYS_TYPES_H
|
#ifdef CURL_PULL_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file stdint.h must be included by the external interface. */
|
/* header file stdint.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_STDINT_H ${CURL_PULL_STDINT_H}
|
#cmakedefine CURL_PULL_STDINT_H
|
||||||
#ifdef CURL_PULL_STDINT_H
|
#ifdef CURL_PULL_STDINT_H
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Configure process defines this to 1 when it finds out that system */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
/* header file inttypes.h must be included by the external interface. */
|
/* header file inttypes.h must be included by the external interface. */
|
||||||
#cmakedefine CURL_PULL_INTTYPES_H ${CURL_PULL_INTTYPES_H}
|
#cmakedefine CURL_PULL_INTTYPES_H
|
||||||
#ifdef CURL_PULL_INTTYPES_H
|
#ifdef CURL_PULL_INTTYPES_H
|
||||||
# include <inttypes.h>
|
# include <inttypes.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The size of `long', as computed by sizeof. */
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
#cmakedefine CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
|
/* header file sys/socket.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_SYS_SOCKET_H
|
||||||
/* Integral data type used for curl_socklen_t. */
|
#ifdef CURL_PULL_SYS_SOCKET_H
|
||||||
#cmakedefine CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T}
|
|
||||||
|
|
||||||
/* on windows socklen_t is in here */
|
|
||||||
#ifdef _WIN32
|
|
||||||
# include <winsock2.h>
|
|
||||||
# include <ws2tcpip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Configure process defines this to 1 when it finds out that system */
|
||||||
|
/* header file sys/poll.h must be included by the external interface. */
|
||||||
|
#cmakedefine CURL_PULL_SYS_POLL_H
|
||||||
|
#ifdef CURL_PULL_SYS_POLL_H
|
||||||
|
# include <sys/poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The size of `long', as computed by sizeof. */
|
||||||
|
#define CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
|
||||||
|
|
||||||
|
/* Integral data type used for curl_socklen_t. */
|
||||||
|
#define CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T}
|
||||||
|
|
||||||
|
/* The size of `curl_socklen_t', as computed by sizeof. */
|
||||||
|
#define CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T}
|
||||||
|
|
||||||
/* Data type definition of curl_socklen_t. */
|
/* Data type definition of curl_socklen_t. */
|
||||||
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
|
||||||
|
|
||||||
/* The size of `curl_socklen_t', as computed by sizeof. */
|
|
||||||
#cmakedefine CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T}
|
|
||||||
|
|
||||||
/* Signed integral data type used for curl_off_t. */
|
/* Signed integral data type used for curl_off_t. */
|
||||||
#cmakedefine CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T}
|
#define CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T}
|
||||||
|
|
||||||
/* Data type definition of curl_off_t. */
|
/* Data type definition of curl_off_t. */
|
||||||
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
|
||||||
|
|
||||||
/* curl_off_t formatting string directive without "%" conversion specifier. */
|
/* curl_off_t formatting string directive without "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}"
|
#define CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}"
|
||||||
|
|
||||||
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
|
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}"
|
#define CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}"
|
||||||
|
|
||||||
/* curl_off_t formatting string directive with "%" conversion specifier. */
|
/* curl_off_t formatting string directive with "%" conversion specifier. */
|
||||||
#cmakedefine CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}"
|
#define CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}"
|
||||||
|
|
||||||
/* The size of `curl_off_t', as computed by sizeof. */
|
/* The size of `curl_off_t', as computed by sizeof. */
|
||||||
#cmakedefine CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T}
|
#define CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T}
|
||||||
|
|
||||||
/* curl_off_t constant suffix. */
|
/* curl_off_t constant suffix. */
|
||||||
#cmakedefine CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T}
|
#define CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T}
|
||||||
|
|
||||||
/* unsigned curl_off_t constant suffix. */
|
/* unsigned curl_off_t constant suffix. */
|
||||||
#cmakedefine CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU}
|
#define CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU}
|
||||||
|
|
||||||
#endif /* __CURL_CURLBUILD_H */
|
#endif /* __CURL_CURLBUILD_H */
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
|
|
||||||
/* This is the version number of the libcurl package from which this header
|
/* This is the version number of the libcurl package from which this header
|
||||||
file origins: */
|
file origins: */
|
||||||
#define LIBCURL_VERSION "7.33.0-DEV"
|
#define LIBCURL_VERSION "7.34.0-DEV"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBCURL_VERSION_MAJOR 7
|
#define LIBCURL_VERSION_MAJOR 7
|
||||||
#define LIBCURL_VERSION_MINOR 33
|
#define LIBCURL_VERSION_MINOR 34
|
||||||
#define LIBCURL_VERSION_PATCH 0
|
#define LIBCURL_VERSION_PATCH 0
|
||||||
|
|
||||||
/* This is the numeric version of the libcurl version number, meant for easier
|
/* This is the numeric version of the libcurl version number, meant for easier
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
and it is always a greater number in a more recent release. It makes
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBCURL_VERSION_NUM 0x072100
|
#define LIBCURL_VERSION_NUM 0x072200
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the date and time when the full source package was created. The
|
* This is the date and time when the full source package was created. The
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -269,6 +269,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
|||||||
(option) == CURLOPT_DNS_INTERFACE || \
|
(option) == CURLOPT_DNS_INTERFACE || \
|
||||||
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
||||||
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
||||||
|
(option) == CURLOPT_LOGIN_OPTIONS || \
|
||||||
0)
|
0)
|
||||||
|
|
||||||
/* evaluates to true if option takes a curl_write_callback argument */
|
/* evaluates to true if option takes a curl_write_callback argument */
|
||||||
|
|||||||
@@ -46,4 +46,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
|||||||
curl_ntlm_msgs.h curl_sasl.h curl_schannel.h curl_multibyte.h \
|
curl_ntlm_msgs.h curl_sasl.h curl_schannel.h curl_multibyte.h \
|
||||||
curl_darwinssl.h hostcheck.h bundles.h conncache.h curl_setup_once.h \
|
curl_darwinssl.h hostcheck.h bundles.h conncache.h curl_setup_once.h \
|
||||||
multihandle.h setup-vms.h pipeline.h dotdot.h x509asn1.h gskit.h \
|
multihandle.h setup-vms.h pipeline.h dotdot.h x509asn1.h gskit.h \
|
||||||
http2.h
|
http2.h sigpipe.h
|
||||||
|
|||||||
@@ -645,10 +645,10 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
|||||||
const char *local_ip4)
|
const char *local_ip4)
|
||||||
{
|
{
|
||||||
#if (ARES_VERSION >= 0x010704)
|
#if (ARES_VERSION >= 0x010704)
|
||||||
uint32_t a4;
|
struct in_addr a4;
|
||||||
|
|
||||||
if((!local_ip4) || (local_ip4[0] == 0)) {
|
if((!local_ip4) || (local_ip4[0] == 0)) {
|
||||||
a4 = 0; /* disabled: do not bind to a specific address */
|
a4.s_addr = 0; /* disabled: do not bind to a specific address */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
|
if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
|
||||||
@@ -656,7 +656,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4));
|
ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* c-ares version too old! */
|
#else /* c-ares version too old! */
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
|||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
failf(data, "axTLS only supports TLSv1");
|
failf(data, "axTLS only supports TLS 1.0 and 1.1, "
|
||||||
|
"and it cannot be specified which one to use");
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
109
lib/base64.c
109
lib/base64.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -40,29 +40,45 @@
|
|||||||
static const char table64[]=
|
static const char table64[]=
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
static void decodeQuantum(unsigned char *dest, const char *src)
|
static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||||
{
|
{
|
||||||
|
size_t padding = 0;
|
||||||
const char *s, *p;
|
const char *s, *p;
|
||||||
unsigned long i, v, x = 0;
|
unsigned long i, v, x = 0;
|
||||||
|
|
||||||
for(i = 0, s = src; i < 4; i++, s++) {
|
for(i = 0, s = src; i < 4; i++, s++) {
|
||||||
v = 0;
|
v = 0;
|
||||||
p = table64;
|
|
||||||
while(*p && (*p != *s)) {
|
if(*s == '=') {
|
||||||
v++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
if(*p == *s)
|
|
||||||
x = (x << 6) + v;
|
|
||||||
else if(*s == '=')
|
|
||||||
x = (x << 6);
|
x = (x << 6);
|
||||||
|
padding++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = table64;
|
||||||
|
|
||||||
|
while(*p && (*p != *s)) {
|
||||||
|
v++;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*p == *s)
|
||||||
|
x = (x << 6) + v;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dest[2] = curlx_ultouc(x & 0xFFUL);
|
if(padding < 1)
|
||||||
|
dest[2] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
dest[1] = curlx_ultouc(x & 0xFFUL);
|
if(padding < 2)
|
||||||
|
dest[1] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
x >>= 8;
|
x >>= 8;
|
||||||
dest[0] = curlx_ultouc(x & 0xFFUL);
|
dest[0] = curlx_ultouc(x & 0xFFUL);
|
||||||
|
|
||||||
|
return 3 - padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -82,58 +98,71 @@ static void decodeQuantum(unsigned char *dest, const char *src)
|
|||||||
CURLcode Curl_base64_decode(const char *src,
|
CURLcode Curl_base64_decode(const char *src,
|
||||||
unsigned char **outptr, size_t *outlen)
|
unsigned char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
size_t srclen = 0;
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
size_t equalsTerm = 0;
|
size_t padding = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
size_t result;
|
||||||
size_t numQuantums;
|
size_t numQuantums;
|
||||||
unsigned char lastQuantum[3];
|
|
||||||
size_t rawlen = 0;
|
size_t rawlen = 0;
|
||||||
|
unsigned char *pos;
|
||||||
unsigned char *newstr;
|
unsigned char *newstr;
|
||||||
|
|
||||||
*outptr = NULL;
|
*outptr = NULL;
|
||||||
*outlen = 0;
|
*outlen = 0;
|
||||||
|
srclen = strlen(src);
|
||||||
|
|
||||||
|
/* Check the length of the input string is valid */
|
||||||
|
if(!srclen || srclen % 4)
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
|
/* Find the position of any = padding characters */
|
||||||
while((src[length] != '=') && src[length])
|
while((src[length] != '=') && src[length])
|
||||||
length++;
|
length++;
|
||||||
|
|
||||||
/* A maximum of two = padding characters is allowed */
|
/* A maximum of two = padding characters is allowed */
|
||||||
if(src[length] == '=') {
|
if(src[length] == '=') {
|
||||||
equalsTerm++;
|
padding++;
|
||||||
if(src[length+equalsTerm] == '=')
|
if(src[length + 1] == '=')
|
||||||
equalsTerm++;
|
padding++;
|
||||||
}
|
}
|
||||||
numQuantums = (length + equalsTerm) / 4;
|
|
||||||
|
|
||||||
/* Don't allocate a buffer if the decoded length is 0 */
|
/* Check the = padding characters weren't part way through the input */
|
||||||
if(numQuantums == 0)
|
if(length + padding != srclen)
|
||||||
return CURLE_OK;
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
rawlen = (numQuantums * 3) - equalsTerm;
|
/* Calculate the number of quantums */
|
||||||
|
numQuantums = srclen / 4;
|
||||||
|
|
||||||
/* The buffer must be large enough to make room for the last quantum
|
/* Calculate the size of the decoded string */
|
||||||
(which may be partially thrown out) and the zero terminator. */
|
rawlen = (numQuantums * 3) - padding;
|
||||||
newstr = malloc(rawlen+4);
|
|
||||||
|
/* Allocate our buffer including room for a zero terminator */
|
||||||
|
newstr = malloc(rawlen + 1);
|
||||||
if(!newstr)
|
if(!newstr)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
*outptr = newstr;
|
pos = newstr;
|
||||||
|
|
||||||
/* Decode all but the last quantum (which may not decode to a
|
/* Decode the quantums */
|
||||||
multiple of 3 bytes) */
|
for(i = 0; i < numQuantums; i++) {
|
||||||
for(i = 0; i < numQuantums - 1; i++) {
|
result = decodeQuantum(pos, src);
|
||||||
decodeQuantum(newstr, src);
|
if(!result) {
|
||||||
newstr += 3; src += 4;
|
Curl_safefree(newstr);
|
||||||
|
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += result;
|
||||||
|
src += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This final decode may actually read slightly past the end of the buffer
|
/* Zero terminate */
|
||||||
if the input string is missing pad bytes. This will almost always be
|
*pos = '\0';
|
||||||
harmless. */
|
|
||||||
decodeQuantum(lastQuantum, src);
|
|
||||||
for(i = 0; i < 3 - equalsTerm; i++)
|
|
||||||
newstr[i] = lastQuantum[i];
|
|
||||||
|
|
||||||
newstr[i] = '\0'; /* zero terminate */
|
/* Return the decoded data */
|
||||||
|
*outptr = newstr;
|
||||||
*outlen = rawlen; /* return size of decoded data */
|
*outlen = rawlen;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -529,10 +529,10 @@
|
|||||||
#define SEND_TYPE_RETV int
|
#define SEND_TYPE_RETV int
|
||||||
|
|
||||||
/* Define to use the QsoSSL package. */
|
/* Define to use the QsoSSL package. */
|
||||||
#define USE_QSOSSL
|
#undef USE_QSOSSL
|
||||||
|
|
||||||
/* Define to use the GSKit package. */
|
/* Define to use the GSKit package. */
|
||||||
#undef USE_GSKIT
|
#define USE_GSKIT
|
||||||
|
|
||||||
/* Use the system keyring as the default CA bundle. */
|
/* Use the system keyring as the default CA bundle. */
|
||||||
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
||||||
|
|||||||
368
lib/connect.c
368
lib/connect.c
@@ -164,8 +164,7 @@ tcpkeepalive(struct SessionHandle *data,
|
|||||||
static CURLcode
|
static CURLcode
|
||||||
singleipconnect(struct connectdata *conn,
|
singleipconnect(struct connectdata *conn,
|
||||||
const Curl_addrinfo *ai, /* start connecting to this */
|
const Curl_addrinfo *ai, /* start connecting to this */
|
||||||
curl_socket_t *sock,
|
curl_socket_t *sock);
|
||||||
bool *connected);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
* Curl_timeleft() returns the amount of milliseconds left allowed for the
|
||||||
@@ -233,45 +232,6 @@ long Curl_timeleft(struct SessionHandle *data,
|
|||||||
return timeout_ms;
|
return timeout_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* checkconnect() checks for a TCP connect on the given socket.
|
|
||||||
* It returns:
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum chkconn_t {
|
|
||||||
CHKCONN_SELECT_ERROR = -1,
|
|
||||||
CHKCONN_CONNECTED = 0,
|
|
||||||
CHKCONN_IDLE = 1,
|
|
||||||
CHKCONN_FDSET_ERROR = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum chkconn_t
|
|
||||||
checkconnect(curl_socket_t sockfd)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
#ifdef mpeix
|
|
||||||
/* Call this function once now, and ignore the results. We do this to
|
|
||||||
"clear" the error state on the socket so that we can later read it
|
|
||||||
reliably. This is reported necessary on the MPE/iX operating system. */
|
|
||||||
(void)verifyconnect(sockfd, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 0);
|
|
||||||
|
|
||||||
if(-1 == rc)
|
|
||||||
/* error, no connect here, try next */
|
|
||||||
return CHKCONN_SELECT_ERROR;
|
|
||||||
|
|
||||||
else if(rc & CURL_CSELECT_ERR)
|
|
||||||
/* error condition caught */
|
|
||||||
return CHKCONN_FDSET_ERROR;
|
|
||||||
|
|
||||||
else if(rc)
|
|
||||||
return CHKCONN_CONNECTED;
|
|
||||||
|
|
||||||
return CHKCONN_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CURLcode bindlocal(struct connectdata *conn,
|
static CURLcode bindlocal(struct connectdata *conn,
|
||||||
curl_socket_t sockfd, int af)
|
curl_socket_t sockfd, int af)
|
||||||
{
|
{
|
||||||
@@ -573,42 +533,53 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
|
|||||||
more address exists or error */
|
more address exists or error */
|
||||||
static CURLcode trynextip(struct connectdata *conn,
|
static CURLcode trynextip(struct connectdata *conn,
|
||||||
int sockindex,
|
int sockindex,
|
||||||
bool *connected)
|
int tempindex)
|
||||||
{
|
{
|
||||||
curl_socket_t sockfd;
|
CURLcode rc = CURLE_COULDNT_CONNECT;
|
||||||
Curl_addrinfo *ai;
|
|
||||||
|
|
||||||
/* First clean up after the failed socket.
|
/* First clean up after the failed socket.
|
||||||
Don't close it yet to ensure that the next IP's socket gets a different
|
Don't close it yet to ensure that the next IP's socket gets a different
|
||||||
file descriptor, which can prevent bugs when the curl_multi_socket_action
|
file descriptor, which can prevent bugs when the curl_multi_socket_action
|
||||||
interface is used with certain select() replacements such as kqueue. */
|
interface is used with certain select() replacements such as kqueue. */
|
||||||
curl_socket_t fd_to_close = conn->sock[sockindex];
|
curl_socket_t fd_to_close = conn->tempsock[tempindex];
|
||||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
conn->tempsock[tempindex] = CURL_SOCKET_BAD;
|
||||||
*connected = FALSE;
|
|
||||||
|
|
||||||
if(sockindex != FIRSTSOCKET) {
|
if(sockindex == FIRSTSOCKET) {
|
||||||
Curl_closesocket(conn, fd_to_close);
|
Curl_addrinfo *ai;
|
||||||
return CURLE_COULDNT_CONNECT; /* no next */
|
int family;
|
||||||
}
|
|
||||||
|
|
||||||
/* try the next address */
|
if(conn->tempaddr[tempindex]) {
|
||||||
ai = conn->ip_addr->ai_next;
|
/* find next address in the same protocol family */
|
||||||
|
family = conn->tempaddr[tempindex]->ai_family;
|
||||||
while(ai) {
|
ai = conn->tempaddr[tempindex]->ai_next;
|
||||||
CURLcode res = singleipconnect(conn, ai, &sockfd, connected);
|
}
|
||||||
if(res)
|
else {
|
||||||
return res;
|
/* happy eyeballs - try the other protocol family */
|
||||||
if(sockfd != CURL_SOCKET_BAD) {
|
int firstfamily = conn->tempaddr[0]->ai_family;
|
||||||
/* store the new socket descriptor */
|
family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
|
||||||
conn->sock[sockindex] = sockfd;
|
ai = conn->tempaddr[0]->ai_next;
|
||||||
conn->ip_addr = ai;
|
}
|
||||||
Curl_closesocket(conn, fd_to_close);
|
|
||||||
return CURLE_OK;
|
while(ai) {
|
||||||
|
while(ai && ai->ai_family != family)
|
||||||
|
ai = ai->ai_next;
|
||||||
|
|
||||||
|
if(ai) {
|
||||||
|
rc = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
|
||||||
|
conn->tempaddr[tempindex] = ai;
|
||||||
|
if(rc == CURLE_COULDNT_CONNECT) {
|
||||||
|
ai = ai->ai_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ai = ai->ai_next;
|
|
||||||
}
|
}
|
||||||
Curl_closesocket(conn, fd_to_close);
|
|
||||||
return CURLE_COULDNT_CONNECT;
|
if(fd_to_close != CURL_SOCKET_BAD)
|
||||||
|
Curl_closesocket(conn, fd_to_close);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copies connection info into the session handle to make it available
|
/* Copies connection info into the session handle to make it available
|
||||||
@@ -707,6 +678,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
|||||||
error, Curl_strerror(conn, error));
|
error, Curl_strerror(conn, error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
||||||
|
|
||||||
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
if(!getaddressinfo((struct sockaddr*)&ssloc,
|
||||||
conn->local_ip, &conn->local_port)) {
|
conn->local_ip, &conn->local_port)) {
|
||||||
@@ -732,11 +704,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
CURLcode code = CURLE_OK;
|
CURLcode code = CURLE_OK;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
long allow;
|
||||||
long allow = DEFAULT_CONNECT_TIMEOUT;
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
enum chkconn_t chk;
|
int result;
|
||||||
|
int i;
|
||||||
|
|
||||||
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||||
|
|
||||||
@@ -759,69 +731,104 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
return CURLE_OPERATION_TIMEDOUT;
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check socket for connect */
|
for(i=0; i<2; i++) {
|
||||||
chk = checkconnect(sockfd);
|
if(conn->tempsock[i] == CURL_SOCKET_BAD)
|
||||||
if(CHKCONN_IDLE == chk) {
|
continue;
|
||||||
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
|
||||||
infof(data, "After %ldms connect time, move on!\n",
|
#ifdef mpeix
|
||||||
conn->timeoutms_per_addr);
|
/* Call this function once now, and ignore the results. We do this to
|
||||||
goto next;
|
"clear" the error state on the socket so that we can later read it
|
||||||
|
reliably. This is reported necessary on the MPE/iX operating system. */
|
||||||
|
(void)verifyconnect(conn->tempsock[i], NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check socket for connect */
|
||||||
|
result = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||||
|
|
||||||
|
if(result == 0) { /* no connection yet */
|
||||||
|
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
||||||
|
infof(data, "After %ldms connect time, move on!\n",
|
||||||
|
conn->timeoutms_per_addr);
|
||||||
|
error = ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* should we try another protocol family? */
|
||||||
|
if(i == 0 && conn->tempaddr[1] == NULL &&
|
||||||
|
curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
|
||||||
|
trynextip(conn, sockindex, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if(result == CURL_CSELECT_OUT) {
|
||||||
|
if(verifyconnect(conn->tempsock[i], &error)) {
|
||||||
|
/* we are connected with TCP, awesome! */
|
||||||
|
int other = i ^ 1;
|
||||||
|
|
||||||
/* not an error, but also no connection yet */
|
/* use this socket from now on */
|
||||||
return code;
|
conn->sock[sockindex] = conn->tempsock[i];
|
||||||
}
|
conn->ip_addr = conn->tempaddr[i];
|
||||||
|
conn->tempsock[i] = CURL_SOCKET_BAD;
|
||||||
|
|
||||||
if(CHKCONN_CONNECTED == chk) {
|
/* close the other socket, if open */
|
||||||
if(verifyconnect(sockfd, &error)) {
|
if(conn->tempsock[other] != CURL_SOCKET_BAD) {
|
||||||
/* we are connected with TCP, awesome! */
|
Curl_closesocket(conn, conn->tempsock[other]);
|
||||||
|
conn->tempsock[other] = CURL_SOCKET_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
/* see if we need to do any proxy magic first once we connected */
|
/* see if we need to do any proxy magic first once we connected */
|
||||||
code = Curl_connected_proxy(conn);
|
code = Curl_connected_proxy(conn, sockindex);
|
||||||
if(code)
|
if(code)
|
||||||
return code;
|
return code;
|
||||||
|
|
||||||
conn->bits.tcpconnect[sockindex] = TRUE;
|
conn->bits.tcpconnect[sockindex] = TRUE;
|
||||||
|
|
||||||
*connected = TRUE;
|
*connected = TRUE;
|
||||||
if(sockindex == FIRSTSOCKET)
|
if(sockindex == FIRSTSOCKET)
|
||||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||||
Curl_verboseconnect(conn);
|
Curl_updateconninfo(conn, conn->sock[sockindex]);
|
||||||
Curl_updateconninfo(conn, sockfd);
|
Curl_verboseconnect(conn);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
infof(data, "Connection failed\n");
|
||||||
}
|
}
|
||||||
/* nope, not connected for real */
|
else if(result & CURL_CSELECT_ERR)
|
||||||
}
|
(void)verifyconnect(conn->tempsock[i], &error);
|
||||||
else {
|
|
||||||
/* nope, not connected */
|
/*
|
||||||
if(CHKCONN_FDSET_ERROR == chk) {
|
* The connection failed here, we should attempt to connect to the "next
|
||||||
(void)verifyconnect(sockfd, &error);
|
* address" for the given host. But first remember the latest error.
|
||||||
infof(data, "%s\n",Curl_strerror(conn, error));
|
*/
|
||||||
|
if(error) {
|
||||||
|
char ipaddress[MAX_IPADR_LEN];
|
||||||
|
data->state.os_errno = error;
|
||||||
|
SET_SOCKERRNO(error);
|
||||||
|
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
|
||||||
|
infof(data, "connect to %s port %ld failed: %s\n",
|
||||||
|
ipaddress, conn->port, Curl_strerror(conn, error));
|
||||||
|
|
||||||
|
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
|
||||||
|
allow : allow / 2;
|
||||||
|
|
||||||
|
code = trynextip(conn, sockindex, i);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
infof(data, "Connection failed\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The connection failed here, we should attempt to connect to the "next
|
|
||||||
* address" for the given host. But first remember the latest error.
|
|
||||||
*/
|
|
||||||
if(error) {
|
|
||||||
data->state.os_errno = error;
|
|
||||||
SET_SOCKERRNO(error);
|
|
||||||
}
|
|
||||||
next:
|
|
||||||
|
|
||||||
conn->timeoutms_per_addr = conn->ip_addr->ai_next == NULL ?
|
|
||||||
allow : allow / 2;
|
|
||||||
code = trynextip(conn, sockindex, connected);
|
|
||||||
|
|
||||||
if(code) {
|
if(code) {
|
||||||
error = SOCKERRNO;
|
/* no more addresses to try */
|
||||||
data->state.os_errno = error;
|
|
||||||
failf(data, "Failed connect to %s:%ld; %s",
|
/* if the first address family runs out of addresses to try before
|
||||||
conn->host.name, conn->port, Curl_strerror(conn, error));
|
the happy eyeball timeout, go ahead and try the next family now */
|
||||||
|
if(conn->tempaddr[1] == NULL) {
|
||||||
|
int rc;
|
||||||
|
rc = trynextip(conn, sockindex, 1);
|
||||||
|
if(rc == CURLE_OK)
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
failf(data, "Failed to connect to %s port %ld: %s",
|
||||||
|
conn->bits.proxy?conn->proxy.name:conn->host.name,
|
||||||
|
conn->port, Curl_strerror(conn, error));
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
@@ -938,8 +945,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
|||||||
static CURLcode
|
static CURLcode
|
||||||
singleipconnect(struct connectdata *conn,
|
singleipconnect(struct connectdata *conn,
|
||||||
const Curl_addrinfo *ai,
|
const Curl_addrinfo *ai,
|
||||||
curl_socket_t *sockp,
|
curl_socket_t *sockp)
|
||||||
bool *connected)
|
|
||||||
{
|
{
|
||||||
struct Curl_sockaddr_ex addr;
|
struct Curl_sockaddr_ex addr;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -948,9 +954,10 @@ singleipconnect(struct connectdata *conn,
|
|||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
curl_socket_t sockfd;
|
curl_socket_t sockfd;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
char ipaddress[MAX_IPADR_LEN];
|
||||||
|
long port;
|
||||||
|
|
||||||
*sockp = CURL_SOCKET_BAD;
|
*sockp = CURL_SOCKET_BAD;
|
||||||
*connected = FALSE; /* default is not connected */
|
|
||||||
|
|
||||||
res = Curl_socket(conn, ai, &addr, &sockfd);
|
res = Curl_socket(conn, ai, &addr, &sockfd);
|
||||||
if(res)
|
if(res)
|
||||||
@@ -961,7 +968,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* store remote address and port used in this connection attempt */
|
/* store remote address and port used in this connection attempt */
|
||||||
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
|
||||||
conn->primary_ip, &conn->primary_port)) {
|
ipaddress, &port)) {
|
||||||
/* malformed address or bug in inet_ntop, try next address */
|
/* malformed address or bug in inet_ntop, try next address */
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
|
||||||
@@ -969,10 +976,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
Curl_closesocket(conn, sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
|
infof(data, " Trying %s...\n", ipaddress);
|
||||||
infof(data, " Trying %s...\n", conn->ip_addr_str);
|
|
||||||
|
|
||||||
Curl_persistconninfo(conn);
|
|
||||||
|
|
||||||
if(data->set.tcp_nodelay)
|
if(data->set.tcp_nodelay)
|
||||||
tcpnodelay(conn, sockfd);
|
tcpnodelay(conn, sockfd);
|
||||||
@@ -1033,7 +1037,7 @@ singleipconnect(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(-1 == rc) {
|
if(-1 == rc) {
|
||||||
switch (error) {
|
switch(error) {
|
||||||
case EINPROGRESS:
|
case EINPROGRESS:
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK:
|
||||||
#if defined(EAGAIN)
|
#if defined(EAGAIN)
|
||||||
@@ -1045,25 +1049,25 @@ singleipconnect(struct connectdata *conn,
|
|||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
*sockp = sockfd;
|
res = CURLE_OK;
|
||||||
return CURLE_OK;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* unknown error, fallthrough and try another address! */
|
/* unknown error, fallthrough and try another address! */
|
||||||
failf(data, "Failed to connect to %s: %s",
|
infof(data, "Immediate connect fail for %s: %s\n",
|
||||||
conn->ip_addr_str, Curl_strerror(conn,error));
|
ipaddress, Curl_strerror(conn,error));
|
||||||
data->state.os_errno = error;
|
data->state.os_errno = error;
|
||||||
|
|
||||||
/* connect failed */
|
/* connect failed */
|
||||||
Curl_closesocket(conn, sockfd);
|
Curl_closesocket(conn, sockfd);
|
||||||
|
res = CURLE_COULDNT_CONNECT;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(!res)
|
||||||
*sockp = sockfd;
|
*sockp = sockfd;
|
||||||
|
|
||||||
return CURLE_OK;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1073,29 +1077,13 @@ singleipconnect(struct connectdata *conn,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||||
const struct Curl_dns_entry *remotehost,
|
const struct Curl_dns_entry *remotehost)
|
||||||
curl_socket_t *sockconn, /* the connected socket */
|
|
||||||
Curl_addrinfo **addr, /* the one we used */
|
|
||||||
bool *connected) /* really connected? */
|
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
curl_socket_t sockfd = CURL_SOCKET_BAD;
|
|
||||||
Curl_addrinfo *ai;
|
|
||||||
Curl_addrinfo *curr_addr;
|
|
||||||
|
|
||||||
struct timeval after;
|
|
||||||
struct timeval before = Curl_tvnow();
|
struct timeval before = Curl_tvnow();
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
/*************************************************************
|
long timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||||
* Figure out what maximum time we have left
|
|
||||||
*************************************************************/
|
|
||||||
long timeout_ms;
|
|
||||||
|
|
||||||
DEBUGASSERT(sockconn);
|
|
||||||
*connected = FALSE; /* default to not connected */
|
|
||||||
|
|
||||||
/* get the timeout left */
|
|
||||||
timeout_ms = Curl_timeleft(data, &before, TRUE);
|
|
||||||
|
|
||||||
if(timeout_ms < 0) {
|
if(timeout_ms < 0) {
|
||||||
/* a precaution, no need to continue if time already is up */
|
/* a precaution, no need to continue if time already is up */
|
||||||
@@ -1104,57 +1092,27 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
||||||
|
conn->tempaddr[0] = remotehost->addr;
|
||||||
|
conn->tempaddr[1] = NULL;
|
||||||
|
conn->tempsock[0] = CURL_SOCKET_BAD;
|
||||||
|
conn->tempsock[1] = CURL_SOCKET_BAD;
|
||||||
|
Curl_expire(conn->data,
|
||||||
|
HAPPY_EYEBALLS_TIMEOUT + (MULTI_TIMEOUT_INACCURACY/1000));
|
||||||
|
|
||||||
ai = remotehost->addr;
|
/* Max time for the next connection attempt */
|
||||||
|
conn->timeoutms_per_addr =
|
||||||
|
conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
|
||||||
|
|
||||||
/* Below is the loop that attempts to connect to all IP-addresses we
|
/* start connecting to first IP */
|
||||||
* know for the given host. One by one until one IP succeeds.
|
res = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
|
||||||
*/
|
while(res != CURLE_OK &&
|
||||||
|
conn->tempaddr[0] &&
|
||||||
|
conn->tempaddr[0]->ai_next &&
|
||||||
|
conn->tempsock[0] == CURL_SOCKET_BAD)
|
||||||
|
res = trynextip(conn, FIRSTSOCKET, 0);
|
||||||
|
|
||||||
/*
|
if(conn->tempsock[0] == CURL_SOCKET_BAD)
|
||||||
* Connecting with a Curl_addrinfo chain
|
return res;
|
||||||
*/
|
|
||||||
for(curr_addr = ai; curr_addr; curr_addr = curr_addr->ai_next) {
|
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
/* Max time for the next address */
|
|
||||||
conn->timeoutms_per_addr = curr_addr->ai_next == NULL ?
|
|
||||||
timeout_ms : timeout_ms / 2;
|
|
||||||
|
|
||||||
/* start connecting to the IP curr_addr points to */
|
|
||||||
res = singleipconnect(conn, curr_addr,
|
|
||||||
&sockfd, connected);
|
|
||||||
if(res)
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if(sockfd != CURL_SOCKET_BAD)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* get a new timeout for next attempt */
|
|
||||||
after = Curl_tvnow();
|
|
||||||
timeout_ms -= Curl_tvdiff(after, before);
|
|
||||||
if(timeout_ms < 0) {
|
|
||||||
failf(data, "connect() timed out!");
|
|
||||||
return CURLE_OPERATION_TIMEDOUT;
|
|
||||||
}
|
|
||||||
before = after;
|
|
||||||
} /* end of connect-to-each-address loop */
|
|
||||||
|
|
||||||
*sockconn = sockfd; /* the socket descriptor we've connected */
|
|
||||||
|
|
||||||
if(sockfd == CURL_SOCKET_BAD) {
|
|
||||||
/* no good connect was made */
|
|
||||||
failf(data, "couldn't connect to %s at %s:%ld",
|
|
||||||
conn->bits.proxy?"proxy":"host",
|
|
||||||
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
|
|
||||||
return CURLE_COULDNT_CONNECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* leave the socket in non-blocking mode */
|
|
||||||
|
|
||||||
/* store the address we use */
|
|
||||||
if(addr)
|
|
||||||
*addr = curr_addr;
|
|
||||||
|
|
||||||
data->info.numconnects++; /* to track the number of connections made */
|
data->info.numconnects++; /* to track the number of connections made */
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -31,11 +31,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
|||||||
bool *connected);
|
bool *connected);
|
||||||
|
|
||||||
CURLcode Curl_connecthost(struct connectdata *conn,
|
CURLcode Curl_connecthost(struct connectdata *conn,
|
||||||
const struct Curl_dns_entry *host, /* connect to
|
const struct Curl_dns_entry *host);
|
||||||
this */
|
|
||||||
curl_socket_t *sockconn, /* not set if error */
|
|
||||||
Curl_addrinfo **addr, /* the one we used */
|
|
||||||
bool *connected); /* truly connected? */
|
|
||||||
|
|
||||||
/* generic function that returns how much time there's left to run, according
|
/* generic function that returns how much time there's left to run, according
|
||||||
to the timeouts set */
|
to the timeouts set */
|
||||||
@@ -44,6 +40,8 @@ long Curl_timeleft(struct SessionHandle *data,
|
|||||||
bool duringconnect);
|
bool duringconnect);
|
||||||
|
|
||||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||||
|
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
|
||||||
|
ipv4/ipv6 connection attempts */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to extract socket and connectdata struct for the most recent
|
* Used to extract socket and connectdata struct for the most recent
|
||||||
|
|||||||
@@ -834,7 +834,7 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
|
|||||||
return server_cert_summary;
|
return server_cert_summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CURL_SUPPORT_MAC_10_7
|
#if CURL_SUPPORT_MAC_10_6
|
||||||
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
|
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
|
||||||
deprecation warnings, so let's not compile this unless it's necessary: */
|
deprecation warnings, so let's not compile this unless it's necessary: */
|
||||||
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
|
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
|
||||||
@@ -874,7 +874,7 @@ static OSStatus CopyIdentityWithLabelOldSchool(char *label,
|
|||||||
CFRelease(search);
|
CFRelease(search);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif /* CURL_SUPPORT_MAC_10_7 */
|
#endif /* CURL_SUPPORT_MAC_10_6 */
|
||||||
|
|
||||||
static OSStatus CopyIdentityWithLabel(char *label,
|
static OSStatus CopyIdentityWithLabel(char *label,
|
||||||
SecIdentityRef *out_cert_and_key)
|
SecIdentityRef *out_cert_and_key)
|
||||||
@@ -914,12 +914,12 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
|||||||
CFRelease(query_dict);
|
CFRelease(query_dict);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if CURL_SUPPORT_MAC_10_7
|
#if CURL_SUPPORT_MAC_10_6
|
||||||
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
|
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
|
||||||
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
|
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
|
||||||
#endif /* CURL_SUPPORT_MAC_10_7 */
|
#endif /* CURL_SUPPORT_MAC_10_7 */
|
||||||
}
|
}
|
||||||
#elif CURL_SUPPORT_MAC_10_7
|
#elif CURL_SUPPORT_MAC_10_6
|
||||||
/* For developers building on older cats, we have no choice but to fall back
|
/* For developers building on older cats, we have no choice but to fall back
|
||||||
to SecKeychainSearch. */
|
to SecKeychainSearch. */
|
||||||
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
|
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
|
||||||
@@ -938,8 +938,10 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
|
|||||||
cPassword, kCFStringEncodingUTF8) : NULL;
|
cPassword, kCFStringEncodingUTF8) : NULL;
|
||||||
CFDataRef pkcs_data = NULL;
|
CFDataRef pkcs_data = NULL;
|
||||||
|
|
||||||
/* We can import P12 files on iOS or OS X 10.6 or later: */
|
/* We can import P12 files on iOS or OS X 10.7 or later: */
|
||||||
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
|
/* These constants are documented as having first appeared in 10.6 but they
|
||||||
|
raise linker errors when used on that cat for some reason. */
|
||||||
|
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||||
if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
|
if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
|
||||||
NULL, NULL, &status)) {
|
NULL, NULL, &status)) {
|
||||||
const void *cKeys[] = {kSecImportExportPassphrase};
|
const void *cKeys[] = {kSecImportExportPassphrase};
|
||||||
@@ -963,7 +965,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
|
|||||||
CFRelease(options);
|
CFRelease(options);
|
||||||
CFRelease(pkcs_data);
|
CFRelease(pkcs_data);
|
||||||
}
|
}
|
||||||
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
|
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
|
||||||
if(password)
|
if(password)
|
||||||
CFRelease(password);
|
CFRelease(password);
|
||||||
CFRelease(pkcs_url);
|
CFRelease(pkcs_url);
|
||||||
@@ -1056,6 +1058,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
||||||
@@ -1100,6 +1114,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
kTLSProtocol12,
|
kTLSProtocol12,
|
||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol1,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol11,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
|
kTLSProtocol12,
|
||||||
|
true);
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol3,
|
kSSLProtocol3,
|
||||||
@@ -1130,10 +1159,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kTLSProtocol1,
|
kTLSProtocol1,
|
||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
failf(data, "Your version of the OS does not support TLSv1.1");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
failf(data, "Your version of the OS does not support TLSv1.2");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocol2,
|
kSSLProtocol2,
|
||||||
@@ -1216,16 +1252,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch(err) {
|
switch(err) {
|
||||||
case errSecPkcs12VerifyFailure: case errSecAuthFailed:
|
case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
|
||||||
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
|
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
|
||||||
"and its private key.", data->set.str[STRING_CERT]);
|
"and its private key.", data->set.str[STRING_CERT]);
|
||||||
break;
|
break;
|
||||||
case errSecDecode: case errSecUnknownFormat:
|
case errSecDecode: case -25257: /* errSecUnknownFormat */
|
||||||
failf(data, "SSL: Couldn't make sense of the data in the "
|
failf(data, "SSL: Couldn't make sense of the data in the "
|
||||||
"certificate \"%s\" and its private key.",
|
"certificate \"%s\" and its private key.",
|
||||||
data->set.str[STRING_CERT]);
|
data->set.str[STRING_CERT]);
|
||||||
break;
|
break;
|
||||||
case errSecPassphraseRequired:
|
case -25260: /* errSecPassphraseRequired */
|
||||||
failf(data, "SSL The certificate \"%s\" requires a password.",
|
failf(data, "SSL The certificate \"%s\" requires a password.",
|
||||||
data->set.str[STRING_CERT]);
|
data->set.str[STRING_CERT]);
|
||||||
break;
|
break;
|
||||||
@@ -1403,7 +1439,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
|
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
|
||||||
/* We want to enable 1/n-1 when using a CBC cipher unless the user
|
/* We want to enable 1/n-1 when using a CBC cipher unless the user
|
||||||
specifically doesn't want us doing that: */
|
specifically doesn't want us doing that: */
|
||||||
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
|
if(SSLSetSessionOption != NULL)
|
||||||
|
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
|
||||||
!data->set.ssl_enable_beast);
|
!data->set.ssl_enable_beast);
|
||||||
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
|
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
|
||||||
|
|
||||||
|
|||||||
@@ -77,10 +77,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
|||||||
|
|
||||||
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
||||||
|
|
||||||
/* skip initial whitespaces */
|
|
||||||
while(*header && ISSPACE(*header))
|
|
||||||
header++;
|
|
||||||
|
|
||||||
if(checkprefix("NTLM", header)) {
|
if(checkprefix("NTLM", header)) {
|
||||||
header += strlen("NTLM");
|
header += strlen("NTLM");
|
||||||
|
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
|||||||
conn->response_header = NULL;
|
conn->response_header = NULL;
|
||||||
break;
|
break;
|
||||||
case NTLMSTATE_TYPE2:
|
case NTLMSTATE_TYPE2:
|
||||||
input = aprintf("TT %s", conn->challenge_header);
|
input = aprintf("TT %s\n", conn->challenge_header);
|
||||||
if(!input)
|
if(!input)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
res = ntlm_wb_response(conn, input, ntlm->state);
|
res = ntlm_wb_response(conn, input, ntlm->state);
|
||||||
|
|||||||
266
lib/curl_sasl.c
266
lib/curl_sasl.c
@@ -23,6 +23,7 @@
|
|||||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||||
* RFC4616 PLAIN authentication
|
* RFC4616 PLAIN authentication
|
||||||
* RFC6749 OAuth 2.0 Authorization Framework
|
* RFC6749 OAuth 2.0 Authorization Framework
|
||||||
|
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@@ -40,6 +41,10 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
|
|
||||||
|
#ifdef USE_NSS
|
||||||
|
#include "nssg.h" /* for Curl_nss_force_init() */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
|
|
||||||
@@ -50,7 +55,7 @@
|
|||||||
/* Retrieves the value for a corresponding key from the challenge string
|
/* Retrieves the value for a corresponding key from the challenge string
|
||||||
* returns TRUE if the key could be found, FALSE if it does not exists
|
* returns TRUE if the key could be found, FALSE if it does not exists
|
||||||
*/
|
*/
|
||||||
static bool sasl_digest_get_key_value(const unsigned char *chlg,
|
static bool sasl_digest_get_key_value(const char *chlg,
|
||||||
const char *key,
|
const char *key,
|
||||||
char *value,
|
char *value,
|
||||||
size_t max_val_len,
|
size_t max_val_len,
|
||||||
@@ -59,7 +64,7 @@ static bool sasl_digest_get_key_value(const unsigned char *chlg,
|
|||||||
char *find_pos;
|
char *find_pos;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
find_pos = strstr((const char *) chlg, key);
|
find_pos = strstr(chlg, key);
|
||||||
if(!find_pos)
|
if(!find_pos)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -163,7 +168,37 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
/*
|
/*
|
||||||
|
* Curl_sasl_decode_cram_md5_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded CRAM-MD5 challenge message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* chlg64 [in] - Pointer to the base64 encoded challenge message.
|
||||||
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
|
* holding the result will be stored upon completion.
|
||||||
|
* outlen [out] - The length of the output message.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
|
||||||
|
size_t *outlen)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
size_t chlg64len = strlen(chlg64);
|
||||||
|
|
||||||
|
*outptr = NULL;
|
||||||
|
*outlen = 0;
|
||||||
|
|
||||||
|
/* Decode the challenge if necessary */
|
||||||
|
if(chlg64len && *chlg64 != '=')
|
||||||
|
result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
* Curl_sasl_create_cram_md5_message()
|
* Curl_sasl_create_cram_md5_message()
|
||||||
*
|
*
|
||||||
* This is used to generate an already encoded CRAM-MD5 response message ready
|
* This is used to generate an already encoded CRAM-MD5 response message ready
|
||||||
@@ -172,7 +207,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
|
* chlg [in] - The challenge.
|
||||||
* userp [in] - The user name.
|
* userp [in] - The user name.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
@@ -182,47 +217,36 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *chlg,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
size_t chlg64len = strlen(chlg64);
|
|
||||||
unsigned char *chlg = (unsigned char *) NULL;
|
|
||||||
size_t chlglen = 0;
|
size_t chlglen = 0;
|
||||||
HMAC_context *ctxt;
|
HMAC_context *ctxt;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
unsigned char digest[MD5_DIGEST_LEN];
|
||||||
char *response;
|
char *response;
|
||||||
|
|
||||||
/* Decode the challenge if necessary */
|
if(chlg)
|
||||||
if(chlg64len && *chlg64 != '=') {
|
chlglen = strlen(chlg);
|
||||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute the digest using the password as the key */
|
/* Compute the digest using the password as the key */
|
||||||
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
|
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
|
||||||
(const unsigned char *) passwdp,
|
(const unsigned char *) passwdp,
|
||||||
curlx_uztoui(strlen(passwdp)));
|
curlx_uztoui(strlen(passwdp)));
|
||||||
|
if(!ctxt)
|
||||||
if(!ctxt) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the digest with the given challenge */
|
/* Update the digest with the given challenge */
|
||||||
if(chlglen > 0)
|
if(chlglen > 0)
|
||||||
Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen));
|
Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
|
||||||
|
curlx_uztoui(chlglen));
|
||||||
Curl_safefree(chlg);
|
|
||||||
|
|
||||||
/* Finalise the digest */
|
/* Finalise the digest */
|
||||||
Curl_HMAC_final(ctxt, digest);
|
Curl_HMAC_final(ctxt, digest);
|
||||||
|
|
||||||
/* Prepare the response */
|
/* Generate the response */
|
||||||
response = aprintf(
|
response = aprintf(
|
||||||
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
userp, digest[0], digest[1], digest[2], digest[3], digest[4],
|
userp, digest[0], digest[1], digest[2], digest[3], digest[4],
|
||||||
@@ -231,13 +255,74 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
if(!response)
|
if(!response)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the response */
|
||||||
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
||||||
|
|
||||||
Curl_safefree(response);
|
Curl_safefree(response);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_sasl_decode_digest_md5_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded DIGEST-MD5 challenge message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* chlg64 [in] - Pointer to the base64 encoded challenge message.
|
||||||
|
* nonce [in/out] - The buffer where the nonce will be stored.
|
||||||
|
* nlen [in] - The length of the nonce buffer.
|
||||||
|
* realm [in/out] - The buffer where the realm will be stored.
|
||||||
|
* rlen [in] - The length of the realm buffer.
|
||||||
|
* alg [in/out] - The buffer where the algorithm will be stored.
|
||||||
|
* alen [in] - The length of the algorithm buffer.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64,
|
||||||
|
char *nonce, size_t nlen,
|
||||||
|
char *realm, size_t rlen,
|
||||||
|
char *alg, size_t alen)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
unsigned char *chlg = NULL;
|
||||||
|
size_t chlglen = 0;
|
||||||
|
size_t chlg64len = strlen(chlg64);
|
||||||
|
|
||||||
|
if(chlg64len && *chlg64 != '=') {
|
||||||
|
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure we have a valid challenge message */
|
||||||
|
if(!chlg)
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
|
/* Retrieve nonce string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) {
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve realm string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "realm=\"", realm, rlen, '\"')) {
|
||||||
|
/* Challenge does not have a realm, set empty string [RFC2831] page 6 */
|
||||||
|
strcpy(realm, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve algorithm string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) {
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_sasl_create_digest_md5_message()
|
* Curl_sasl_create_digest_md5_message()
|
||||||
*
|
*
|
||||||
@@ -247,10 +332,11 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
|
* nonce [in] - The nonce.
|
||||||
|
* realm [in] - The realm.
|
||||||
* userp [in] - The user name.
|
* userp [in] - The user name.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* service [in] - The service type such as www, smtp or pop
|
* service [in] - The service type such as www, smtp, pop or imap.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
* holding the result will be stored upon completion.
|
* holding the result will be stored upon completion.
|
||||||
* outlen [out] - The length of the output message.
|
* outlen [out] - The length of the output message.
|
||||||
@@ -258,71 +344,36 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *nonce,
|
||||||
|
const char *realm,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
const char *service,
|
const char *service,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
#ifndef DEBUGBUILD
|
||||||
static const char table16[] = "0123456789abcdef";
|
static const char table16[] = "0123456789abcdef";
|
||||||
|
#endif
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
unsigned char *chlg = (unsigned char *) NULL;
|
|
||||||
size_t chlglen = 0;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
MD5_context *ctxt;
|
MD5_context *ctxt;
|
||||||
|
char *response = NULL;
|
||||||
unsigned char digest[MD5_DIGEST_LEN];
|
unsigned char digest[MD5_DIGEST_LEN];
|
||||||
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
|
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
char HA2_hex[2 * MD5_DIGEST_LEN + 1];
|
char HA2_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
|
char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
|
||||||
|
|
||||||
char nonce[64];
|
|
||||||
char realm[128];
|
|
||||||
char alg[64];
|
|
||||||
char nonceCount[] = "00000001";
|
char nonceCount[] = "00000001";
|
||||||
char cnonce[] = "12345678"; /* will be changed */
|
char cnonce[] = "12345678"; /* will be changed */
|
||||||
char method[] = "AUTHENTICATE";
|
char method[] = "AUTHENTICATE";
|
||||||
char qop[] = "auth";
|
char qop[] = "auth";
|
||||||
char uri[128];
|
char uri[128];
|
||||||
char response[512];
|
|
||||||
|
|
||||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if(!chlg)
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
|
|
||||||
/* Retrieve nonce string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "nonce=\"", nonce,
|
|
||||||
sizeof(nonce), '\"')) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve realm string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "realm=\"", realm,
|
|
||||||
sizeof(realm), '\"')) {
|
|
||||||
/* Challenge does not have a realm, set empty string [RFC2831] page 6 */
|
|
||||||
strcpy(realm, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve algorithm string from the challenge */
|
|
||||||
if(!sasl_digest_get_key_value(chlg, "algorithm=", alg, sizeof(alg), ',')) {
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(chlg);
|
|
||||||
|
|
||||||
/* We do not support other algorithms */
|
|
||||||
if(strcmp(alg, "md5-sess") != 0)
|
|
||||||
return CURLE_LOGIN_DENIED;
|
|
||||||
|
|
||||||
|
#ifndef DEBUGBUILD
|
||||||
/* Generate 64 bits of random data */
|
/* Generate 64 bits of random data */
|
||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
cnonce[i] = table16[Curl_rand(data)%16];
|
cnonce[i] = table16[Curl_rand(data)%16];
|
||||||
|
#endif
|
||||||
|
|
||||||
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
|
||||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||||
@@ -401,14 +452,20 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
|||||||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||||
snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
|
snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
|
||||||
|
|
||||||
snprintf(response, sizeof(response),
|
/* Generate the response */
|
||||||
"username=\"%s\",realm=\"%s\",nonce=\"%s\","
|
response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
|
||||||
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s",
|
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s",
|
||||||
userp, realm, nonce,
|
userp, realm, nonce,
|
||||||
cnonce, nonceCount, uri, resp_hash_hex);
|
cnonce, nonceCount, uri, resp_hash_hex);
|
||||||
|
if(!response)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the response */
|
||||||
return Curl_base64_encode(data, response, 0, outptr, outlen);
|
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
||||||
|
|
||||||
|
Curl_safefree(response);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -438,8 +495,36 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr,
|
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr, outlen);
|
||||||
outlen);
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Curl_sasl_decode_ntlm_type2_message()
|
||||||
|
*
|
||||||
|
* This is used to decode an already encoded NTLM type-2 message.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* data [in] - Pointer to session handle.
|
||||||
|
* type2msg [in] - Pointer to the base64 encoded type-2 message.
|
||||||
|
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||||
|
*
|
||||||
|
* Returns CURLE_OK on success.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
|
||||||
|
const char *type2msg,
|
||||||
|
struct ntlmdata *ntlm)
|
||||||
|
{
|
||||||
|
#ifdef USE_NSS
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
|
/* make sure the crypto backend is initialized */
|
||||||
|
result = Curl_nss_force_init(data);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Curl_ntlm_decode_type2_message(data, type2msg, ntlm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -451,7 +536,6 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - Pointer to session handle.
|
* data [in] - Pointer to session handle.
|
||||||
* header [in] - Pointer to the base64 encoded type-2 message buffer.
|
|
||||||
* userp [in] - The user name in the format User or Domain\User.
|
* userp [in] - The user name in the format User or Domain\User.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||||
@@ -462,33 +546,27 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||||
const char *header,
|
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm);
|
return Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr,
|
||||||
|
outlen);
|
||||||
if(!result)
|
|
||||||
result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm,
|
|
||||||
outptr, outlen);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
#endif /* USE_NTLM */
|
#endif /* USE_NTLM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Curl_sasl_create_xoauth2_message()
|
* Curl_sasl_create_xoauth2_message()
|
||||||
*
|
*
|
||||||
* This is used to generate an already encoded XOAUTH2 message ready
|
* This is used to generate an already encoded OAuth 2.0 message ready for
|
||||||
* for sending to the recipient.
|
* sending to the recipient.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
*
|
*
|
||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* user [in] - The user name.
|
* user [in] - The user name.
|
||||||
* bearer [in] - The XOAUTH Bearer token.
|
* bearer [in] - The bearer token.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
* holding the result will be stored upon completion.
|
* holding the result will be stored upon completion.
|
||||||
* outlen [out] - The length of the output message.
|
* outlen [out] - The length of the output message.
|
||||||
@@ -500,16 +578,20 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
|
|||||||
const char *bearer,
|
const char *bearer,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
char *xoauth;
|
CURLcode result = CURLE_OK;
|
||||||
|
char *xoauth = NULL;
|
||||||
|
|
||||||
|
/* Generate the message */
|
||||||
xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
|
xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
|
||||||
|
|
||||||
if(!xoauth)
|
if(!xoauth)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Base64 encode the reply */
|
/* Base64 encode the reply */
|
||||||
return Curl_base64_encode(data, xoauth, strlen(xoauth), outptr,
|
result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
|
||||||
outlen);
|
|
||||||
|
Curl_safefree(xoauth);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -66,16 +66,27 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
|||||||
size_t *outlen);
|
size_t *outlen);
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
|
/* This is used to decode a base64 encoded CRAM-MD5 challange message */
|
||||||
|
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
|
||||||
|
size_t *outlen);
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded CRAM-MD5 response message */
|
/* This is used to generate a base64 encoded CRAM-MD5 response message */
|
||||||
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *chlg,
|
||||||
const char *user,
|
const char *user,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
char **outptr, size_t *outlen);
|
char **outptr, size_t *outlen);
|
||||||
|
|
||||||
|
/* This is used to decode a base64 encoded DIGEST-MD5 challange message */
|
||||||
|
CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64,
|
||||||
|
char *nonce, size_t nlen,
|
||||||
|
char *realm, size_t rlen,
|
||||||
|
char *alg, size_t alen);
|
||||||
|
|
||||||
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||||
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||||
const char *chlg64,
|
const char *nonce,
|
||||||
|
const char *realm,
|
||||||
const char *user,
|
const char *user,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
const char *service,
|
const char *service,
|
||||||
@@ -90,10 +101,13 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
|||||||
char **outptr,
|
char **outptr,
|
||||||
size_t *outlen);
|
size_t *outlen);
|
||||||
|
|
||||||
/* This is used to decode an incoming NTLM type-2 message and generate a
|
/* This is used to decode a base64 encoded NTLM type-2 message */
|
||||||
base64 encoded type-3 response */
|
CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
|
||||||
|
const char *type2msg,
|
||||||
|
struct ntlmdata *ntlm);
|
||||||
|
|
||||||
|
/* This is used to generate a base64 encoded NTLM type-3 message */
|
||||||
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||||
const char *header,
|
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
|
|||||||
@@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
|||||||
SP_PROT_TLS1_1_CLIENT |
|
SP_PROT_TLS1_1_CLIENT |
|
||||||
SP_PROT_TLS1_2_CLIENT;
|
SP_PROT_TLS1_2_CLIENT;
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT;
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
|
||||||
break;
|
break;
|
||||||
|
|||||||
13
lib/cyassl.c
13
lib/cyassl.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -98,8 +98,19 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||||||
req_method = SSLv23_client_method();
|
req_method = SSLv23_client_method();
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, "
|
||||||
|
"TLS 1.0 is used exclusively\n");
|
||||||
req_method = TLSv1_client_method();
|
req_method = TLSv1_client_method();
|
||||||
break;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
req_method = TLSv1_client_method();
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
req_method = TLSv1_1_client_method();
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
req_method = TLSv1_2_client_method();
|
||||||
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
req_method = SSLv3_client_method();
|
req_method = SSLv3_client_method();
|
||||||
break;
|
break;
|
||||||
|
|||||||
56
lib/easy.c
56
lib/easy.c
@@ -50,11 +50,6 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
|
|
||||||
#define SIGPIPE_IGNORE 1
|
|
||||||
#include <signal.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "strequal.h"
|
#include "strequal.h"
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
@@ -78,6 +73,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "conncache.h"
|
#include "conncache.h"
|
||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
|
#include "sigpipe.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -85,56 +81,6 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#ifdef SIGPIPE_IGNORE
|
|
||||||
struct sigpipe_ignore {
|
|
||||||
struct sigaction old_pipe_act;
|
|
||||||
bool no_signal;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
|
|
||||||
* internals, and then sigpipe_restore() will restore the situation when we
|
|
||||||
* return from libcurl again.
|
|
||||||
*/
|
|
||||||
static void sigpipe_ignore(struct SessionHandle *data,
|
|
||||||
struct sigpipe_ignore *ig)
|
|
||||||
{
|
|
||||||
/* get a local copy of no_signal because the SessionHandle might not be
|
|
||||||
around when we restore */
|
|
||||||
ig->no_signal = data->set.no_signal;
|
|
||||||
if(!data->set.no_signal) {
|
|
||||||
struct sigaction action;
|
|
||||||
/* first, extract the existing situation */
|
|
||||||
memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
|
|
||||||
sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
|
|
||||||
action = ig->old_pipe_act;
|
|
||||||
/* ignore this signal */
|
|
||||||
action.sa_handler = SIG_IGN;
|
|
||||||
sigaction(SIGPIPE, &action, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sigpipe_restore() puts back the outside world's opinion of signal handler
|
|
||||||
* and SIGPIPE handling. It MUST only be called after a corresponding
|
|
||||||
* sigpipe_ignore() was used.
|
|
||||||
*/
|
|
||||||
static void sigpipe_restore(struct sigpipe_ignore *ig)
|
|
||||||
{
|
|
||||||
if(!ig->no_signal)
|
|
||||||
/* restore the outside state */
|
|
||||||
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* for systems without sigaction */
|
|
||||||
#define sigpipe_ignore(x,y) Curl_nop_stmt
|
|
||||||
#define sigpipe_restore(x) Curl_nop_stmt
|
|
||||||
#define SIGPIPE_VARIABLE(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
||||||
of win32_init() */
|
of win32_init() */
|
||||||
static void win32_cleanup(void)
|
static void win32_cleanup(void)
|
||||||
|
|||||||
188
lib/ftp.c
188
lib/ftp.c
@@ -1802,23 +1802,87 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform the necessary magic that needs to be done once the TCP connection
|
||||||
|
* to the proxy has completed.
|
||||||
|
*/
|
||||||
|
static CURLcode proxy_magic(struct connectdata *conn,
|
||||||
|
char *newhost, unsigned short newport,
|
||||||
|
bool *magicdone)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
struct SessionHandle *data=conn->data;
|
||||||
|
|
||||||
|
*magicdone = FALSE;
|
||||||
|
switch(conn->proxytype) {
|
||||||
|
case CURLPROXY_SOCKS5:
|
||||||
|
case CURLPROXY_SOCKS5_HOSTNAME:
|
||||||
|
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
|
||||||
|
newport, SECONDARYSOCKET, conn);
|
||||||
|
*magicdone = TRUE;
|
||||||
|
break;
|
||||||
|
case CURLPROXY_SOCKS4:
|
||||||
|
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||||
|
SECONDARYSOCKET, conn, FALSE);
|
||||||
|
*magicdone = TRUE;
|
||||||
|
break;
|
||||||
|
case CURLPROXY_SOCKS4A:
|
||||||
|
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||||
|
SECONDARYSOCKET, conn, TRUE);
|
||||||
|
*magicdone = TRUE;
|
||||||
|
break;
|
||||||
|
case CURLPROXY_HTTP:
|
||||||
|
case CURLPROXY_HTTP_1_0:
|
||||||
|
/* do nothing here. handled later. */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
failf(data, "unknown proxytype option given");
|
||||||
|
result = CURLE_COULDNT_CONNECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||||
|
/* BLOCKING */
|
||||||
|
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||||
|
|
||||||
|
/* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
|
||||||
|
* member conn->proto.http; we want FTP through HTTP and we have to
|
||||||
|
* change the member temporarily for connecting to the HTTP proxy. After
|
||||||
|
* Curl_proxyCONNECT we have to set back the member to the original
|
||||||
|
* struct FTP pointer
|
||||||
|
*/
|
||||||
|
struct HTTP http_proxy;
|
||||||
|
struct FTP *ftp_save = data->req.protop;
|
||||||
|
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||||
|
data->req.protop = &http_proxy;
|
||||||
|
|
||||||
|
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
|
||||||
|
|
||||||
|
data->req.protop = ftp_save;
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
|
||||||
|
/* the CONNECT procedure is not complete, the tunnel is not yet up */
|
||||||
|
state(conn, FTP_STOP); /* this phase is completed */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*magicdone = TRUE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||||
int ftpcode)
|
int ftpcode)
|
||||||
{
|
{
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
Curl_addrinfo *conninfo;
|
|
||||||
struct Curl_dns_entry *addr=NULL;
|
struct Curl_dns_entry *addr=NULL;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned short connectport; /* the local port connect() should use! */
|
unsigned short connectport; /* the local port connect() should use! */
|
||||||
unsigned short newport=0; /* remote port */
|
|
||||||
bool connected;
|
|
||||||
|
|
||||||
/* newhost must be able to hold a full IP-style address in ASCII, which
|
|
||||||
in the IPv6 case means 5*8-1 = 39 letters */
|
|
||||||
#define NEWHOST_BUFSIZE 48
|
|
||||||
char newhost[NEWHOST_BUFSIZE];
|
|
||||||
char *str=&data->state.buffer[4]; /* start on the first letter */
|
char *str=&data->state.buffer[4]; /* start on the first letter */
|
||||||
|
|
||||||
if((ftpc->count1 == 0) &&
|
if((ftpc->count1 == 0) &&
|
||||||
@@ -1851,7 +1915,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||||
}
|
}
|
||||||
if(ptr) {
|
if(ptr) {
|
||||||
newport = (unsigned short)(num & 0xffff);
|
ftpc->newport = (unsigned short)(num & 0xffff);
|
||||||
|
|
||||||
if(conn->bits.tunnel_proxy ||
|
if(conn->bits.tunnel_proxy ||
|
||||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||||
@@ -1860,10 +1924,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
|
||||||
|
conn->host.name);
|
||||||
else
|
else
|
||||||
/* use the same IP we are already connected to */
|
/* use the same IP we are already connected to */
|
||||||
snprintf(newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
|
snprintf(ftpc->newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1916,14 +1981,15 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||||
proxy address not the ftp host */
|
proxy address not the ftp host */
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
|
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s", conn->host.name);
|
||||||
else
|
else
|
||||||
snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
|
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
|
||||||
|
conn->ip_addr_str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
snprintf(newhost, sizeof(newhost),
|
snprintf(ftpc->newhost, sizeof(ftpc->newhost),
|
||||||
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||||
newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
|
ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
|
||||||
}
|
}
|
||||||
else if(ftpc->count1 == 0) {
|
else if(ftpc->count1 == 0) {
|
||||||
/* EPSV failed, move on to PASV */
|
/* EPSV failed, move on to PASV */
|
||||||
@@ -1957,24 +2023,21 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* normal, direct, ftp connection */
|
/* normal, direct, ftp connection */
|
||||||
rc = Curl_resolv(conn, newhost, newport, &addr);
|
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
|
||||||
if(rc == CURLRESOLV_PENDING)
|
if(rc == CURLRESOLV_PENDING)
|
||||||
/* BLOCKING */
|
/* BLOCKING */
|
||||||
(void)Curl_resolver_wait_resolv(conn, &addr);
|
(void)Curl_resolver_wait_resolv(conn, &addr);
|
||||||
|
|
||||||
connectport = newport; /* we connect to the remote port */
|
connectport = ftpc->newport; /* we connect to the remote port */
|
||||||
|
|
||||||
if(!addr) {
|
if(!addr) {
|
||||||
failf(data, "Can't resolve new host %s:%hu", newhost, connectport);
|
failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
|
||||||
return CURLE_FTP_CANT_GET_HOST;
|
return CURLE_FTP_CANT_GET_HOST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Curl_connecthost(conn,
|
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
|
||||||
addr,
|
result = Curl_connecthost(conn, addr);
|
||||||
&conn->sock[SECONDARYSOCKET],
|
|
||||||
&conninfo,
|
|
||||||
&connected);
|
|
||||||
|
|
||||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||||
|
|
||||||
@@ -1985,88 +2048,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When this is used from the multi interface, this might've returned with
|
* When this is used from the multi interface, this might've returned with
|
||||||
* the 'connected' set to FALSE and thus we are now awaiting a non-blocking
|
* the 'connected' set to FALSE and thus we are now awaiting a non-blocking
|
||||||
* connect to connect and we should not be "hanging" here waiting.
|
* connect to connect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(data->set.verbose)
|
if(data->set.verbose)
|
||||||
/* this just dumps information about this second connection */
|
/* this just dumps information about this second connection */
|
||||||
ftp_pasv_verbose(conn, conninfo, newhost, connectport);
|
ftp_pasv_verbose(conn, conn->ip_addr, ftpc->newhost, connectport);
|
||||||
|
|
||||||
switch(conn->proxytype) {
|
|
||||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
|
||||||
* FALSE */
|
|
||||||
case CURLPROXY_SOCKS5:
|
|
||||||
case CURLPROXY_SOCKS5_HOSTNAME:
|
|
||||||
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost, newport,
|
|
||||||
SECONDARYSOCKET, conn);
|
|
||||||
connected = TRUE;
|
|
||||||
break;
|
|
||||||
case CURLPROXY_SOCKS4:
|
|
||||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
|
||||||
SECONDARYSOCKET, conn, FALSE);
|
|
||||||
connected = TRUE;
|
|
||||||
break;
|
|
||||||
case CURLPROXY_SOCKS4A:
|
|
||||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
|
||||||
SECONDARYSOCKET, conn, TRUE);
|
|
||||||
connected = TRUE;
|
|
||||||
break;
|
|
||||||
case CURLPROXY_HTTP:
|
|
||||||
case CURLPROXY_HTTP_1_0:
|
|
||||||
/* do nothing here. handled later. */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
failf(data, "unknown proxytype option given");
|
|
||||||
result = CURLE_COULDNT_CONNECT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result) {
|
|
||||||
if(ftpc->count1 == 0 && ftpcode == 229)
|
|
||||||
return ftp_epsv_disable(conn);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
|
||||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
|
||||||
* FALSE */
|
|
||||||
|
|
||||||
/* BLOCKING */
|
|
||||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
|
||||||
|
|
||||||
/* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
|
|
||||||
* conn->proto.http; we want FTP through HTTP and we have to change the
|
|
||||||
* member temporarily for connecting to the HTTP proxy. After
|
|
||||||
* Curl_proxyCONNECT we have to set back the member to the original struct
|
|
||||||
* FTP pointer
|
|
||||||
*/
|
|
||||||
struct HTTP http_proxy;
|
|
||||||
struct FTP *ftp_save = data->req.protop;
|
|
||||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
|
||||||
data->req.protop = &http_proxy;
|
|
||||||
|
|
||||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
|
|
||||||
|
|
||||||
data->req.protop = ftp_save;
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
|
|
||||||
/* the CONNECT procedure is not complete, the tunnel is not yet up */
|
|
||||||
state(conn, FTP_STOP); /* this phase is completed */
|
|
||||||
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
|
|
||||||
conn->bits.do_more = TRUE;
|
conn->bits.do_more = TRUE;
|
||||||
state(conn, FTP_STOP); /* this phase is completed */
|
state(conn, FTP_STOP); /* this phase is completed */
|
||||||
|
|
||||||
@@ -3625,6 +3617,10 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
|||||||
/* Ready to do more? */
|
/* Ready to do more? */
|
||||||
if(connected) {
|
if(connected) {
|
||||||
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
|
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
|
||||||
|
if(conn->bits.proxy) {
|
||||||
|
infof(data, "Connection to proxy confirmed\n");
|
||||||
|
result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(result && (ftpc->count1 == 0)) {
|
if(result && (ftpc->count1 == 0)) {
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ struct ftp_conn {
|
|||||||
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
||||||
LIST parsing was done and wc_statemach set
|
LIST parsing was done and wc_statemach set
|
||||||
it */
|
it */
|
||||||
|
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||||
|
in the IPv6 case means 5*8-1 = 39 letters */
|
||||||
|
#define NEWHOST_BUFSIZE 48
|
||||||
|
char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
|
||||||
|
unsigned short newport; /* connection to */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
|
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
|
||||||
|
|||||||
@@ -277,7 +277,57 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
|||||||
ptr.to_certinfo = &data->info.certs;
|
ptr.to_certinfo = &data->info.certs;
|
||||||
*param_slistp = ptr.to_slist;
|
*param_slistp = ptr.to_slist;
|
||||||
break;
|
break;
|
||||||
|
case CURLINFO_TLS_SESSION:
|
||||||
|
{
|
||||||
|
struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
|
||||||
|
param_slistp;
|
||||||
|
struct curl_tlssessioninfo *tsi = &data->tsi;
|
||||||
|
struct connectdata *conn = data->easy_conn;
|
||||||
|
unsigned int sockindex = 0;
|
||||||
|
|
||||||
|
*tsip = tsi;
|
||||||
|
tsi->backend = CURLSSLBACKEND_NONE;
|
||||||
|
tsi->internals = NULL;
|
||||||
|
|
||||||
|
if(!conn)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Find the active ("in use") SSL connection, if any */
|
||||||
|
while((sockindex < sizeof(conn->ssl) / sizeof(conn->ssl[0])) &&
|
||||||
|
(!conn->ssl[sockindex].use))
|
||||||
|
sockindex++;
|
||||||
|
|
||||||
|
if(sockindex == sizeof(conn->ssl) / sizeof(conn->ssl[0]))
|
||||||
|
break; /* no SSL session found */
|
||||||
|
|
||||||
|
/* Return the TLS session information from the relevant backend */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
tsi->backend = CURLSSLBACKEND_OPENSSL;
|
||||||
|
tsi->internals = conn->ssl[sockindex].ctx;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_GNUTLS
|
||||||
|
tsi->backend = CURLSSLBACKEND_GNUTLS;
|
||||||
|
tsi->internals = conn->ssl[sockindex].session;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_NSS
|
||||||
|
tsi->backend = CURLSSLBACKEND_NSS;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_QSOSSL
|
||||||
|
tsi->backend = CURLSSLBACKEND_QSOSSL;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_GSKIT
|
||||||
|
tsi->backend = CURLSSLBACKEND_GSKIT;
|
||||||
|
tsi->internals = conn->ssl[sockindex].handle;
|
||||||
|
#endif
|
||||||
|
/* NOTE: For other SSL backends, it is not immediately clear what data
|
||||||
|
to return from 'struct ssl_connect_data'; thus, for now we keep the
|
||||||
|
backend as CURLSSLBACKEND_NONE in those cases, which should be
|
||||||
|
interpreted as "not supported" */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|||||||
459
lib/gskit.c
459
lib/gskit.c
@@ -29,9 +29,38 @@
|
|||||||
|
|
||||||
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
|
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
|
||||||
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
|
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
|
||||||
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
|
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_TLSV10_CIPHER_SPECS
|
||||||
|
#define GSK_TLSV10_CIPHER_SPECS 236
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_TLSV11_CIPHER_SPECS
|
||||||
|
#define GSK_TLSV11_CIPHER_SPECS 237
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_TLSV12_CIPHER_SPECS
|
||||||
|
#define GSK_TLSV12_CIPHER_SPECS 238
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_PROTOCOL_TLSV11
|
||||||
|
#define GSK_PROTOCOL_TLSV11 437
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_PROTOCOL_TLSV12
|
||||||
|
#define GSK_PROTOCOL_TLSV12 438
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_FALSE
|
||||||
|
#define GSK_FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GSK_TRUE
|
||||||
|
#define GSK_TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_LIMITS_H
|
#ifdef HAVE_LIMITS_H
|
||||||
# include <limits.h>
|
# include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -54,30 +83,65 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* SSL version flags. */
|
||||||
|
#define CURL_GSKPROTO_SSLV2 0
|
||||||
|
#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
|
||||||
|
#define CURL_GSKPROTO_SSLV3 1
|
||||||
|
#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
|
||||||
|
#define CURL_GSKPROTO_TLSV10 2
|
||||||
|
#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
|
||||||
|
#define CURL_GSKPROTO_TLSV11 3
|
||||||
|
#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
|
||||||
|
#define CURL_GSKPROTO_TLSV12 4
|
||||||
|
#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
|
||||||
|
#define CURL_GSKPROTO_LAST 5
|
||||||
|
|
||||||
|
|
||||||
/* Supported ciphers. */
|
/* Supported ciphers. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char * name; /* Cipher name. */
|
const char *name; /* Cipher name. */
|
||||||
const char * gsktoken; /* Corresponding token for GSKit String. */
|
const char *gsktoken; /* Corresponding token for GSKit String. */
|
||||||
int sslver; /* SSL version. */
|
unsigned int versions; /* SSL version flags. */
|
||||||
} gskit_cipher;
|
} gskit_cipher;
|
||||||
|
|
||||||
static const gskit_cipher ciphertable[] = {
|
static const gskit_cipher ciphertable[] = {
|
||||||
{ "null-md5", "01", CURL_SSLVERSION_SSLv3 },
|
{ "null-md5", "01",
|
||||||
{ "null-sha", "02", CURL_SSLVERSION_SSLv3 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
{ "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
|
||||||
{ "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
|
{ "null-sha", "02",
|
||||||
{ "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
{ "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
|
||||||
{ "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
|
{ "exp-rc4-md5", "03",
|
||||||
{ "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
|
||||||
{ "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
|
{ "rc4-md5", "04",
|
||||||
{ "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
{ "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
|
||||||
{ "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
|
{ "rc4-sha", "05",
|
||||||
{ "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
{ "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
|
||||||
{ "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
|
{ "exp-rc2-cbc-md5", "06",
|
||||||
{ "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
|
||||||
|
{ "exp-des-cbc-sha", "09",
|
||||||
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV11_MASK },
|
||||||
|
{ "des-cbc3-sha", "0A",
|
||||||
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "aes128-sha", "2F",
|
||||||
|
CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "aes256-sha", "35",
|
||||||
|
CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "aes128-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
|
||||||
|
{ "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
|
{ "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
|
{ "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
|
{ "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
|
{ "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
|
{ "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
|
||||||
{ (const char *) NULL, (const char *) NULL, 0 }
|
{ (const char *) NULL, (const char *) NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,8 +161,8 @@ static bool is_separator(char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode gskit_status(struct SessionHandle * data, int rc,
|
static CURLcode gskit_status(struct SessionHandle *data, int rc,
|
||||||
const char * procname, CURLcode defcode)
|
const char *procname, CURLcode defcode)
|
||||||
{
|
{
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
|
|
||||||
@@ -137,13 +201,13 @@ static CURLcode gskit_status(struct SessionHandle * data, int rc,
|
|||||||
default:
|
default:
|
||||||
failf(data, "%s: %s", procname, gsk_strerror(rc));
|
failf(data, "%s: %s", procname, gsk_strerror(rc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return defcode;
|
return defcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode set_enum(struct SessionHandle * data,
|
static CURLcode set_enum(struct SessionHandle *data, gsk_handle h,
|
||||||
gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
|
GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
|
||||||
{
|
{
|
||||||
int rc = gsk_attribute_set_enum(h, id, value);
|
int rc = gsk_attribute_set_enum(h, id, value);
|
||||||
|
|
||||||
@@ -153,6 +217,9 @@ static CURLcode set_enum(struct SessionHandle * data,
|
|||||||
case GSK_ERROR_IO:
|
case GSK_ERROR_IO:
|
||||||
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
|
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
|
||||||
break;
|
break;
|
||||||
|
case GSK_ATTRIBUTE_INVALID_ID:
|
||||||
|
if(unsupported_ok)
|
||||||
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
default:
|
default:
|
||||||
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
|
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
|
||||||
break;
|
break;
|
||||||
@@ -161,8 +228,8 @@ static CURLcode set_enum(struct SessionHandle * data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode set_buffer(struct SessionHandle * data,
|
static CURLcode set_buffer(struct SessionHandle *data, gsk_handle h,
|
||||||
gsk_handle h, GSK_BUF_ID id, const char * buffer)
|
GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
|
||||||
{
|
{
|
||||||
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
|
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
|
||||||
|
|
||||||
@@ -172,6 +239,9 @@ static CURLcode set_buffer(struct SessionHandle * data,
|
|||||||
case GSK_ERROR_IO:
|
case GSK_ERROR_IO:
|
||||||
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
|
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
|
||||||
break;
|
break;
|
||||||
|
case GSK_ATTRIBUTE_INVALID_ID:
|
||||||
|
if(unsupported_ok)
|
||||||
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
default:
|
default:
|
||||||
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
|
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
|
||||||
break;
|
break;
|
||||||
@@ -180,7 +250,7 @@ static CURLcode set_buffer(struct SessionHandle * data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode set_numeric(struct SessionHandle * data,
|
static CURLcode set_numeric(struct SessionHandle *data,
|
||||||
gsk_handle h, GSK_NUM_ID id, int value)
|
gsk_handle h, GSK_NUM_ID id, int value)
|
||||||
{
|
{
|
||||||
int rc = gsk_attribute_set_numeric_value(h, id, value);
|
int rc = gsk_attribute_set_numeric_value(h, id, value);
|
||||||
@@ -200,8 +270,8 @@ static CURLcode set_numeric(struct SessionHandle * data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode set_callback(struct SessionHandle * data,
|
static CURLcode set_callback(struct SessionHandle *data,
|
||||||
gsk_handle h, GSK_CALLBACK_ID id, void * info)
|
gsk_handle h, GSK_CALLBACK_ID id, void *info)
|
||||||
{
|
{
|
||||||
int rc = gsk_attribute_set_callback(h, id, info);
|
int rc = gsk_attribute_set_callback(h, id, info);
|
||||||
|
|
||||||
@@ -219,17 +289,20 @@ static CURLcode set_callback(struct SessionHandle * data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
|
static CURLcode set_ciphers(struct SessionHandle *data,
|
||||||
|
gsk_handle h, unsigned int *protoflags)
|
||||||
{
|
{
|
||||||
const char * cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
|
const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
|
||||||
char * sslv2ciphers;
|
const char *clp;
|
||||||
char * sslv3ciphers;
|
const gskit_cipher *ctp;
|
||||||
const char * clp;
|
|
||||||
const gskit_cipher * ctp;
|
|
||||||
char * v2p;
|
|
||||||
char * v3p;
|
|
||||||
int i;
|
int i;
|
||||||
|
int l;
|
||||||
|
bool unsupported;
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
|
struct {
|
||||||
|
char *buf;
|
||||||
|
char *ptr;
|
||||||
|
} ciphers[CURL_GSKPROTO_LAST];
|
||||||
|
|
||||||
/* Compile cipher list into GSKit-compatible cipher lists. */
|
/* Compile cipher list into GSKit-compatible cipher lists. */
|
||||||
|
|
||||||
@@ -243,42 +316,44 @@ static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
|
|||||||
/* We allocate GSKit buffers of the same size as the input string: since
|
/* We allocate GSKit buffers of the same size as the input string: since
|
||||||
GSKit tokens are always shorter than their cipher names, allocated buffers
|
GSKit tokens are always shorter than their cipher names, allocated buffers
|
||||||
will always be large enough to accomodate the result. */
|
will always be large enough to accomodate the result. */
|
||||||
i = strlen(cipherlist) + 1;
|
l = strlen(cipherlist) + 1;
|
||||||
v2p = malloc(i);
|
memset((char *) ciphers, 0, sizeof ciphers);
|
||||||
if(!v2p)
|
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
|
||||||
return CURLE_OUT_OF_MEMORY;
|
ciphers[i].buf = malloc(l);
|
||||||
v3p = malloc(i);
|
if(!ciphers[i].buf) {
|
||||||
if(!v3p) {
|
while(i--)
|
||||||
free(v2p);
|
free(ciphers[i].buf);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
ciphers[i].ptr = ciphers[i].buf;
|
||||||
|
*ciphers[i].ptr = '\0';
|
||||||
}
|
}
|
||||||
sslv2ciphers = v2p;
|
|
||||||
sslv3ciphers = v3p;
|
|
||||||
|
|
||||||
/* Process each cipher in input string. */
|
/* Process each cipher in input string. */
|
||||||
|
unsupported = FALSE;
|
||||||
|
cc = CURLE_OK;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
|
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
|
||||||
cipherlist++;
|
cipherlist++;
|
||||||
i = cipherlist - clp;
|
l = cipherlist - clp;
|
||||||
if(!i)
|
if(!l)
|
||||||
break;
|
break;
|
||||||
/* Search the cipher in our table. */
|
/* Search the cipher in our table. */
|
||||||
for(ctp = ciphertable; ctp->name; ctp++)
|
for(ctp = ciphertable; ctp->name; ctp++)
|
||||||
if(strnequal(ctp->name, clp, i) && !ctp->name[i])
|
if(strnequal(ctp->name, clp, l) && !ctp->name[l])
|
||||||
break;
|
break;
|
||||||
if(!ctp->name)
|
if(!ctp->name) {
|
||||||
failf(data, "Unknown cipher %.*s: ignored", i, clp);
|
failf(data, "Unknown cipher %.*s", l, clp);
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
switch (ctp->sslver) {
|
unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
|
||||||
case CURL_SSLVERSION_SSLv2:
|
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
|
||||||
strcpy(v2p, ctp->gsktoken);
|
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
|
||||||
v2p += strlen(v2p);
|
if(ctp->versions & (1 << i)) {
|
||||||
break;
|
strcpy(ciphers[i].ptr, ctp->gsktoken);
|
||||||
default:
|
ciphers[i].ptr += strlen(ctp->gsktoken);
|
||||||
/* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
|
}
|
||||||
strcpy(v3p, ctp->gsktoken);
|
|
||||||
v3p += strlen(v3p);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,13 +361,63 @@ static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
|
|||||||
while(is_separator(*cipherlist))
|
while(is_separator(*cipherlist))
|
||||||
cipherlist++;
|
cipherlist++;
|
||||||
}
|
}
|
||||||
*v2p = '\0';
|
|
||||||
*v3p = '\0';
|
/* Disable protocols with empty cipher lists. */
|
||||||
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
|
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
|
||||||
if(cc == CURLE_OK)
|
if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
|
||||||
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
|
*protoflags &= ~(1 << i);
|
||||||
free(sslv2ciphers);
|
ciphers[i].buf[0] = '\0';
|
||||||
free(sslv3ciphers);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
|
||||||
|
if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
|
||||||
|
cc = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
|
||||||
|
ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
|
||||||
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||||
|
cc = CURLE_OK;
|
||||||
|
if(unsupported) {
|
||||||
|
failf(data, "TLSv1.1-only ciphers are not yet supported");
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
|
||||||
|
cc = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
|
||||||
|
ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
|
||||||
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||||
|
cc = CURLE_OK;
|
||||||
|
if(unsupported) {
|
||||||
|
failf(data, "TLSv1.2-only ciphers are not yet supported");
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
|
||||||
|
the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
|
||||||
|
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
|
||||||
|
cc = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
|
||||||
|
ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
|
||||||
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||||
|
cc = CURLE_OK;
|
||||||
|
strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
|
||||||
|
ciphers[CURL_GSKPROTO_TLSV10].ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set-up other ciphers. */
|
||||||
|
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
|
||||||
|
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
|
||||||
|
ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
|
||||||
|
if(cc == CURLE_OK && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
|
||||||
|
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
|
||||||
|
ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
|
||||||
|
|
||||||
|
/* Clean-up. */
|
||||||
|
for(i = 0; i < CURL_GSKPROTO_LAST; i++)
|
||||||
|
free(ciphers[i].buf);
|
||||||
|
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,10 +436,10 @@ void Curl_gskit_cleanup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode init_environment(struct SessionHandle * data,
|
static CURLcode init_environment(struct SessionHandle *data,
|
||||||
gsk_handle * envir, const char * appid,
|
gsk_handle *envir, const char *appid,
|
||||||
const char * file, const char * label,
|
const char *file, const char *label,
|
||||||
const char * password)
|
const char *password)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
CURLcode c;
|
CURLcode c;
|
||||||
@@ -333,15 +458,15 @@ static CURLcode init_environment(struct SessionHandle * data,
|
|||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
|
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
|
||||||
if(c == CURLE_OK && appid)
|
if(c == CURLE_OK && appid)
|
||||||
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid);
|
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
|
||||||
if(c == CURLE_OK && file)
|
if(c == CURLE_OK && file)
|
||||||
c = set_buffer(data, h, GSK_KEYRING_FILE, file);
|
c = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
|
||||||
if(c == CURLE_OK && label)
|
if(c == CURLE_OK && label)
|
||||||
c = set_buffer(data, h, GSK_KEYRING_LABEL, label);
|
c = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
|
||||||
if(c == CURLE_OK && password)
|
if(c == CURLE_OK && password)
|
||||||
c = set_buffer(data, h, GSK_KEYRING_PW, password);
|
c = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
|
||||||
|
|
||||||
if(c == CURLE_OK) {
|
if(c == CURLE_OK) {
|
||||||
/* Locate CAs, Client certificate and key according to our settings.
|
/* Locate CAs, Client certificate and key according to our settings.
|
||||||
@@ -359,9 +484,9 @@ static CURLcode init_environment(struct SessionHandle * data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void cancel_async_handshake(struct connectdata * conn, int sockindex)
|
static void cancel_async_handshake(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
Qso_OverlappedIO_t cstat;
|
Qso_OverlappedIO_t cstat;
|
||||||
|
|
||||||
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
|
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
|
||||||
@@ -369,15 +494,15 @@ static void cancel_async_handshake(struct connectdata * conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void close_async_handshake(struct ssl_connect_data * connssl)
|
static void close_async_handshake(struct ssl_connect_data *connssl)
|
||||||
{
|
{
|
||||||
QsoDestroyIOCompletionPort(connssl->iocport);
|
QsoDestroyIOCompletionPort(connssl->iocport);
|
||||||
connssl->iocport = -1;
|
connssl->iocport = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void close_one(struct ssl_connect_data * conn,
|
static void close_one(struct ssl_connect_data *conn,
|
||||||
struct SessionHandle * data)
|
struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
if(conn->handle) {
|
if(conn->handle) {
|
||||||
gskit_status(data, gsk_secure_soc_close(&conn->handle),
|
gskit_status(data, gsk_secure_soc_close(&conn->handle),
|
||||||
@@ -389,10 +514,10 @@ static void close_one(struct ssl_connect_data * conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t gskit_send(struct connectdata * conn, int sockindex,
|
static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||||
const void * mem, size_t len, CURLcode * curlcode)
|
const void *mem, size_t len, CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
int written;
|
int written;
|
||||||
|
|
||||||
@@ -408,10 +533,10 @@ static ssize_t gskit_send(struct connectdata * conn, int sockindex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t gskit_recv(struct connectdata * conn, int num, char * buf,
|
static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||||
size_t buffersize, CURLcode * curlcode)
|
size_t buffersize, CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
int buffsize;
|
int buffsize;
|
||||||
int nread;
|
int nread;
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
@@ -428,20 +553,18 @@ static ssize_t gskit_recv(struct connectdata * conn, int num, char * buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
|
static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
gsk_handle envir;
|
gsk_handle envir;
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
int rc;
|
int rc;
|
||||||
char * keyringfile;
|
char *keyringfile;
|
||||||
char * keyringpwd;
|
char *keyringpwd;
|
||||||
char * keyringlabel;
|
char *keyringlabel;
|
||||||
char * v2ciphers;
|
char *sni;
|
||||||
char * v3ciphers;
|
unsigned int protoflags;
|
||||||
char * sni;
|
|
||||||
bool sslv2enable, sslv3enable, tlsv1enable;
|
|
||||||
long timeout;
|
long timeout;
|
||||||
Qso_OverlappedIO_t commarea;
|
Qso_OverlappedIO_t commarea;
|
||||||
|
|
||||||
@@ -491,43 +614,39 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
|
|||||||
return cc;
|
return cc;
|
||||||
|
|
||||||
/* Determine which SSL/TLS version should be enabled. */
|
/* Determine which SSL/TLS version should be enabled. */
|
||||||
sslv2enable = sslv3enable = tlsv1enable = false;
|
protoflags = CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
|
||||||
sni = conn->host.name;
|
sni = conn->host.name;
|
||||||
switch (data->set.ssl.version) {
|
switch (data->set.ssl.version) {
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
sslv2enable = true;
|
protoflags = CURL_GSKPROTO_SSLV2_MASK;
|
||||||
sni = (char *) NULL;
|
sni = (char *) NULL;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
sslv3enable = true;
|
protoflags = CURL_GSKPROTO_SSLV2_MASK;
|
||||||
sni = (char *) NULL;
|
sni = (char *) NULL;
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
tlsv1enable = true;
|
protoflags = CURL_GSKPROTO_TLSV10_MASK |
|
||||||
|
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
|
||||||
break;
|
break;
|
||||||
default: /* CURL_SSLVERSION_DEFAULT. */
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
sslv3enable = true;
|
protoflags = CURL_GSKPROTO_TLSV10_MASK;
|
||||||
tlsv1enable = true;
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
protoflags = CURL_GSKPROTO_TLSV11_MASK;
|
||||||
|
break;
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
protoflags = CURL_GSKPROTO_TLSV12_MASK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
|
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
|
||||||
if(sni) {
|
if(sni) {
|
||||||
rc = gsk_attribute_set_buffer(connssl->handle,
|
cc = set_buffer(data, connssl->handle,
|
||||||
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
|
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
|
||||||
switch (rc) {
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL)
|
||||||
case GSK_OK:
|
cc = CURLE_OK;
|
||||||
case GSK_ATTRIBUTE_INVALID_ID:
|
|
||||||
break;
|
|
||||||
case GSK_ERROR_IO:
|
|
||||||
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
|
|
||||||
cc = CURLE_SSL_CONNECT_ERROR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
|
|
||||||
cc = CURLE_SSL_CONNECT_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set session parameters. */
|
/* Set session parameters. */
|
||||||
@@ -544,23 +663,51 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
|
|||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
|
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
|
||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_ciphers(data, connssl->handle);
|
cc = set_ciphers(data, connssl->handle, &protoflags);
|
||||||
|
if(!protoflags) {
|
||||||
|
failf(data, "No SSL protocol/cipher combination enabled");
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
|
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
|
||||||
sslv2enable? GSK_PROTOCOL_SSLV2_ON:
|
(protoflags & CURL_GSKPROTO_SSLV2_MASK)?
|
||||||
GSK_PROTOCOL_SSLV2_OFF);
|
GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
|
||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
|
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
|
||||||
sslv3enable? GSK_PROTOCOL_SSLV3_ON:
|
(protoflags & CURL_GSKPROTO_SSLV3_MASK)?
|
||||||
GSK_PROTOCOL_SSLV3_OFF);
|
GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
|
||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
|
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
|
||||||
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
|
(protoflags & CURL_GSKPROTO_TLSV10_MASK)?
|
||||||
GSK_PROTOCOL_TLSV1_OFF);
|
GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
|
||||||
|
if(cc == CURLE_OK) {
|
||||||
|
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11,
|
||||||
|
(protoflags & CURL_GSKPROTO_TLSV11_MASK)?
|
||||||
|
GSK_TRUE: GSK_FALSE, TRUE);
|
||||||
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||||
|
cc = CURLE_OK;
|
||||||
|
if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
|
||||||
|
failf(data, "TLS 1.1 not yet supported");
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cc == CURLE_OK) {
|
||||||
|
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12,
|
||||||
|
(protoflags & CURL_GSKPROTO_TLSV12_MASK)?
|
||||||
|
GSK_TRUE: GSK_FALSE, TRUE);
|
||||||
|
if(cc == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||||
|
cc = CURLE_OK;
|
||||||
|
if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
|
||||||
|
failf(data, "TLS 1.2 not yet supported");
|
||||||
|
cc = CURLE_SSL_CIPHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if(cc == CURLE_OK)
|
if(cc == CURLE_OK)
|
||||||
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
|
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
|
||||||
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
|
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
|
||||||
GSK_SERVER_AUTH_PASSTHRU);
|
GSK_SERVER_AUTH_PASSTHRU, FALSE);
|
||||||
|
|
||||||
if(cc == CURLE_OK) {
|
if(cc == CURLE_OK) {
|
||||||
/* Start handshake. Try asynchronous first. */
|
/* Start handshake. Try asynchronous first. */
|
||||||
@@ -596,11 +743,11 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode gskit_connect_step2(struct connectdata * conn, int sockindex,
|
static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
|
||||||
bool nonblocking)
|
bool nonblocking)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
Qso_OverlappedIO_t cstat;
|
Qso_OverlappedIO_t cstat;
|
||||||
long timeout_ms;
|
long timeout_ms;
|
||||||
struct timeval stmv;
|
struct timeval stmv;
|
||||||
@@ -648,15 +795,15 @@ static CURLcode gskit_connect_step2(struct connectdata * conn, int sockindex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode gskit_connect_step3(struct connectdata * conn, int sockindex)
|
static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
const gsk_cert_data_elem * cdev;
|
const gsk_cert_data_elem *cdev;
|
||||||
int cdec;
|
int cdec;
|
||||||
const gsk_cert_data_elem * p;
|
const gsk_cert_data_elem *p;
|
||||||
const char * cert = (const char *) NULL;
|
const char *cert = (const char *) NULL;
|
||||||
const char * certend;
|
const char *certend;
|
||||||
int i;
|
int i;
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
|
|
||||||
@@ -715,11 +862,11 @@ static CURLcode gskit_connect_step3(struct connectdata * conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CURLcode gskit_connect_common(struct connectdata * conn, int sockindex,
|
static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||||
bool nonblocking, bool * done)
|
bool nonblocking, bool *done)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
long timeout_ms;
|
long timeout_ms;
|
||||||
Qso_OverlappedIO_t cstat;
|
Qso_OverlappedIO_t cstat;
|
||||||
CURLcode cc = CURLE_OK;
|
CURLcode cc = CURLE_OK;
|
||||||
@@ -774,9 +921,9 @@ static CURLcode gskit_connect_common(struct connectdata * conn, int sockindex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
|
CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
|
||||||
int sockindex,
|
int sockindex,
|
||||||
bool * done)
|
bool *done)
|
||||||
{
|
{
|
||||||
CURLcode cc;
|
CURLcode cc;
|
||||||
|
|
||||||
@@ -787,7 +934,7 @@ CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex)
|
CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
CURLcode retcode;
|
CURLcode retcode;
|
||||||
bool done;
|
bool done;
|
||||||
@@ -803,17 +950,17 @@ CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Curl_gskit_close(struct connectdata * conn, int sockindex)
|
void Curl_gskit_close(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
|
||||||
if(connssl->use)
|
if(connssl->use)
|
||||||
close_one(connssl, data);
|
close_one(connssl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Curl_gskit_close_all(struct SessionHandle * data)
|
int Curl_gskit_close_all(struct SessionHandle *data)
|
||||||
{
|
{
|
||||||
/* Unimplemented. */
|
/* Unimplemented. */
|
||||||
(void) data;
|
(void) data;
|
||||||
@@ -821,10 +968,10 @@ int Curl_gskit_close_all(struct SessionHandle * data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex)
|
int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
struct SessionHandle * data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
int what;
|
int what;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -875,14 +1022,14 @@ int Curl_gskit_shutdown(struct connectdata * conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t Curl_gskit_version(char * buffer, size_t size)
|
size_t Curl_gskit_version(char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
strncpy(buffer, "GSKit", size);
|
strncpy(buffer, "GSKit", size);
|
||||||
return strlen(buffer);
|
return strlen(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Curl_gskit_check_cxn(struct connectdata * cxn)
|
int Curl_gskit_check_cxn(struct connectdata *cxn)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int errlen;
|
int errlen;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -633,10 +633,8 @@ gtls_connect_step3(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
infof(data, "\t server certificate verification OK\n");
|
infof(data, "\t server certificate verification OK\n");
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
infof(data, "\t server certificate verification SKIPPED\n");
|
infof(data, "\t server certificate verification SKIPPED\n");
|
||||||
goto after_server_cert_verification;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize an X.509 certificate structure. */
|
/* initialize an X.509 certificate structure. */
|
||||||
gnutls_x509_crt_init(&x509_cert);
|
gnutls_x509_crt_init(&x509_cert);
|
||||||
@@ -766,8 +764,6 @@ gtls_connect_step3(struct connectdata *conn,
|
|||||||
|
|
||||||
gnutls_x509_crt_deinit(x509_cert);
|
gnutls_x509_crt_deinit(x509_cert);
|
||||||
|
|
||||||
after_server_cert_verification:
|
|
||||||
|
|
||||||
/* compression algorithm (if any) */
|
/* compression algorithm (if any) */
|
||||||
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
|
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
|
||||||
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
|
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
|
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
|
||||||
defined(USE_GSKIT)
|
defined(USE_GSKIT) || defined(USE_NSS)
|
||||||
/* these backends use functions from this file */
|
/* these backends use functions from this file */
|
||||||
|
|
||||||
#include "hostcheck.h"
|
#include "hostcheck.h"
|
||||||
@@ -94,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */
|
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT or NSS */
|
||||||
|
|||||||
13
lib/hostip.c
13
lib/hostip.c
@@ -291,9 +291,10 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
|||||||
{
|
{
|
||||||
struct hostcache_prune_data user;
|
struct hostcache_prune_data user;
|
||||||
|
|
||||||
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
|
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache ||
|
||||||
/* cache forever means never prune, and NULL hostcache means
|
dns->inuse)
|
||||||
we can't do it */
|
/* cache forever means never prune, and NULL hostcache means we can't do
|
||||||
|
it, if it still is in use then we leave it */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
time(&user.now);
|
time(&user.now);
|
||||||
@@ -428,9 +429,13 @@ int Curl_resolv(struct connectdata *conn,
|
|||||||
/* free the allocated entry_id again */
|
/* free the allocated entry_id again */
|
||||||
free(entry_id);
|
free(entry_id);
|
||||||
|
|
||||||
|
infof(data, "Hostname was %sfound in DNS cache\n", dns?"":"NOT ");
|
||||||
|
|
||||||
/* See whether the returned entry is stale. Done before we release lock */
|
/* See whether the returned entry is stale. Done before we release lock */
|
||||||
if(remove_entry_if_stale(data, dns))
|
if(remove_entry_if_stale(data, dns)) {
|
||||||
|
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||||
|
}
|
||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
dns->inuse++; /* we use it! */
|
dns->inuse++; /* we use it! */
|
||||||
|
|||||||
95
lib/http.c
95
lib/http.c
@@ -187,25 +187,25 @@ char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
|
|||||||
* case of allocation failure. Returns an empty string if the header value
|
* case of allocation failure. Returns an empty string if the header value
|
||||||
* consists entirely of whitespace.
|
* consists entirely of whitespace.
|
||||||
*/
|
*/
|
||||||
static char *copy_header_value(const char *h)
|
char *Curl_copy_header_value(const char *header)
|
||||||
{
|
{
|
||||||
const char *start;
|
const char *start;
|
||||||
const char *end;
|
const char *end;
|
||||||
char *value;
|
char *value;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
DEBUGASSERT(h);
|
DEBUGASSERT(header);
|
||||||
|
|
||||||
/* Find the end of the header name */
|
/* Find the end of the header name */
|
||||||
while(*h && (*h != ':'))
|
while(*header && (*header != ':'))
|
||||||
++h;
|
++header;
|
||||||
|
|
||||||
if(*h)
|
if(*header)
|
||||||
/* Skip over colon */
|
/* Skip over colon */
|
||||||
++h;
|
++header;
|
||||||
|
|
||||||
/* Find the first non-space letter */
|
/* Find the first non-space letter */
|
||||||
start = h;
|
start = header;
|
||||||
while(*start && ISSPACE(*start))
|
while(*start && ISSPACE(*start))
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ static char *copy_header_value(const char *h)
|
|||||||
end--;
|
end--;
|
||||||
|
|
||||||
/* get length of the type */
|
/* get length of the type */
|
||||||
len = end-start+1;
|
len = end - start + 1;
|
||||||
|
|
||||||
value = malloc(len + 1);
|
value = malloc(len + 1);
|
||||||
if(!value)
|
if(!value)
|
||||||
@@ -699,9 +699,8 @@ Curl_http_output_auth(struct connectdata *conn,
|
|||||||
* proxy CONNECT loop.
|
* proxy CONNECT loop.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||||
int httpcode,
|
const char *auth) /* the first non-space */
|
||||||
const char *header) /* the first non-space */
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This resource requires authentication
|
* This resource requires authentication
|
||||||
@@ -709,24 +708,17 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
unsigned long *availp;
|
unsigned long *availp;
|
||||||
const char *start;
|
|
||||||
struct auth *authp;
|
struct auth *authp;
|
||||||
|
|
||||||
if(httpcode == 407) {
|
if(proxy) {
|
||||||
start = header+strlen("Proxy-authenticate:");
|
|
||||||
availp = &data->info.proxyauthavail;
|
availp = &data->info.proxyauthavail;
|
||||||
authp = &data->state.authproxy;
|
authp = &data->state.authproxy;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
start = header+strlen("WWW-Authenticate:");
|
|
||||||
availp = &data->info.httpauthavail;
|
availp = &data->info.httpauthavail;
|
||||||
authp = &data->state.authhost;
|
authp = &data->state.authhost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass all white spaces */
|
|
||||||
while(*start && ISSPACE(*start))
|
|
||||||
start++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here we check if we want the specific single authentication (using ==) and
|
* Here we check if we want the specific single authentication (using ==) and
|
||||||
* if we do, we initiate usage of it.
|
* if we do, we initiate usage of it.
|
||||||
@@ -744,10 +736,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while(*start) {
|
while(*auth) {
|
||||||
#ifdef USE_HTTP_NEGOTIATE
|
#ifdef USE_HTTP_NEGOTIATE
|
||||||
if(checkprefix("GSS-Negotiate", start) ||
|
if(checkprefix("GSS-Negotiate", auth) ||
|
||||||
checkprefix("Negotiate", start)) {
|
checkprefix("Negotiate", auth)) {
|
||||||
int neg;
|
int neg;
|
||||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||||
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||||
@@ -760,7 +752,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
|
neg = Curl_input_negotiate(conn, proxy, auth);
|
||||||
if(neg == 0) {
|
if(neg == 0) {
|
||||||
DEBUGASSERT(!data->req.newurl);
|
DEBUGASSERT(!data->req.newurl);
|
||||||
data->req.newurl = strdup(data->change.url);
|
data->req.newurl = strdup(data->change.url);
|
||||||
@@ -779,14 +771,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_NTLM
|
#ifdef USE_NTLM
|
||||||
/* NTLM support requires the SSL crypto libs */
|
/* NTLM support requires the SSL crypto libs */
|
||||||
if(checkprefix("NTLM", start)) {
|
if(checkprefix("NTLM", auth)) {
|
||||||
*availp |= CURLAUTH_NTLM;
|
*availp |= CURLAUTH_NTLM;
|
||||||
authp->avail |= CURLAUTH_NTLM;
|
authp->avail |= CURLAUTH_NTLM;
|
||||||
if(authp->picked == CURLAUTH_NTLM ||
|
if(authp->picked == CURLAUTH_NTLM ||
|
||||||
authp->picked == CURLAUTH_NTLM_WB) {
|
authp->picked == CURLAUTH_NTLM_WB) {
|
||||||
/* NTLM authentication is picked and activated */
|
/* NTLM authentication is picked and activated */
|
||||||
CURLcode ntlm =
|
CURLcode ntlm =
|
||||||
Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
|
Curl_input_ntlm(conn, proxy, auth);
|
||||||
if(CURLE_OK == ntlm) {
|
if(CURLE_OK == ntlm) {
|
||||||
data->state.authproblem = FALSE;
|
data->state.authproblem = FALSE;
|
||||||
#ifdef NTLM_WB_ENABLED
|
#ifdef NTLM_WB_ENABLED
|
||||||
@@ -798,14 +790,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
|
|
||||||
/* Get the challenge-message which will be passed to
|
/* Get the challenge-message which will be passed to
|
||||||
* ntlm_auth for generating the type 3 message later */
|
* ntlm_auth for generating the type 3 message later */
|
||||||
while(*start && ISSPACE(*start))
|
while(*auth && ISSPACE(*auth))
|
||||||
start++;
|
auth++;
|
||||||
if(checkprefix("NTLM", start)) {
|
if(checkprefix("NTLM", auth)) {
|
||||||
start += strlen("NTLM");
|
auth += strlen("NTLM");
|
||||||
while(*start && ISSPACE(*start))
|
while(*auth && ISSPACE(*auth))
|
||||||
start++;
|
auth++;
|
||||||
if(*start)
|
if(*auth)
|
||||||
if((conn->challenge_header = strdup(start)) == NULL)
|
if((conn->challenge_header = strdup(auth)) == NULL)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -820,7 +812,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
if(checkprefix("Digest", start)) {
|
if(checkprefix("Digest", auth)) {
|
||||||
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
if((authp->avail & CURLAUTH_DIGEST) != 0) {
|
||||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||||
}
|
}
|
||||||
@@ -833,7 +825,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
* authentication isn't activated yet, as we need to store the
|
* authentication isn't activated yet, as we need to store the
|
||||||
* incoming data from this header in case we are gonna use
|
* incoming data from this header in case we are gonna use
|
||||||
* Digest. */
|
* Digest. */
|
||||||
dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
|
dig = Curl_input_digest(conn, proxy, auth);
|
||||||
|
|
||||||
if(CURLDIGEST_FINE != dig) {
|
if(CURLDIGEST_FINE != dig) {
|
||||||
infof(data, "Authentication problem. Ignoring this.\n");
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
@@ -843,7 +835,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(checkprefix("Basic", start)) {
|
if(checkprefix("Basic", auth)) {
|
||||||
*availp |= CURLAUTH_BASIC;
|
*availp |= CURLAUTH_BASIC;
|
||||||
authp->avail |= CURLAUTH_BASIC;
|
authp->avail |= CURLAUTH_BASIC;
|
||||||
if(authp->picked == CURLAUTH_BASIC) {
|
if(authp->picked == CURLAUTH_BASIC) {
|
||||||
@@ -857,12 +849,12 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* there may be multiple methods on one line, so keep reading */
|
/* there may be multiple methods on one line, so keep reading */
|
||||||
while(*start && *start != ',') /* read up to the next comma */
|
while(*auth && *auth != ',') /* read up to the next comma */
|
||||||
start++;
|
auth++;
|
||||||
if(*start == ',') /* if we're on a comma, skip it */
|
if(*auth == ',') /* if we're on a comma, skip it */
|
||||||
start++;
|
auth++;
|
||||||
while(*start && ISSPACE(*start))
|
while(*auth && ISSPACE(*auth))
|
||||||
start++;
|
auth++;
|
||||||
}
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -1831,7 +1823,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
|||||||
custom Host: header if this is NOT a redirect, as setting Host: in the
|
custom Host: header if this is NOT a redirect, as setting Host: in the
|
||||||
redirected request is being out on thin ice. Except if the host name
|
redirected request is being out on thin ice. Except if the host name
|
||||||
is the same as the first one! */
|
is the same as the first one! */
|
||||||
char *cookiehost = copy_header_value(ptr);
|
char *cookiehost = Curl_copy_header_value(ptr);
|
||||||
if(!cookiehost)
|
if(!cookiehost)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if(!*cookiehost)
|
if(!*cookiehost)
|
||||||
@@ -3247,7 +3239,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
/* check for Content-Type: header lines to get the MIME-type */
|
/* check for Content-Type: header lines to get the MIME-type */
|
||||||
else if(checkprefix("Content-Type:", k->p)) {
|
else if(checkprefix("Content-Type:", k->p)) {
|
||||||
char *contenttype = copy_header_value(k->p);
|
char *contenttype = Curl_copy_header_value(k->p);
|
||||||
if(!contenttype)
|
if(!contenttype)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if(!*contenttype)
|
if(!*contenttype)
|
||||||
@@ -3259,7 +3251,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(checkprefix("Server:", k->p)) {
|
else if(checkprefix("Server:", k->p)) {
|
||||||
char *server_name = copy_header_value(k->p);
|
char *server_name = Curl_copy_header_value(k->p);
|
||||||
|
|
||||||
/* Turn off pipelining if the server version is blacklisted */
|
/* Turn off pipelining if the server version is blacklisted */
|
||||||
if(conn->bundle && conn->bundle->server_supports_pipelining) {
|
if(conn->bundle && conn->bundle->server_supports_pipelining) {
|
||||||
@@ -3455,7 +3447,16 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
(401 == k->httpcode)) ||
|
(401 == k->httpcode)) ||
|
||||||
(checkprefix("Proxy-authenticate:", k->p) &&
|
(checkprefix("Proxy-authenticate:", k->p) &&
|
||||||
(407 == k->httpcode))) {
|
(407 == k->httpcode))) {
|
||||||
result = Curl_http_input_auth(conn, k->httpcode, k->p);
|
|
||||||
|
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
|
||||||
|
char *auth = Curl_copy_header_value(k->p);
|
||||||
|
if(!auth)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
result = Curl_http_input_auth(conn, proxy, auth);
|
||||||
|
|
||||||
|
Curl_safefree(auth);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3463,7 +3464,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
|||||||
checkprefix("Location:", k->p) &&
|
checkprefix("Location:", k->p) &&
|
||||||
!data->req.location) {
|
!data->req.location) {
|
||||||
/* this is the URL that the server advises us to use instead */
|
/* this is the URL that the server advises us to use instead */
|
||||||
char *location = copy_header_value(k->p);
|
char *location = Curl_copy_header_value(k->p);
|
||||||
if(!location)
|
if(!location)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
if(!*location)
|
if(!*location)
|
||||||
|
|||||||
@@ -35,11 +35,12 @@ extern const struct Curl_handler Curl_handler_http;
|
|||||||
extern const struct Curl_handler Curl_handler_https;
|
extern const struct Curl_handler Curl_handler_https;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Header specific functions */
|
||||||
bool Curl_compareheader(const char *headerline, /* line to check */
|
bool Curl_compareheader(const char *headerline, /* line to check */
|
||||||
const char *header, /* header keyword _with_ colon */
|
const char *header, /* header keyword _with_ colon */
|
||||||
const char *content); /* content string to find */
|
const char *content); /* content string to find */
|
||||||
|
|
||||||
char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader);
|
char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader);
|
||||||
|
char *Curl_copy_header_value(const char *header);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/*
|
/*
|
||||||
@@ -81,8 +82,8 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
|||||||
|
|
||||||
/* These functions are in http.c */
|
/* These functions are in http.c */
|
||||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||||
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||||
int httpcode, const char *header);
|
const char *auth);
|
||||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||||
CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
|
CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
|
||||||
|
|
||||||
|
|||||||
@@ -141,10 +141,6 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
d = &data->state.digest;
|
d = &data->state.digest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip initial whitespaces */
|
|
||||||
while(*header && ISSPACE(*header))
|
|
||||||
header++;
|
|
||||||
|
|
||||||
if(checkprefix("Digest", header)) {
|
if(checkprefix("Digest", header)) {
|
||||||
header += strlen("Digest");
|
header += strlen("Digest");
|
||||||
|
|
||||||
@@ -306,6 +302,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
/* We have a Digest setup for this, use it! Now, to get all the details for
|
/* We have a Digest setup for this, use it! Now, to get all the details for
|
||||||
this sorted out, I must urge you dear friend to read up on the RFC2617
|
this sorted out, I must urge you dear friend to read up on the RFC2617
|
||||||
section 3.2.2, */
|
section 3.2.2, */
|
||||||
|
size_t urilen;
|
||||||
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
||||||
unsigned char request_digest[33];
|
unsigned char request_digest[33];
|
||||||
unsigned char *md5this;
|
unsigned char *md5this;
|
||||||
@@ -440,13 +437,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
Further details on Digest implementation differences:
|
Further details on Digest implementation differences:
|
||||||
http://www.fngtps.com/2006/09/http-authentication
|
http://www.fngtps.com/2006/09/http-authentication
|
||||||
*/
|
*/
|
||||||
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
|
|
||||||
md5this = (unsigned char *)aprintf("%s:%.*s", request,
|
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL))
|
||||||
curlx_sztosi(tmp - (char *)uripath),
|
urilen = tmp - (char *)uripath;
|
||||||
uripath);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
|
urilen = strlen((char *)uripath);
|
||||||
|
|
||||||
|
md5this = (unsigned char *)aprintf("%s:%.*s", request, urilen, uripath);
|
||||||
|
|
||||||
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
|
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
|
||||||
/* We don't support auth-int for PUT or POST at the moment.
|
/* We don't support auth-int for PUT or POST at the moment.
|
||||||
@@ -511,7 +508,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
"username=\"%s\", "
|
"username=\"%s\", "
|
||||||
"realm=\"%s\", "
|
"realm=\"%s\", "
|
||||||
"nonce=\"%s\", "
|
"nonce=\"%s\", "
|
||||||
"uri=\"%s\", "
|
"uri=\"%.*s\", "
|
||||||
"cnonce=\"%s\", "
|
"cnonce=\"%s\", "
|
||||||
"nc=%08x, "
|
"nc=%08x, "
|
||||||
"qop=%s, "
|
"qop=%s, "
|
||||||
@@ -520,7 +517,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
userp_quoted,
|
userp_quoted,
|
||||||
d->realm,
|
d->realm,
|
||||||
d->nonce,
|
d->nonce,
|
||||||
uripath, /* this is the PATH part of the URL */
|
urilen, uripath, /* this is the PATH part of the URL */
|
||||||
d->cnonce,
|
d->cnonce,
|
||||||
d->nc,
|
d->nc,
|
||||||
d->qop,
|
d->qop,
|
||||||
@@ -537,13 +534,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
"username=\"%s\", "
|
"username=\"%s\", "
|
||||||
"realm=\"%s\", "
|
"realm=\"%s\", "
|
||||||
"nonce=\"%s\", "
|
"nonce=\"%s\", "
|
||||||
"uri=\"%s\", "
|
"uri=\"%.*s\", "
|
||||||
"response=\"%s\"",
|
"response=\"%s\"",
|
||||||
proxy?"Proxy-":"",
|
proxy?"Proxy-":"",
|
||||||
userp_quoted,
|
userp_quoted,
|
||||||
d->realm,
|
d->realm,
|
||||||
d->nonce,
|
d->nonce,
|
||||||
uripath, /* this is the PATH part of the URL */
|
urilen, uripath, /* this is the PATH part of the URL */
|
||||||
request_digest);
|
request_digest);
|
||||||
}
|
}
|
||||||
Curl_safefree(userp_quoted);
|
Curl_safefree(userp_quoted);
|
||||||
|
|||||||
@@ -145,8 +145,6 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
const char* protocol;
|
const char* protocol;
|
||||||
CURLcode error;
|
CURLcode error;
|
||||||
|
|
||||||
while(*header && ISSPACE(*header))
|
|
||||||
header++;
|
|
||||||
if(checkprefix("GSS-Negotiate", header)) {
|
if(checkprefix("GSS-Negotiate", header)) {
|
||||||
protocol = "GSS-Negotiate";
|
protocol = "GSS-Negotiate";
|
||||||
gss = TRUE;
|
gss = TRUE;
|
||||||
|
|||||||
@@ -98,9 +98,6 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
|||||||
const char* protocol;
|
const char* protocol;
|
||||||
CURLcode error;
|
CURLcode error;
|
||||||
|
|
||||||
while(*header && ISSPACE(*header))
|
|
||||||
header++;
|
|
||||||
|
|
||||||
if(checkprefix("GSS-Negotiate", header)) {
|
if(checkprefix("GSS-Negotiate", header)) {
|
||||||
protocol = "GSS-Negotiate";
|
protocol = "GSS-Negotiate";
|
||||||
gss = TRUE;
|
gss = TRUE;
|
||||||
|
|||||||
@@ -452,8 +452,16 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
|||||||
(401 == k->httpcode)) ||
|
(401 == k->httpcode)) ||
|
||||||
(checkprefix("Proxy-authenticate:", line_start) &&
|
(checkprefix("Proxy-authenticate:", line_start) &&
|
||||||
(407 == k->httpcode))) {
|
(407 == k->httpcode))) {
|
||||||
result = Curl_http_input_auth(conn, k->httpcode,
|
|
||||||
line_start);
|
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
|
||||||
|
char *auth = Curl_copy_header_value(line_start);
|
||||||
|
if(!auth)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
result = Curl_http_input_auth(conn, proxy, auth);
|
||||||
|
|
||||||
|
Curl_safefree(auth);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
309
lib/imap.c
309
lib/imap.c
@@ -27,6 +27,7 @@
|
|||||||
* RFC4959 IMAP Extension for SASL Initial Client Response
|
* RFC4959 IMAP Extension for SASL Initial Client Response
|
||||||
* RFC5092 IMAP URL Scheme
|
* RFC5092 IMAP URL Scheme
|
||||||
* RFC6749 OAuth 2.0 Authorization Framework
|
* RFC6749 OAuth 2.0 Authorization Framework
|
||||||
|
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@@ -370,6 +371,35 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
|
|||||||
return FALSE; /* Nothing for us */
|
return FALSE; /* Nothing for us */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* imap_get_message()
|
||||||
|
*
|
||||||
|
* Gets the authentication message from the response buffer.
|
||||||
|
*/
|
||||||
|
static void imap_get_message(char *buffer, char** outptr)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char* message = NULL;
|
||||||
|
|
||||||
|
/* Find the start of the message */
|
||||||
|
for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Find the end of the message */
|
||||||
|
for(len = strlen(message); len--;)
|
||||||
|
if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
|
||||||
|
message[len] != '\t')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Terminate the message */
|
||||||
|
if(++len) {
|
||||||
|
message[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
*outptr = message;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* state()
|
||||||
@@ -396,6 +426,7 @@ static void state(struct connectdata *conn, imapstate newstate)
|
|||||||
"AUTHENTICATE_NTLM",
|
"AUTHENTICATE_NTLM",
|
||||||
"AUTHENTICATE_NTLM_TYPE2MSG",
|
"AUTHENTICATE_NTLM_TYPE2MSG",
|
||||||
"AUTHENTICATE_XOAUTH2",
|
"AUTHENTICATE_XOAUTH2",
|
||||||
|
"AUTHENTICATE_CANCEL",
|
||||||
"AUTHENTICATE_FINAL",
|
"AUTHENTICATE_FINAL",
|
||||||
"LOGIN",
|
"LOGIN",
|
||||||
"LIST",
|
"LIST",
|
||||||
@@ -553,8 +584,8 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the supported authentication mechanism by decreasing order of
|
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||||
security */
|
security, as well as the initial response where appropriate */
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
|
if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
|
||||||
(imapc->prefmech & SASL_MECH_DIGEST_MD5)) {
|
(imapc->prefmech & SASL_MECH_DIGEST_MD5)) {
|
||||||
@@ -622,7 +653,7 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
if(mech) {
|
if(mech && (imapc->preftype & IMAP_TYPE_SASL)) {
|
||||||
/* Perform SASL based authentication */
|
/* Perform SASL based authentication */
|
||||||
if(initresp) {
|
if(initresp) {
|
||||||
result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
|
result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
|
||||||
@@ -639,7 +670,8 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
|
|||||||
|
|
||||||
Curl_safefree(initresp);
|
Curl_safefree(initresp);
|
||||||
}
|
}
|
||||||
else if(!imapc->login_disabled)
|
else if((!imapc->login_disabled) &&
|
||||||
|
(imapc->preftype & IMAP_TYPE_CLEARTEXT))
|
||||||
/* Perform clear text authentication */
|
/* Perform clear text authentication */
|
||||||
result = imap_perform_login(conn);
|
result = imap_perform_login(conn);
|
||||||
else {
|
else {
|
||||||
@@ -976,20 +1008,17 @@ static CURLcode imap_state_auth_plain_resp(struct connectdata *conn,
|
|||||||
/* Create the authorisation message */
|
/* Create the authorisation message */
|
||||||
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
|
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
|
||||||
&plainauth, &len);
|
&plainauth, &len);
|
||||||
|
if(!result && plainauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", plainauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||||
if(plainauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", plainauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(plainauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(plainauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,20 +1042,17 @@ static CURLcode imap_state_auth_login_resp(struct connectdata *conn,
|
|||||||
/* Create the user message */
|
/* Create the user message */
|
||||||
result = Curl_sasl_create_login_message(data, conn->user,
|
result = Curl_sasl_create_login_message(data, conn->user,
|
||||||
&authuser, &len);
|
&authuser, &len);
|
||||||
|
if(!result && authuser) {
|
||||||
|
/* Send the user */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authuser);
|
||||||
|
|
||||||
/* Send the user */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_LOGIN_PASSWD);
|
||||||
if(authuser) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authuser);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, IMAP_AUTHENTICATE_LOGIN_PASSWD);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authuser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authuser);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,20 +1076,17 @@ static CURLcode imap_state_auth_login_password_resp(struct connectdata *conn,
|
|||||||
/* Create the password message */
|
/* Create the password message */
|
||||||
result = Curl_sasl_create_login_message(data, conn->passwd,
|
result = Curl_sasl_create_login_message(data, conn->passwd,
|
||||||
&authpasswd, &len);
|
&authpasswd, &len);
|
||||||
|
if(!result && authpasswd) {
|
||||||
|
/* Send the password */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authpasswd);
|
||||||
|
|
||||||
/* Send the password */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||||
if(authpasswd) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authpasswd);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authpasswd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authpasswd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,9 +1098,10 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg = NULL;
|
||||||
size_t len = 0;
|
char *chlg64 = NULL;
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -1086,38 +1110,34 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
imap_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Terminate the challenge */
|
/* Decode the challenge message */
|
||||||
if(*chlg64 != '=') {
|
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
|
||||||
for(len = strlen(chlg64); len--;)
|
if(result) {
|
||||||
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
|
/* Send the cancellation */
|
||||||
chlg64[len] != '\t')
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
|
||||||
break;
|
|
||||||
|
|
||||||
if(++len) {
|
if(!result)
|
||||||
chlg64[len] = '\0';
|
state(conn, IMAP_AUTHENTICATE_CANCEL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* Create the response message */
|
/* Create the response message */
|
||||||
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
|
||||||
conn->passwd, &rplyb64, &len);
|
conn->passwd, &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
/* Send the response */
|
/* Send the response */
|
||||||
if(!result) {
|
|
||||||
if(rplyb64) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1128,9 +1148,13 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg64 = NULL;
|
||||||
size_t len = 0;
|
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
char nonce[64];
|
||||||
|
char realm[128];
|
||||||
|
char algorithm[64];
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -1139,27 +1163,36 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
imap_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Create the response message */
|
/* Decode the challange message */
|
||||||
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||||
conn->passwd, "imap",
|
realm, sizeof(realm),
|
||||||
&rplyb64, &len);
|
algorithm, sizeof(algorithm));
|
||||||
|
if(result || strcmp(algorithm, "md5-sess") != 0) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
|
||||||
|
|
||||||
/* Send the response */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_CANCEL);
|
||||||
if(rplyb64) {
|
}
|
||||||
|
else {
|
||||||
|
/* Create the response message */
|
||||||
|
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
|
||||||
|
conn->user, conn->passwd,
|
||||||
|
"imap", &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
|
/* Send the response */
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP);
|
state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1211,20 +1244,17 @@ static CURLcode imap_state_auth_ntlm_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
||||||
&conn->ntlm,
|
&conn->ntlm,
|
||||||
&type1msg, &len);
|
&type1msg, &len);
|
||||||
|
if(!result && type1msg) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type1msg);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_NTLM_TYPE2MSG);
|
||||||
if(type1msg) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type1msg);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, IMAP_AUTHENTICATE_NTLM_TYPE2MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(type1msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type1msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1235,8 +1265,9 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
size_t len = 0;
|
char *type2msg = NULL;
|
||||||
char *type3msg = NULL;
|
char *type3msg = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -1245,31 +1276,40 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Create the type-3 message */
|
/* Get the challenge message */
|
||||||
result = Curl_sasl_create_ntlm_type3_message(data,
|
imap_get_message(data->state.buffer, &type2msg);
|
||||||
data->state.buffer + 2,
|
|
||||||
conn->user, conn->passwd,
|
|
||||||
&conn->ntlm,
|
|
||||||
&type3msg, &len);
|
|
||||||
|
|
||||||
/* Send the message */
|
/* Decode the type-2 message */
|
||||||
if(!result) {
|
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
|
||||||
if(type3msg) {
|
if(result) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
state(conn, IMAP_AUTHENTICATE_CANCEL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Create the type-3 message */
|
||||||
|
result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
|
||||||
|
conn->passwd, &conn->ntlm,
|
||||||
|
&type3msg, &len);
|
||||||
|
if(!result && type3msg) {
|
||||||
|
/* Send the message */
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type3msg);
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type3msg);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(type3msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type3msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For AUTH XOAUTH2 (without initial response) responses */
|
/* For AUTHENTICATE XOAUTH2 (without initial response) responses */
|
||||||
static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
|
static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
|
||||||
int imapcode,
|
int imapcode,
|
||||||
imapstate instate)
|
imapstate instate)
|
||||||
@@ -1290,24 +1330,36 @@ static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
||||||
conn->xoauth2_bearer,
|
conn->xoauth2_bearer,
|
||||||
&xoauth, &len);
|
&xoauth, &len);
|
||||||
|
if(!result && xoauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", xoauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||||
if(xoauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", xoauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(xoauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(xoauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For final responses to the AUTHENTICATE sequence */
|
/* For AUTHENTICATE cancellation responses */
|
||||||
|
static CURLcode imap_state_auth_cancel_resp(struct connectdata *conn,
|
||||||
|
int imapcode,
|
||||||
|
imapstate instate)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
(void)imapcode;
|
||||||
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
|
failf(data, "Authentication cancelled");
|
||||||
|
|
||||||
|
return CURLE_LOGIN_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For final responses in the AUTHENTICATE sequence */
|
||||||
static CURLcode imap_state_auth_final_resp(struct connectdata *conn,
|
static CURLcode imap_state_auth_final_resp(struct connectdata *conn,
|
||||||
int imapcode,
|
int imapcode,
|
||||||
imapstate instate)
|
imapstate instate)
|
||||||
@@ -1660,6 +1712,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
|
|||||||
result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
|
result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IMAP_AUTHENTICATE_CANCEL:
|
||||||
|
result = imap_state_auth_cancel_resp(conn, imapcode, imapc->state);
|
||||||
|
break;
|
||||||
|
|
||||||
case IMAP_AUTHENTICATE_FINAL:
|
case IMAP_AUTHENTICATE_FINAL:
|
||||||
result = imap_state_auth_final_resp(conn, imapcode, imapc->state);
|
result = imap_state_auth_final_resp(conn, imapcode, imapc->state);
|
||||||
break;
|
break;
|
||||||
@@ -1782,7 +1838,8 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
|
|||||||
pp->endofresp = imap_endofresp;
|
pp->endofresp = imap_endofresp;
|
||||||
pp->conn = conn;
|
pp->conn = conn;
|
||||||
|
|
||||||
/* Set the default preferred authentication mechanism */
|
/* Set the default preferred authentication type and mechanism */
|
||||||
|
imapc->preftype = IMAP_TYPE_ANY;
|
||||||
imapc->prefmech = SASL_AUTH_ANY;
|
imapc->prefmech = SASL_AUTH_ANY;
|
||||||
|
|
||||||
/* Initialise the pingpong layer */
|
/* Initialise the pingpong layer */
|
||||||
@@ -1982,7 +2039,7 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
|
|||||||
|
|
||||||
/* The IMAP session may or may not have been allocated/setup at this
|
/* The IMAP session may or may not have been allocated/setup at this
|
||||||
point! */
|
point! */
|
||||||
if(!dead_connection && imapc->pp.conn)
|
if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
|
||||||
if(!imap_perform_logout(conn))
|
if(!imap_perform_logout(conn))
|
||||||
(void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
|
(void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
|
||||||
|
|
||||||
@@ -2276,24 +2333,42 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
|
|||||||
if(strnequal(key, "AUTH", 4)) {
|
if(strnequal(key, "AUTH", 4)) {
|
||||||
const char *value = ptr + 1;
|
const char *value = ptr + 1;
|
||||||
|
|
||||||
if(strequal(value, "*"))
|
if(strequal(value, "*")) {
|
||||||
|
imapc->preftype = IMAP_TYPE_ANY;
|
||||||
imapc->prefmech = SASL_AUTH_ANY;
|
imapc->prefmech = SASL_AUTH_ANY;
|
||||||
else if(strequal(value, SASL_MECH_STRING_LOGIN))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_LOGIN)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_LOGIN;
|
imapc->prefmech = SASL_MECH_LOGIN;
|
||||||
else if(strequal(value, SASL_MECH_STRING_PLAIN))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_PLAIN)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_PLAIN;
|
imapc->prefmech = SASL_MECH_PLAIN;
|
||||||
else if(strequal(value, SASL_MECH_STRING_CRAM_MD5))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_CRAM_MD5)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_CRAM_MD5;
|
imapc->prefmech = SASL_MECH_CRAM_MD5;
|
||||||
else if(strequal(value, SASL_MECH_STRING_DIGEST_MD5))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_DIGEST_MD5)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_DIGEST_MD5;
|
imapc->prefmech = SASL_MECH_DIGEST_MD5;
|
||||||
else if(strequal(value, SASL_MECH_STRING_GSSAPI))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_GSSAPI)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_GSSAPI;
|
imapc->prefmech = SASL_MECH_GSSAPI;
|
||||||
else if(strequal(value, SASL_MECH_STRING_NTLM))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_NTLM)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_NTLM;
|
imapc->prefmech = SASL_MECH_NTLM;
|
||||||
else if(strequal(value, SASL_MECH_STRING_XOAUTH2))
|
}
|
||||||
|
else if(strequal(value, SASL_MECH_STRING_XOAUTH2)) {
|
||||||
|
imapc->preftype = IMAP_TYPE_SASL;
|
||||||
imapc->prefmech = SASL_MECH_XOAUTH2;
|
imapc->prefmech = SASL_MECH_XOAUTH2;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
imapc->preftype = IMAP_TYPE_NONE;
|
||||||
imapc->prefmech = SASL_AUTH_NONE;
|
imapc->prefmech = SASL_AUTH_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = CURLE_URL_MALFORMAT;
|
result = CURLE_URL_MALFORMAT;
|
||||||
|
|||||||
10
lib/imap.h
10
lib/imap.h
@@ -44,6 +44,7 @@ typedef enum {
|
|||||||
IMAP_AUTHENTICATE_NTLM,
|
IMAP_AUTHENTICATE_NTLM,
|
||||||
IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
|
IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
|
||||||
IMAP_AUTHENTICATE_XOAUTH2,
|
IMAP_AUTHENTICATE_XOAUTH2,
|
||||||
|
IMAP_AUTHENTICATE_CANCEL,
|
||||||
IMAP_AUTHENTICATE_FINAL,
|
IMAP_AUTHENTICATE_FINAL,
|
||||||
IMAP_LOGIN,
|
IMAP_LOGIN,
|
||||||
IMAP_LIST,
|
IMAP_LIST,
|
||||||
@@ -77,6 +78,7 @@ struct imap_conn {
|
|||||||
imapstate state; /* Always use imap.c:state() to change state! */
|
imapstate state; /* Always use imap.c:state() to change state! */
|
||||||
bool ssldone; /* Is connect() over SSL done? */
|
bool ssldone; /* Is connect() over SSL done? */
|
||||||
unsigned int authmechs; /* Accepted authentication mechanisms */
|
unsigned int authmechs; /* Accepted authentication mechanisms */
|
||||||
|
unsigned int preftype; /* Preferred authentication type */
|
||||||
unsigned int prefmech; /* Preferred authentication mechanism */
|
unsigned int prefmech; /* Preferred authentication mechanism */
|
||||||
unsigned int authused; /* Auth mechanism used for the connection */
|
unsigned int authused; /* Auth mechanism used for the connection */
|
||||||
int cmdid; /* Last used command ID */
|
int cmdid; /* Last used command ID */
|
||||||
@@ -91,4 +93,12 @@ struct imap_conn {
|
|||||||
extern const struct Curl_handler Curl_handler_imap;
|
extern const struct Curl_handler Curl_handler_imap;
|
||||||
extern const struct Curl_handler Curl_handler_imaps;
|
extern const struct Curl_handler Curl_handler_imaps;
|
||||||
|
|
||||||
|
/* Authentication type flags */
|
||||||
|
#define IMAP_TYPE_CLEARTEXT (1 << 0)
|
||||||
|
#define IMAP_TYPE_SASL (1 << 1)
|
||||||
|
|
||||||
|
/* Authentication type values */
|
||||||
|
#define IMAP_TYPE_NONE 0
|
||||||
|
#define IMAP_TYPE_ANY ~0U
|
||||||
|
|
||||||
#endif /* HEADER_CURL_IMAP_H */
|
#endif /* HEADER_CURL_IMAP_H */
|
||||||
|
|||||||
33
lib/multi.c
33
lib/multi.c
@@ -41,6 +41,7 @@
|
|||||||
#include "bundles.h"
|
#include "bundles.h"
|
||||||
#include "multihandle.h"
|
#include "multihandle.h"
|
||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
|
#include "sigpipe.h"
|
||||||
|
|
||||||
#define _MPRINTF_REPLACE /* use our functions only */
|
#define _MPRINTF_REPLACE /* use our functions only */
|
||||||
#include <curl/mprintf.h>
|
#include <curl/mprintf.h>
|
||||||
@@ -621,17 +622,28 @@ static int waitconnect_getsock(struct connectdata *conn,
|
|||||||
curl_socket_t *sock,
|
curl_socket_t *sock,
|
||||||
int numsocks)
|
int numsocks)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
int s=0;
|
||||||
|
int rc=0;
|
||||||
|
|
||||||
if(!numsocks)
|
if(!numsocks)
|
||||||
return GETSOCK_BLANK;
|
return GETSOCK_BLANK;
|
||||||
|
|
||||||
sock[0] = conn->sock[FIRSTSOCKET];
|
for(i=0; i<2; i++) {
|
||||||
|
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
|
||||||
|
sock[s] = conn->tempsock[i];
|
||||||
|
rc |= GETSOCK_WRITESOCK(s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* when we've sent a CONNECT to a proxy, we should rather wait for the
|
/* when we've sent a CONNECT to a proxy, we should rather wait for the
|
||||||
socket to become readable to be able to get the response headers */
|
socket to become readable to be able to get the response headers */
|
||||||
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
|
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) {
|
||||||
return GETSOCK_READSOCK(0);
|
sock[0] = conn->sock[FIRSTSOCKET];
|
||||||
|
rc = GETSOCK_READSOCK(0);
|
||||||
|
}
|
||||||
|
|
||||||
return GETSOCK_WRITESOCK(0);
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int domore_getsock(struct connectdata *conn,
|
static int domore_getsock(struct connectdata *conn,
|
||||||
@@ -778,9 +790,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
|
|||||||
|
|
||||||
/* If the internally desired timeout is actually shorter than requested from
|
/* If the internally desired timeout is actually shorter than requested from
|
||||||
the outside, then use the shorter time! But only if the internal timer
|
the outside, then use the shorter time! But only if the internal timer
|
||||||
is actually larger than 0! */
|
is actually larger than -1! */
|
||||||
(void)multi_timeout(multi, &timeout_internal);
|
(void)multi_timeout(multi, &timeout_internal);
|
||||||
if((timeout_internal > 0) && (timeout_internal < (long)timeout_ms))
|
if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
|
||||||
timeout_ms = (int)timeout_internal;
|
timeout_ms = (int)timeout_internal;
|
||||||
|
|
||||||
/* Count up how many fds we have from the multi handle */
|
/* Count up how many fds we have from the multi handle */
|
||||||
@@ -865,6 +877,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
|
|||||||
|
|
||||||
if(nfds) {
|
if(nfds) {
|
||||||
/* wait... */
|
/* wait... */
|
||||||
|
infof(data, "Curl_poll(%d ds, %d ms)\n", nfds, timeout_ms);
|
||||||
i = Curl_poll(ufds, nfds, timeout_ms);
|
i = Curl_poll(ufds, nfds, timeout_ms);
|
||||||
|
|
||||||
if(i) {
|
if(i) {
|
||||||
@@ -1774,12 +1787,18 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
|||||||
struct SessionHandle *nextdata;
|
struct SessionHandle *nextdata;
|
||||||
|
|
||||||
if(GOOD_MULTI_HANDLE(multi)) {
|
if(GOOD_MULTI_HANDLE(multi)) {
|
||||||
|
bool restore_pipe = FALSE;
|
||||||
|
SIGPIPE_VARIABLE(pipe_st);
|
||||||
|
|
||||||
multi->type = 0; /* not good anymore */
|
multi->type = 0; /* not good anymore */
|
||||||
|
|
||||||
/* Close all the connections in the connection cache */
|
/* Close all the connections in the connection cache */
|
||||||
close_all_connections(multi);
|
close_all_connections(multi);
|
||||||
|
|
||||||
if(multi->closure_handle) {
|
if(multi->closure_handle) {
|
||||||
|
sigpipe_ignore(multi->closure_handle, &pipe_st);
|
||||||
|
restore_pipe = TRUE;
|
||||||
|
|
||||||
multi->closure_handle->dns.hostcache = multi->hostcache;
|
multi->closure_handle->dns.hostcache = multi->hostcache;
|
||||||
Curl_hostcache_clean(multi->closure_handle,
|
Curl_hostcache_clean(multi->closure_handle,
|
||||||
multi->closure_handle->dns.hostcache);
|
multi->closure_handle->dns.hostcache);
|
||||||
@@ -1824,6 +1843,8 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
|||||||
Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
|
Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
|
||||||
|
|
||||||
free(multi);
|
free(multi);
|
||||||
|
if(restore_pipe)
|
||||||
|
sigpipe_restore(&pipe_st);
|
||||||
|
|
||||||
return CURLM_OK;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#define MULTI_TIMEOUT_INACCURACY 3000
|
#define MULTI_TIMEOUT_INACCURACY 3000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MULTI_TIMEOUT_INACCURACY_MS (MULTI_TIMEOUT_INACCURACY / 1000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes for library-wide functions provided by multi.c
|
* Prototypes for library-wide functions provided by multi.c
|
||||||
*/
|
*/
|
||||||
|
|||||||
187
lib/nss.c
187
lib/nss.c
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -63,6 +63,7 @@
|
|||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
|
#include "x509asn1.h"
|
||||||
|
|
||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
@@ -76,9 +77,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
|
|||||||
|
|
||||||
PRLock * nss_initlock = NULL;
|
PRLock * nss_initlock = NULL;
|
||||||
PRLock * nss_crllock = NULL;
|
PRLock * nss_crllock = NULL;
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
NSSInitContext * nss_context = NULL;
|
NSSInitContext * nss_context = NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile int initialized = 0;
|
volatile int initialized = 0;
|
||||||
|
|
||||||
@@ -653,6 +652,10 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
|
|||||||
SSLChannelInfo channel;
|
SSLChannelInfo channel;
|
||||||
SSLCipherSuiteInfo suite;
|
SSLCipherSuiteInfo suite;
|
||||||
CERTCertificate *cert;
|
CERTCertificate *cert;
|
||||||
|
CERTCertificate *cert2;
|
||||||
|
CERTCertificate *cert3;
|
||||||
|
PRTime now;
|
||||||
|
int i;
|
||||||
|
|
||||||
if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
|
if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
|
||||||
SECSuccess && channel.length == sizeof channel &&
|
SECSuccess && channel.length == sizeof channel &&
|
||||||
@@ -663,11 +666,45 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
infof(conn->data, "Server certificate:\n");
|
|
||||||
|
|
||||||
cert = SSL_PeerCertificate(sock);
|
cert = SSL_PeerCertificate(sock);
|
||||||
display_cert_info(conn->data, cert);
|
|
||||||
CERT_DestroyCertificate(cert);
|
if(cert) {
|
||||||
|
infof(conn->data, "Server certificate:\n");
|
||||||
|
|
||||||
|
if(!conn->data->set.ssl.certinfo) {
|
||||||
|
display_cert_info(conn->data, cert);
|
||||||
|
CERT_DestroyCertificate(cert);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Count certificates in chain. */
|
||||||
|
now = PR_Now();
|
||||||
|
i = 1;
|
||||||
|
if(!cert->isRoot) {
|
||||||
|
cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
|
||||||
|
while(cert2) {
|
||||||
|
i++;
|
||||||
|
if(cert2->isRoot) {
|
||||||
|
CERT_DestroyCertificate(cert2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
|
||||||
|
CERT_DestroyCertificate(cert2);
|
||||||
|
cert2 = cert3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Curl_ssl_init_certinfo(conn->data, i);
|
||||||
|
for(i = 0; cert; cert = cert2) {
|
||||||
|
Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
|
||||||
|
(char *)cert->derCert.data + cert->derCert.len);
|
||||||
|
if(cert->isRoot) {
|
||||||
|
CERT_DestroyCertificate(cert);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
|
||||||
|
CERT_DestroyCertificate(cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -854,7 +891,6 @@ isTLSIntoleranceError(PRInt32 err)
|
|||||||
|
|
||||||
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
|
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
NSSInitParameters initparams;
|
NSSInitParameters initparams;
|
||||||
|
|
||||||
if(nss_context != NULL)
|
if(nss_context != NULL)
|
||||||
@@ -862,12 +898,6 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
|
|||||||
|
|
||||||
memset((void *) &initparams, '\0', sizeof(initparams));
|
memset((void *) &initparams, '\0', sizeof(initparams));
|
||||||
initparams.length = sizeof(initparams);
|
initparams.length = sizeof(initparams);
|
||||||
#else /* HAVE_NSS_INITCONTEXT */
|
|
||||||
SECStatus rv;
|
|
||||||
|
|
||||||
if(NSS_IsInitialized())
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(cert_dir) {
|
if(cert_dir) {
|
||||||
const bool use_sql = NSS_VersionCheck("3.12.0");
|
const bool use_sql = NSS_VersionCheck("3.12.0");
|
||||||
@@ -876,35 +906,22 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
infof(data, "Initializing NSS with certpath: %s\n", certpath);
|
infof(data, "Initializing NSS with certpath: %s\n", certpath);
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
|
nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
|
||||||
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
|
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
|
||||||
free(certpath);
|
free(certpath);
|
||||||
|
|
||||||
if(nss_context != NULL)
|
if(nss_context != NULL)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* HAVE_NSS_INITCONTEXT */
|
|
||||||
rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY);
|
|
||||||
free(certpath);
|
|
||||||
|
|
||||||
if(rv == SECSuccess)
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
infof(data, "Unable to initialize NSS database\n");
|
infof(data, "Unable to initialize NSS database\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
infof(data, "Initializing NSS with certpath: none\n");
|
infof(data, "Initializing NSS with certpath: none\n");
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
|
nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
|
||||||
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
|
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
|
||||||
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
|
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
|
||||||
if(nss_context != NULL)
|
if(nss_context != NULL)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
#else /* HAVE_NSS_INITCONTEXT */
|
|
||||||
if(NSS_NoDB_Init(NULL) == SECSuccess)
|
|
||||||
return CURLE_OK;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
infof(data, "Unable to initialize NSS\n");
|
infof(data, "Unable to initialize NSS\n");
|
||||||
return CURLE_SSL_CACERT_BADFILE;
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
@@ -1000,12 +1017,8 @@ void Curl_nss_cleanup(void)
|
|||||||
SECMOD_DestroyModule(mod);
|
SECMOD_DestroyModule(mod);
|
||||||
mod = NULL;
|
mod = NULL;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
NSS_ShutdownContext(nss_context);
|
NSS_ShutdownContext(nss_context);
|
||||||
nss_context = NULL;
|
nss_context = NULL;
|
||||||
#else /* HAVE_NSS_INITCONTEXT */
|
|
||||||
NSS_Shutdown();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
PR_Unlock(nss_initlock);
|
PR_Unlock(nss_initlock);
|
||||||
|
|
||||||
@@ -1172,13 +1185,69 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode nss_init_sslver(SSLVersionRange *sslver,
|
||||||
|
struct SessionHandle *data)
|
||||||
|
{
|
||||||
|
switch (data->set.ssl.version) {
|
||||||
|
default:
|
||||||
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
|
if(data->state.ssl_connect_retry) {
|
||||||
|
infof(data, "TLS disabled due to previous handshake failure\n");
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_3_0;
|
||||||
|
}
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||||
|
#elif defined SSL_LIBRARY_VERSION_TLS_1_1
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||||
|
#else
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
#endif
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_SSLv2:
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_2;
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_SSLv3:
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_3_0;
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_3_0;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_1
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||||
|
return CURLE_OK;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
#ifdef SSL_LIBRARY_VERSION_TLS_1_2
|
||||||
|
sslver->min = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||||
|
sslver->max = SSL_LIBRARY_VERSION_TLS_1_2;
|
||||||
|
return CURLE_OK;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
failf(data, "TLS minor version cannot be set");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
PRErrorCode err = 0;
|
PRErrorCode err = 0;
|
||||||
PRFileDesc *model = NULL;
|
PRFileDesc *model = NULL;
|
||||||
PRBool ssl2 = PR_FALSE;
|
|
||||||
PRBool ssl3 = PR_FALSE;
|
|
||||||
PRBool tlsv1 = PR_FALSE;
|
|
||||||
PRBool ssl_no_cache;
|
PRBool ssl_no_cache;
|
||||||
PRBool ssl_cbc_random_iv;
|
PRBool ssl_cbc_random_iv;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
@@ -1190,6 +1259,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
long time_left;
|
long time_left;
|
||||||
PRUint32 timeout;
|
PRUint32 timeout;
|
||||||
|
|
||||||
|
SSLVersionRange sslver = {
|
||||||
|
SSL_LIBRARY_VERSION_3_0, /* min */
|
||||||
|
SSL_LIBRARY_VERSION_TLS_1_0 /* max */
|
||||||
|
};
|
||||||
|
|
||||||
if(connssl->state == ssl_connection_complete)
|
if(connssl->state == ssl_connection_complete)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
@@ -1244,39 +1318,16 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
|
if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* do not use SSL cache if we are not going to verify peer */
|
/* do not use SSL cache if disabled or we are not going to verify peer */
|
||||||
ssl_no_cache = (data->set.ssl.verifypeer) ? PR_FALSE : PR_TRUE;
|
ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
|
||||||
|
PR_FALSE : PR_TRUE;
|
||||||
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
|
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
switch (data->set.ssl.version) {
|
/* enable/disable the requested SSL version(s) */
|
||||||
default:
|
if(nss_init_sslver(&sslver, data) != CURLE_OK)
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
|
||||||
ssl3 = PR_TRUE;
|
|
||||||
if(data->state.ssl_connect_retry)
|
|
||||||
infof(data, "TLS disabled due to previous handshake failure\n");
|
|
||||||
else
|
|
||||||
tlsv1 = PR_TRUE;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1:
|
|
||||||
tlsv1 = PR_TRUE;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_SSLv2:
|
|
||||||
ssl2 = PR_TRUE;
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_SSLv3:
|
|
||||||
ssl3 = PR_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
|
|
||||||
goto error;
|
goto error;
|
||||||
if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
|
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
|
||||||
goto error;
|
|
||||||
if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ssl_cbc_random_iv = !data->set.ssl_enable_beast;
|
ssl_cbc_random_iv = !data->set.ssl_enable_beast;
|
||||||
@@ -1462,11 +1513,13 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
|||||||
if(model)
|
if(model)
|
||||||
PR_Close(model);
|
PR_Close(model);
|
||||||
|
|
||||||
/* cleanup on connection failure */
|
/* cleanup on connection failure */
|
||||||
Curl_llist_destroy(connssl->obj_list, NULL);
|
Curl_llist_destroy(connssl->obj_list, NULL);
|
||||||
connssl->obj_list = NULL;
|
connssl->obj_list = NULL;
|
||||||
|
|
||||||
if(ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
|
if((sslver.min == SSL_LIBRARY_VERSION_3_0)
|
||||||
|
&& (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
|
||||||
|
&& isTLSIntoleranceError(err)) {
|
||||||
/* schedule reconnect through Curl_retry_request() */
|
/* schedule reconnect through Curl_retry_request() */
|
||||||
data->state.ssl_connect_retry = TRUE;
|
data->state.ssl_connect_retry = TRUE;
|
||||||
infof(data, "Error in TLS handshake, trying SSLv3...\n");
|
infof(data, "Error in TLS handshake, trying SSLv3...\n");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@@ -526,7 +526,7 @@ static int parsedate(const char *date, time_t *output)
|
|||||||
/* Add the time zone diff between local time zone and GMT. */
|
/* Add the time zone diff between local time zone and GMT. */
|
||||||
long delta = (long)(tzoff!=-1?tzoff:0);
|
long delta = (long)(tzoff!=-1?tzoff:0);
|
||||||
|
|
||||||
if((delta>0) && (t + delta < t))
|
if((delta>0) && (t > LONG_MAX - delta))
|
||||||
return -1; /* time_t overflow */
|
return -1; /* time_t overflow */
|
||||||
|
|
||||||
t += delta;
|
t += delta;
|
||||||
|
|||||||
268
lib/pop3.c
268
lib/pop3.c
@@ -29,6 +29,7 @@
|
|||||||
* RFC4616 PLAIN authentication
|
* RFC4616 PLAIN authentication
|
||||||
* RFC5034 POP3 SASL Authentication Mechanism
|
* RFC5034 POP3 SASL Authentication Mechanism
|
||||||
* RFC6749 OAuth 2.0 Authorization Framework
|
* RFC6749 OAuth 2.0 Authorization Framework
|
||||||
|
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@@ -349,6 +350,35 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
|
|||||||
return FALSE; /* Nothing for us */
|
return FALSE; /* Nothing for us */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* pop3_get_message()
|
||||||
|
*
|
||||||
|
* Gets the authentication message from the response buffer.
|
||||||
|
*/
|
||||||
|
static void pop3_get_message(char *buffer, char** outptr)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char* message = NULL;
|
||||||
|
|
||||||
|
/* Find the start of the message */
|
||||||
|
for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Find the end of the message */
|
||||||
|
for(len = strlen(message); len--;)
|
||||||
|
if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
|
||||||
|
message[len] != '\t')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Terminate the message */
|
||||||
|
if(++len) {
|
||||||
|
message[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
*outptr = message;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* state()
|
||||||
@@ -375,6 +405,7 @@ static void state(struct connectdata *conn, pop3state newstate)
|
|||||||
"AUTH_NTLM",
|
"AUTH_NTLM",
|
||||||
"AUTH_NTLM_TYPE2MSG",
|
"AUTH_NTLM_TYPE2MSG",
|
||||||
"AUTH_XOAUTH2",
|
"AUTH_XOAUTH2",
|
||||||
|
"AUTH_CANCEL",
|
||||||
"AUTH_FINAL",
|
"AUTH_FINAL",
|
||||||
"APOP",
|
"APOP",
|
||||||
"USER",
|
"USER",
|
||||||
@@ -570,8 +601,8 @@ static CURLcode pop3_perform_authenticate(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the supported authentication mechanism by decreasing order of
|
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||||
security */
|
security, as well as the initial response where appropriate */
|
||||||
if(pop3c->authtypes & POP3_TYPE_SASL) {
|
if(pop3c->authtypes & POP3_TYPE_SASL) {
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
|
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
|
||||||
@@ -834,20 +865,17 @@ static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn,
|
|||||||
/* Create the authorisation message */
|
/* Create the authorisation message */
|
||||||
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
|
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
|
||||||
&plainauth, &len);
|
&plainauth, &len);
|
||||||
|
if(!result && plainauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_FINAL);
|
||||||
if(plainauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, POP3_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(plainauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(plainauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,20 +899,17 @@ static CURLcode pop3_state_auth_login_resp(struct connectdata *conn,
|
|||||||
/* Create the user message */
|
/* Create the user message */
|
||||||
result = Curl_sasl_create_login_message(data, conn->user,
|
result = Curl_sasl_create_login_message(data, conn->user,
|
||||||
&authuser, &len);
|
&authuser, &len);
|
||||||
|
if(!result && authuser) {
|
||||||
|
/* Send the user */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authuser);
|
||||||
|
|
||||||
/* Send the user */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_LOGIN_PASSWD);
|
||||||
if(authuser) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authuser);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, POP3_AUTH_LOGIN_PASSWD);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authuser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authuser);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,20 +933,17 @@ static CURLcode pop3_state_auth_login_password_resp(struct connectdata *conn,
|
|||||||
/* Create the password message */
|
/* Create the password message */
|
||||||
result = Curl_sasl_create_login_message(data, conn->passwd,
|
result = Curl_sasl_create_login_message(data, conn->passwd,
|
||||||
&authpasswd, &len);
|
&authpasswd, &len);
|
||||||
|
if(!result && authpasswd) {
|
||||||
|
/* Send the password */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authpasswd);
|
||||||
|
|
||||||
/* Send the password */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_FINAL);
|
||||||
if(authpasswd) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authpasswd);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, POP3_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authpasswd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authpasswd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,9 +955,10 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg = NULL;
|
||||||
size_t len = 0;
|
char *chlg64 = NULL;
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -944,38 +967,34 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
pop3_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Terminate the challenge */
|
/* Decode the challenge message */
|
||||||
if(*chlg64 != '=') {
|
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
|
||||||
for(len = strlen(chlg64); len--;)
|
if(result) {
|
||||||
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
|
/* Send the cancellation */
|
||||||
chlg64[len] != '\t')
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
|
||||||
break;
|
|
||||||
|
|
||||||
if(++len) {
|
if(!result)
|
||||||
chlg64[len] = '\0';
|
state(conn, POP3_AUTH_CANCEL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* Create the response message */
|
/* Create the response message */
|
||||||
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
|
||||||
conn->passwd, &rplyb64, &len);
|
conn->passwd, &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
/* Send the response */
|
/* Send the response */
|
||||||
if(!result) {
|
|
||||||
if(rplyb64) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, POP3_AUTH_FINAL);
|
state(conn, POP3_AUTH_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,9 +1005,13 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg64 = NULL;
|
||||||
size_t len = 0;
|
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
char nonce[64];
|
||||||
|
char realm[128];
|
||||||
|
char algorithm[64];
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -997,27 +1020,36 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
pop3_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Create the response message */
|
/* Decode the challange message */
|
||||||
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||||
conn->passwd, "pop",
|
realm, sizeof(realm),
|
||||||
&rplyb64, &len);
|
algorithm, sizeof(algorithm));
|
||||||
|
if(result || strcmp(algorithm, "md5-sess") != 0) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
|
||||||
|
|
||||||
/* Send the response */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_CANCEL);
|
||||||
if(rplyb64) {
|
}
|
||||||
|
else {
|
||||||
|
/* Create the response message */
|
||||||
|
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
|
||||||
|
conn->user, conn->passwd,
|
||||||
|
"pop", &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
|
/* Send the response */
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, POP3_AUTH_DIGESTMD5_RESP);
|
state(conn, POP3_AUTH_DIGESTMD5_RESP);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,20 +1101,17 @@ static CURLcode pop3_state_auth_ntlm_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
||||||
&conn->ntlm,
|
&conn->ntlm,
|
||||||
&type1msg, &len);
|
&type1msg, &len);
|
||||||
|
if(!result && type1msg) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type1msg);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_NTLM_TYPE2MSG);
|
||||||
if(type1msg) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type1msg);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, POP3_AUTH_NTLM_TYPE2MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(type1msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type1msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1093,8 +1122,9 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
size_t len = 0;
|
char *type2msg = NULL;
|
||||||
char *type3msg = NULL;
|
char *type3msg = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -1103,26 +1133,35 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Create the type-3 message */
|
/* Get the type-2 message */
|
||||||
result = Curl_sasl_create_ntlm_type3_message(data,
|
pop3_get_message(data->state.buffer, &type2msg);
|
||||||
data->state.buffer + 2,
|
|
||||||
conn->user, conn->passwd,
|
|
||||||
&conn->ntlm,
|
|
||||||
&type3msg, &len);
|
|
||||||
|
|
||||||
/* Send the message */
|
/* Decode the type-2 message */
|
||||||
if(!result) {
|
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
|
||||||
if(type3msg) {
|
if(result) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
state(conn, POP3_AUTH_CANCEL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Create the type-3 message */
|
||||||
|
result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
|
||||||
|
conn->passwd, &conn->ntlm,
|
||||||
|
&type3msg, &len);
|
||||||
|
if(!result && type3msg) {
|
||||||
|
/* Send the message */
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type3msg);
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type3msg);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, POP3_AUTH_FINAL);
|
state(conn, POP3_AUTH_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(type3msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type3msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1147,24 +1186,36 @@ static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
||||||
conn->xoauth2_bearer,
|
conn->xoauth2_bearer,
|
||||||
&xoauth, &len);
|
&xoauth, &len);
|
||||||
|
if(!result && xoauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", xoauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, POP3_AUTH_FINAL);
|
||||||
if(xoauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", xoauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, POP3_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(xoauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(xoauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For final responses to the AUTH sequence */
|
/* For AUTH cancellation responses */
|
||||||
|
static CURLcode pop3_state_auth_cancel_resp(struct connectdata *conn,
|
||||||
|
int pop3code,
|
||||||
|
pop3state instate)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
(void)pop3code;
|
||||||
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
|
failf(data, "Authentication cancelled");
|
||||||
|
|
||||||
|
return CURLE_LOGIN_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For final responses in the AUTH sequence */
|
||||||
static CURLcode pop3_state_auth_final_resp(struct connectdata *conn,
|
static CURLcode pop3_state_auth_final_resp(struct connectdata *conn,
|
||||||
int pop3code,
|
int pop3code,
|
||||||
pop3state instate)
|
pop3state instate)
|
||||||
@@ -1386,6 +1437,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
|||||||
result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
|
result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case POP3_AUTH_CANCEL:
|
||||||
|
result = pop3_state_auth_cancel_resp(conn, pop3code, pop3c->state);
|
||||||
|
break;
|
||||||
|
|
||||||
case POP3_AUTH_FINAL:
|
case POP3_AUTH_FINAL:
|
||||||
result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state);
|
result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state);
|
||||||
break;
|
break;
|
||||||
@@ -1570,12 +1625,12 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
|
|||||||
{
|
{
|
||||||
/* This is POP3 and no proxy */
|
/* This is POP3 and no proxy */
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
struct POP3 *pop3 = conn->data->req.protop;
|
||||||
|
|
||||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||||
|
|
||||||
if(conn->data->set.opt_no_body) {
|
if(conn->data->set.opt_no_body) {
|
||||||
/* Requested no body means no transfer */
|
/* Requested no body means no transfer */
|
||||||
struct POP3 *pop3 = conn->data->req.protop;
|
|
||||||
pop3->transfer = FTPTRANSFER_INFO;
|
pop3->transfer = FTPTRANSFER_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,8 +1689,7 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
|
|||||||
* Disconnect from an POP3 server. Cleanup protocol-specific per-connection
|
* Disconnect from an POP3 server. Cleanup protocol-specific per-connection
|
||||||
* resources. BLOCKING.
|
* resources. BLOCKING.
|
||||||
*/
|
*/
|
||||||
static CURLcode pop3_disconnect(struct connectdata *conn,
|
static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
|
||||||
bool dead_connection)
|
|
||||||
{
|
{
|
||||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||||
|
|
||||||
@@ -1645,7 +1699,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* The POP3 session may or may not have been allocated/setup at this
|
/* The POP3 session may or may not have been allocated/setup at this
|
||||||
point! */
|
point! */
|
||||||
if(!dead_connection && pop3c->pp.conn)
|
if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
|
||||||
if(!pop3_perform_quit(conn))
|
if(!pop3_perform_quit(conn))
|
||||||
(void)pop3_block_statemach(conn); /* ignore errors on QUIT */
|
(void)pop3_block_statemach(conn); /* ignore errors on QUIT */
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ typedef enum {
|
|||||||
POP3_AUTH_NTLM,
|
POP3_AUTH_NTLM,
|
||||||
POP3_AUTH_NTLM_TYPE2MSG,
|
POP3_AUTH_NTLM_TYPE2MSG,
|
||||||
POP3_AUTH_XOAUTH2,
|
POP3_AUTH_XOAUTH2,
|
||||||
|
POP3_AUTH_CANCEL,
|
||||||
POP3_AUTH_FINAL,
|
POP3_AUTH_FINAL,
|
||||||
POP3_APOP,
|
POP3_APOP,
|
||||||
POP3_USER,
|
POP3_USER,
|
||||||
@@ -92,7 +93,7 @@ extern const struct Curl_handler Curl_handler_pop3s;
|
|||||||
|
|
||||||
/* Authentication type values */
|
/* Authentication type values */
|
||||||
#define POP3_TYPE_NONE 0
|
#define POP3_TYPE_NONE 0
|
||||||
#define POP3_TYPE_ANY ~0
|
#define POP3_TYPE_ANY ~0U
|
||||||
|
|
||||||
/* This is the 5-bytes End-Of-Body marker for POP3 */
|
/* This is the 5-bytes End-Of-Body marker for POP3 */
|
||||||
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
|
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
|
||||||
|
|||||||
@@ -204,6 +204,12 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
|
|||||||
case CURL_SSLVERSION_SSLv3:
|
case CURL_SSLVERSION_SSLv3:
|
||||||
h->protocol = SSL_VERSION_3;
|
h->protocol = SSL_VERSION_3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
failf(data, "TLS minor version cannot be set");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
h->peerCert = NULL;
|
h->peerCert = NULL;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
typedef unsigned long u_int32_t;
|
typedef unsigned long u_int32_t;
|
||||||
|
|
||||||
|
|
||||||
/* System API wrapper prototypes and definitions to support ASCII parameters. */
|
/* System API wrapper prototypes & definitions to support ASCII parameters. */
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -42,7 +42,8 @@ typedef unsigned long u_int32_t;
|
|||||||
#include <qsoasync.h>
|
#include <qsoasync.h>
|
||||||
#include <gssapi.h>
|
#include <gssapi.h>
|
||||||
|
|
||||||
extern int Curl_getaddrinfo_a(const char * nodename, const char * servname,
|
extern int Curl_getaddrinfo_a(const char * nodename,
|
||||||
|
const char * servname,
|
||||||
const struct addrinfo * hints,
|
const struct addrinfo * hints,
|
||||||
struct addrinfo * * res);
|
struct addrinfo * * res);
|
||||||
#define getaddrinfo Curl_getaddrinfo_a
|
#define getaddrinfo Curl_getaddrinfo_a
|
||||||
@@ -66,7 +67,8 @@ extern int Curl_SSL_Init_a(SSLInit * init);
|
|||||||
#define SSL_Init Curl_SSL_Init_a
|
#define SSL_Init Curl_SSL_Init_a
|
||||||
|
|
||||||
|
|
||||||
extern char * Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp);
|
extern char * Curl_SSL_Strerror_a(int sslreturnvalue,
|
||||||
|
SSLErrorMsg * serrmsgp);
|
||||||
#define SSL_Strerror Curl_SSL_Strerror_a
|
#define SSL_Strerror Curl_SSL_Strerror_a
|
||||||
|
|
||||||
|
|
||||||
@@ -226,5 +228,12 @@ extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
#define sendto Curl_os400_sendto
|
#define sendto Curl_os400_sendto
|
||||||
#define recvfrom Curl_os400_recvfrom
|
#define recvfrom Curl_os400_recvfrom
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBZ
|
||||||
|
#define zlibVersion Curl_os400_zlibVersion
|
||||||
|
#define inflateInit_ Curl_os400_inflateInit_
|
||||||
|
#define inflateInit2_ Curl_os400_inflateInit2_
|
||||||
|
#define inflate Curl_os400_inflate
|
||||||
|
#define inflateEnd Curl_os400_inflateEnd
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* HEADER_CURL_SETUP_OS400_H */
|
#endif /* HEADER_CURL_SETUP_OS400_H */
|
||||||
|
|||||||
78
lib/sigpipe.h
Normal file
78
lib/sigpipe.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#ifndef HEADER_CURL_SIGPIPE_H
|
||||||
|
#define HEADER_CURL_SIGPIPE_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2013, 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 http://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
struct sigpipe_ignore {
|
||||||
|
struct sigaction old_pipe_act;
|
||||||
|
bool no_signal;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
|
||||||
|
* internals, and then sigpipe_restore() will restore the situation when we
|
||||||
|
* return from libcurl again.
|
||||||
|
*/
|
||||||
|
static void sigpipe_ignore(struct SessionHandle *data,
|
||||||
|
struct sigpipe_ignore *ig)
|
||||||
|
{
|
||||||
|
/* get a local copy of no_signal because the SessionHandle might not be
|
||||||
|
around when we restore */
|
||||||
|
ig->no_signal = data->set.no_signal;
|
||||||
|
if(!data->set.no_signal) {
|
||||||
|
struct sigaction action;
|
||||||
|
/* first, extract the existing situation */
|
||||||
|
memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
|
||||||
|
sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
|
||||||
|
action = ig->old_pipe_act;
|
||||||
|
/* ignore this signal */
|
||||||
|
action.sa_handler = SIG_IGN;
|
||||||
|
sigaction(SIGPIPE, &action, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigpipe_restore() puts back the outside world's opinion of signal handler
|
||||||
|
* and SIGPIPE handling. It MUST only be called after a corresponding
|
||||||
|
* sigpipe_ignore() was used.
|
||||||
|
*/
|
||||||
|
static void sigpipe_restore(struct sigpipe_ignore *ig)
|
||||||
|
{
|
||||||
|
if(!ig->no_signal)
|
||||||
|
/* restore the outside state */
|
||||||
|
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* for systems without sigaction */
|
||||||
|
#define sigpipe_ignore(x,y) Curl_nop_stmt
|
||||||
|
#define sigpipe_restore(x) Curl_nop_stmt
|
||||||
|
#define SIGPIPE_VARIABLE(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HEADER_CURL_SIGPIPE_H */
|
||||||
663
lib/smtp.c
663
lib/smtp.c
@@ -27,7 +27,8 @@
|
|||||||
* RFC4954 SMTP Authentication
|
* RFC4954 SMTP Authentication
|
||||||
* RFC5321 SMTP protocol
|
* RFC5321 SMTP protocol
|
||||||
* RFC6749 OAuth 2.0 Authorization Framework
|
* RFC6749 OAuth 2.0 Authorization Framework
|
||||||
* Draft SMTP URL Interface
|
* Draft SMTP URL Interface <draft-earhart-url-smtp-00.txt>
|
||||||
|
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
|
|||||||
static CURLcode smtp_setup_connection(struct connectdata *conn);
|
static CURLcode smtp_setup_connection(struct connectdata *conn);
|
||||||
static CURLcode smtp_parse_url_options(struct connectdata *conn);
|
static CURLcode smtp_parse_url_options(struct connectdata *conn);
|
||||||
static CURLcode smtp_parse_url_path(struct connectdata *conn);
|
static CURLcode smtp_parse_url_path(struct connectdata *conn);
|
||||||
|
static CURLcode smtp_parse_custom_request(struct connectdata *conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SMTP protocol handler.
|
* SMTP protocol handler.
|
||||||
@@ -218,7 +220,7 @@ static void smtp_to_smtps(struct connectdata *conn)
|
|||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* pop3_endofresp()
|
* smtp_endofresp()
|
||||||
*
|
*
|
||||||
* Checks for an ending SMTP status code at the start of the given string, but
|
* Checks for an ending SMTP status code at the start of the given string, but
|
||||||
* also detects various capabilities from the EHLO response including the
|
* also detects various capabilities from the EHLO response including the
|
||||||
@@ -229,80 +231,62 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
|
|||||||
{
|
{
|
||||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||||
bool result = FALSE;
|
bool result = FALSE;
|
||||||
size_t wordlen;
|
|
||||||
|
|
||||||
|
/* Nothing for us */
|
||||||
if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
|
if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
|
||||||
return FALSE; /* Nothing for us */
|
return FALSE;
|
||||||
|
|
||||||
/* Do we have a command response? */
|
/* Do we have a command response? This should be the response code followed
|
||||||
result = (line[3] == ' ') ? TRUE : FALSE;
|
by a space and optionally some text as per RFC-5321 and as outlined in
|
||||||
if(result)
|
Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
|
||||||
|
only send the response code instead as per Section 4.2. */
|
||||||
|
if(line[3] == ' ' || len == 5) {
|
||||||
|
result = TRUE;
|
||||||
*resp = curlx_sltosi(strtol(line, NULL, 10));
|
*resp = curlx_sltosi(strtol(line, NULL, 10));
|
||||||
|
|
||||||
/* Are we processing EHLO command data? */
|
/* Make sure real server never sends internal value */
|
||||||
if(smtpc->state == SMTP_EHLO && (!result || (result && *resp/100 == 2))) {
|
if(*resp == 1)
|
||||||
line += 4;
|
*resp = 0;
|
||||||
len -= 4;
|
}
|
||||||
|
/* Do we have a multiline (continuation) response? */
|
||||||
/* Does the server support the STARTTLS capability? */
|
else if(line[3] == '-' &&
|
||||||
if(len >= 8 && !memcmp(line, "STARTTLS", 8))
|
(smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) {
|
||||||
smtpc->tls_supported = TRUE;
|
result = TRUE;
|
||||||
|
*resp = 1; /* Internal response code */
|
||||||
/* Does the server support the SIZE capability? */
|
|
||||||
else if(len >= 4 && !memcmp(line, "SIZE", 4))
|
|
||||||
smtpc->size_supported = TRUE;
|
|
||||||
|
|
||||||
/* Do we have the authentication mechanism list? */
|
|
||||||
else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
|
|
||||||
line += 5;
|
|
||||||
len -= 5;
|
|
||||||
|
|
||||||
/* Loop through the data line */
|
|
||||||
for(;;) {
|
|
||||||
while(len &&
|
|
||||||
(*line == ' ' || *line == '\t' ||
|
|
||||||
*line == '\r' || *line == '\n')) {
|
|
||||||
|
|
||||||
line++;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Extract the word */
|
|
||||||
for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
|
|
||||||
line[wordlen] != '\t' && line[wordlen] != '\r' &&
|
|
||||||
line[wordlen] != '\n';)
|
|
||||||
wordlen++;
|
|
||||||
|
|
||||||
/* Test the word for a matching authentication mechanism */
|
|
||||||
if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
|
|
||||||
smtpc->authmechs |= SASL_MECH_LOGIN;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
|
|
||||||
smtpc->authmechs |= SASL_MECH_PLAIN;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
|
|
||||||
smtpc->authmechs |= SASL_MECH_CRAM_MD5;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
|
|
||||||
smtpc->authmechs |= SASL_MECH_DIGEST_MD5;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
|
|
||||||
smtpc->authmechs |= SASL_MECH_GSSAPI;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
|
|
||||||
smtpc->authmechs |= SASL_MECH_EXTERNAL;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
|
|
||||||
smtpc->authmechs |= SASL_MECH_NTLM;
|
|
||||||
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
|
|
||||||
smtpc->authmechs |= SASL_MECH_XOAUTH2;
|
|
||||||
|
|
||||||
line += wordlen;
|
|
||||||
len -= wordlen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* smtp_get_message()
|
||||||
|
*
|
||||||
|
* Gets the authentication message from the response buffer.
|
||||||
|
*/
|
||||||
|
static void smtp_get_message(char *buffer, char** outptr)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
char* message = NULL;
|
||||||
|
|
||||||
|
/* Find the start of the message */
|
||||||
|
for(message = buffer + 4; *message == ' ' || *message == '\t'; message++)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Find the end of the message */
|
||||||
|
for(len = strlen(message); len--;)
|
||||||
|
if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
|
||||||
|
message[len] != '\t')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Terminate the message */
|
||||||
|
if(++len) {
|
||||||
|
message[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
*outptr = message;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* state()
|
* state()
|
||||||
@@ -330,7 +314,9 @@ static void state(struct connectdata *conn, smtpstate newstate)
|
|||||||
"AUTH_NTLM",
|
"AUTH_NTLM",
|
||||||
"AUTH_NTLM_TYPE2MSG",
|
"AUTH_NTLM_TYPE2MSG",
|
||||||
"AUTH_XOAUTH2",
|
"AUTH_XOAUTH2",
|
||||||
|
"AUTH_CANCEL",
|
||||||
"AUTH_FINAL",
|
"AUTH_FINAL",
|
||||||
|
"COMMAND",
|
||||||
"MAIL",
|
"MAIL",
|
||||||
"RCPT",
|
"RCPT",
|
||||||
"DATA",
|
"DATA",
|
||||||
@@ -565,6 +551,35 @@ static CURLcode smtp_perform_authenticate(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* smtp_perform_command()
|
||||||
|
*
|
||||||
|
* Sends a SMTP based command.
|
||||||
|
*/
|
||||||
|
static CURLcode smtp_perform_command(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct SMTP *smtp = data->req.protop;
|
||||||
|
|
||||||
|
/* Send the command */
|
||||||
|
if(smtp->rcpt)
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
|
||||||
|
smtp->custom && smtp->custom[0] != '\0' ?
|
||||||
|
smtp->custom : "VRFY",
|
||||||
|
smtp->rcpt->data);
|
||||||
|
else
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
|
||||||
|
smtp->custom && smtp->custom[0] != '\0' ?
|
||||||
|
smtp->custom : "HELP");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
state(conn, SMTP_COMMAND);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* smtp_perform_mail()
|
* smtp_perform_mail()
|
||||||
@@ -656,16 +671,14 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
|
|||||||
struct SMTP *smtp = data->req.protop;
|
struct SMTP *smtp = data->req.protop;
|
||||||
|
|
||||||
/* Send the RCPT TO command */
|
/* Send the RCPT TO command */
|
||||||
if(smtp->rcpt) {
|
if(smtp->rcpt->data[0] == '<')
|
||||||
if(smtp->rcpt->data[0] == '<')
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
|
smtp->rcpt->data);
|
||||||
smtp->rcpt->data);
|
else
|
||||||
else
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
|
smtp->rcpt->data);
|
||||||
smtp->rcpt->data);
|
if(!result)
|
||||||
if(!result)
|
state(conn, SMTP_RCPT);
|
||||||
state(conn, SMTP_RCPT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -740,10 +753,13 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||||
|
const char *line = data->state.buffer;
|
||||||
|
size_t len = strlen(line);
|
||||||
|
size_t wordlen;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
if(smtpcode/100 != 2) {
|
if(smtpcode/100 != 2 && smtpcode != 1) {
|
||||||
if((data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) &&
|
if((data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) &&
|
||||||
!conn->bits.user_passwd)
|
!conn->bits.user_passwd)
|
||||||
result = smtp_perform_helo(conn);
|
result = smtp_perform_helo(conn);
|
||||||
@@ -752,21 +768,83 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
|
|||||||
result = CURLE_REMOTE_ACCESS_DENIED;
|
result = CURLE_REMOTE_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
else {
|
||||||
/* We don't have a SSL/TLS connection yet, but SSL is requested */
|
line += 4;
|
||||||
if(smtpc->tls_supported)
|
len -= 4;
|
||||||
/* Switch to TLS connection now */
|
|
||||||
result = smtp_perform_starttls(conn);
|
/* Does the server support the STARTTLS capability? */
|
||||||
else if(data->set.use_ssl == CURLUSESSL_TRY)
|
if(len >= 8 && !memcmp(line, "STARTTLS", 8))
|
||||||
/* Fallback and carry on with authentication */
|
smtpc->tls_supported = TRUE;
|
||||||
result = smtp_perform_authenticate(conn);
|
|
||||||
else {
|
/* Does the server support the SIZE capability? */
|
||||||
failf(data, "STARTTLS not supported.");
|
else if(len >= 4 && !memcmp(line, "SIZE", 4))
|
||||||
result = CURLE_USE_SSL_FAILED;
|
smtpc->size_supported = TRUE;
|
||||||
|
|
||||||
|
/* Do we have the authentication mechanism list? */
|
||||||
|
else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
|
||||||
|
line += 5;
|
||||||
|
len -= 5;
|
||||||
|
|
||||||
|
/* Loop through the data line */
|
||||||
|
for(;;) {
|
||||||
|
while(len &&
|
||||||
|
(*line == ' ' || *line == '\t' ||
|
||||||
|
*line == '\r' || *line == '\n')) {
|
||||||
|
|
||||||
|
line++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Extract the word */
|
||||||
|
for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
|
||||||
|
line[wordlen] != '\t' && line[wordlen] != '\r' &&
|
||||||
|
line[wordlen] != '\n';)
|
||||||
|
wordlen++;
|
||||||
|
|
||||||
|
/* Test the word for a matching authentication mechanism */
|
||||||
|
if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
|
||||||
|
smtpc->authmechs |= SASL_MECH_LOGIN;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
|
||||||
|
smtpc->authmechs |= SASL_MECH_PLAIN;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
|
||||||
|
smtpc->authmechs |= SASL_MECH_CRAM_MD5;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
|
||||||
|
smtpc->authmechs |= SASL_MECH_DIGEST_MD5;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
|
||||||
|
smtpc->authmechs |= SASL_MECH_GSSAPI;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
|
||||||
|
smtpc->authmechs |= SASL_MECH_EXTERNAL;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
|
||||||
|
smtpc->authmechs |= SASL_MECH_NTLM;
|
||||||
|
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
|
||||||
|
smtpc->authmechs |= SASL_MECH_XOAUTH2;
|
||||||
|
|
||||||
|
line += wordlen;
|
||||||
|
len -= wordlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(smtpcode != 1) {
|
||||||
|
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||||
|
/* We don't have a SSL/TLS connection yet, but SSL is requested */
|
||||||
|
if(smtpc->tls_supported)
|
||||||
|
/* Switch to TLS connection now */
|
||||||
|
result = smtp_perform_starttls(conn);
|
||||||
|
else if(data->set.use_ssl == CURLUSESSL_TRY)
|
||||||
|
/* Fallback and carry on with authentication */
|
||||||
|
result = smtp_perform_authenticate(conn);
|
||||||
|
else {
|
||||||
|
failf(data, "STARTTLS not supported.");
|
||||||
|
result = CURLE_USE_SSL_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = smtp_perform_authenticate(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
result = smtp_perform_authenticate(conn);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -811,20 +889,17 @@ static CURLcode smtp_state_auth_plain_resp(struct connectdata *conn,
|
|||||||
/* Create the authorisation message */
|
/* Create the authorisation message */
|
||||||
result = Curl_sasl_create_plain_message(conn->data, conn->user,
|
result = Curl_sasl_create_plain_message(conn->data, conn->user,
|
||||||
conn->passwd, &plainauth, &len);
|
conn->passwd, &plainauth, &len);
|
||||||
|
if(!result && plainauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_FINAL);
|
||||||
if(plainauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(plainauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(plainauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -848,20 +923,17 @@ static CURLcode smtp_state_auth_login_resp(struct connectdata *conn,
|
|||||||
/* Create the user message */
|
/* Create the user message */
|
||||||
result = Curl_sasl_create_login_message(conn->data, conn->user,
|
result = Curl_sasl_create_login_message(conn->data, conn->user,
|
||||||
&authuser, &len);
|
&authuser, &len);
|
||||||
|
if(!result && authuser) {
|
||||||
|
/* Send the user */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
|
||||||
|
|
||||||
/* Send the user */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_LOGIN_PASSWD);
|
||||||
if(authuser) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_AUTH_LOGIN_PASSWD);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authuser);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authuser);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,20 +957,17 @@ static CURLcode smtp_state_auth_login_password_resp(struct connectdata *conn,
|
|||||||
/* Create the password message */
|
/* Create the password message */
|
||||||
result = Curl_sasl_create_login_message(conn->data, conn->passwd,
|
result = Curl_sasl_create_login_message(conn->data, conn->passwd,
|
||||||
&authpasswd, &len);
|
&authpasswd, &len);
|
||||||
|
if(!result && authpasswd) {
|
||||||
|
/* Send the password */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
|
||||||
|
|
||||||
/* Send the password */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_FINAL);
|
||||||
if(authpasswd) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(authpasswd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(authpasswd);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,9 +979,10 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg = NULL;
|
||||||
size_t len = 0;
|
char *chlg64 = NULL;
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -921,38 +991,34 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 4; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
smtp_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Terminate the challenge */
|
/* Decode the challenge message */
|
||||||
if(*chlg64 != '=') {
|
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
|
||||||
for(len = strlen(chlg64); len--;)
|
if(result) {
|
||||||
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
|
/* Send the cancellation */
|
||||||
chlg64[len] != '\t')
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
|
||||||
break;
|
|
||||||
|
|
||||||
if(++len) {
|
if(!result)
|
||||||
chlg64[len] = '\0';
|
state(conn, SMTP_AUTH_CANCEL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
/* Create the response message */
|
/* Create the response message */
|
||||||
result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
|
||||||
conn->passwd, &rplyb64, &len);
|
conn->passwd, &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
/* Send the response */
|
/* Send the response */
|
||||||
if(!result) {
|
|
||||||
if(rplyb64) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH_FINAL);
|
state(conn, SMTP_AUTH_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,9 +1029,13 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
char *chlg64 = data->state.buffer;
|
char *chlg64 = NULL;
|
||||||
size_t len = 0;
|
|
||||||
char *rplyb64 = NULL;
|
char *rplyb64 = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
char nonce[64];
|
||||||
|
char realm[128];
|
||||||
|
char algorithm[64];
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
@@ -974,27 +1044,36 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn,
|
|||||||
return CURLE_LOGIN_DENIED;
|
return CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the challenge */
|
/* Get the challenge message */
|
||||||
for(chlg64 += 4; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
|
smtp_get_message(data->state.buffer, &chlg64);
|
||||||
;
|
|
||||||
|
|
||||||
/* Create the response message */
|
/* Decode the challange message */
|
||||||
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
|
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||||
conn->passwd, "smtp",
|
realm, sizeof(realm),
|
||||||
&rplyb64, &len);
|
algorithm, sizeof(algorithm));
|
||||||
|
if(result || strcmp(algorithm, "md5-sess") != 0) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
|
||||||
|
|
||||||
/* Send the response */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_CANCEL);
|
||||||
if(rplyb64) {
|
}
|
||||||
|
else {
|
||||||
|
/* Create the response message */
|
||||||
|
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
|
||||||
|
conn->user, conn->passwd,
|
||||||
|
"smtp", &rplyb64, &len);
|
||||||
|
if(!result && rplyb64) {
|
||||||
|
/* Send the response */
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH_DIGESTMD5_RESP);
|
state(conn, SMTP_AUTH_DIGESTMD5_RESP);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(rplyb64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(rplyb64);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1047,20 +1126,17 @@ static CURLcode smtp_state_auth_ntlm_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
|
||||||
&conn->ntlm,
|
&conn->ntlm,
|
||||||
&type1msg, &len);
|
&type1msg, &len);
|
||||||
|
if(!result && type1msg) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type1msg);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_NTLM_TYPE2MSG);
|
||||||
if(type1msg) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type1msg);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_AUTH_NTLM_TYPE2MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(type1msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type1msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1071,6 +1147,7 @@ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
char *type2msg = NULL;
|
||||||
char *type3msg = NULL;
|
char *type3msg = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
@@ -1081,26 +1158,35 @@ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
|||||||
result = CURLE_LOGIN_DENIED;
|
result = CURLE_LOGIN_DENIED;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Create the type-3 message */
|
/* Get the type-2 message */
|
||||||
result = Curl_sasl_create_ntlm_type3_message(data,
|
smtp_get_message(data->state.buffer, &type2msg);
|
||||||
data->state.buffer + 4,
|
|
||||||
conn->user, conn->passwd,
|
|
||||||
&conn->ntlm,
|
|
||||||
&type3msg, &len);
|
|
||||||
|
|
||||||
/* Send the message */
|
/* Decode the type-2 message */
|
||||||
if(!result) {
|
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
|
||||||
if(type3msg) {
|
if(result) {
|
||||||
|
/* Send the cancellation */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
state(conn, SMTP_AUTH_CANCEL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Create the type-3 message */
|
||||||
|
result = Curl_sasl_create_ntlm_type3_message(data, conn->user,
|
||||||
|
conn->passwd, &conn->ntlm,
|
||||||
|
&type3msg, &len);
|
||||||
|
if(!result && type3msg) {
|
||||||
|
/* Send the message */
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg);
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg);
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
state(conn, SMTP_AUTH_FINAL);
|
state(conn, SMTP_AUTH_FINAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(type3msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(type3msg);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1125,24 +1211,36 @@ static CURLcode smtp_state_auth_xoauth2_resp(struct connectdata *conn,
|
|||||||
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
|
||||||
conn->xoauth2_bearer,
|
conn->xoauth2_bearer,
|
||||||
&xoauth, &len);
|
&xoauth, &len);
|
||||||
|
if(!result && xoauth) {
|
||||||
|
/* Send the message */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", xoauth);
|
||||||
|
|
||||||
/* Send the message */
|
if(!result)
|
||||||
if(!result) {
|
state(conn, SMTP_AUTH_FINAL);
|
||||||
if(xoauth) {
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", xoauth);
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_AUTH_FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Curl_safefree(xoauth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Curl_safefree(xoauth);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For the final responses to the AUTH sequence */
|
/* For AUTH cancellation responses */
|
||||||
|
static CURLcode smtp_state_auth_cancel_resp(struct connectdata *conn,
|
||||||
|
int smtpcode,
|
||||||
|
smtpstate instate)
|
||||||
|
{
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
(void)smtpcode;
|
||||||
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
|
failf(data, "Authentication cancelled");
|
||||||
|
|
||||||
|
return CURLE_LOGIN_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For final responses in the AUTH sequence */
|
||||||
static CURLcode smtp_state_auth_final_resp(struct connectdata *conn,
|
static CURLcode smtp_state_auth_final_resp(struct connectdata *conn,
|
||||||
int smtpcode,
|
int smtpcode,
|
||||||
smtpstate instate)
|
smtpstate instate)
|
||||||
@@ -1163,26 +1261,68 @@ static CURLcode smtp_state_auth_final_resp(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For command responses */
|
||||||
|
static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
|
||||||
|
smtpstate instate)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct SMTP *smtp = data->req.protop;
|
||||||
|
char *line = data->state.buffer;
|
||||||
|
size_t len = strlen(line);
|
||||||
|
|
||||||
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
|
if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
|
||||||
|
(!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
|
||||||
|
failf(data, "Command failed: %d", smtpcode);
|
||||||
|
result = CURLE_RECV_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Temporarily add the LF character back and send as body to the client */
|
||||||
|
if(!data->set.opt_no_body) {
|
||||||
|
line[len] = '\n';
|
||||||
|
result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
|
||||||
|
line[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(smtpcode != 1) {
|
||||||
|
if(smtp->rcpt) {
|
||||||
|
smtp->rcpt = smtp->rcpt->next;
|
||||||
|
|
||||||
|
if(smtp->rcpt) {
|
||||||
|
/* Send the next command */
|
||||||
|
result = smtp_perform_command(conn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* End of DO phase */
|
||||||
|
state(conn, SMTP_STOP);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* End of DO phase */
|
||||||
|
state(conn, SMTP_STOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* For MAIL responses */
|
/* For MAIL responses */
|
||||||
static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
|
static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
|
||||||
smtpstate instate)
|
smtpstate instate)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct SMTP *smtp = data->req.protop;
|
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
if(smtpcode/100 != 2) {
|
if(smtpcode/100 != 2) {
|
||||||
failf(data, "MAIL failed: %d", smtpcode);
|
failf(data, "MAIL failed: %d", smtpcode);
|
||||||
result = CURLE_SEND_ERROR;
|
result = CURLE_SEND_ERROR;
|
||||||
state(conn, SMTP_STOP);
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
smtp->rcpt = data->set.mail_rcpt;
|
/* Start the RCPT TO command */
|
||||||
|
|
||||||
result = smtp_perform_rcpt_to(conn);
|
result = smtp_perform_rcpt_to(conn);
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1200,23 +1340,20 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
|
|||||||
if(smtpcode/100 != 2) {
|
if(smtpcode/100 != 2) {
|
||||||
failf(data, "RCPT failed: %d", smtpcode);
|
failf(data, "RCPT failed: %d", smtpcode);
|
||||||
result = CURLE_SEND_ERROR;
|
result = CURLE_SEND_ERROR;
|
||||||
state(conn, SMTP_STOP);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(smtp->rcpt) {
|
smtp->rcpt = smtp->rcpt->next;
|
||||||
smtp->rcpt = smtp->rcpt->next;
|
|
||||||
|
if(smtp->rcpt)
|
||||||
|
/* Send the next RCPT TO command */
|
||||||
result = smtp_perform_rcpt_to(conn);
|
result = smtp_perform_rcpt_to(conn);
|
||||||
|
else {
|
||||||
|
/* Send the DATA command */
|
||||||
|
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
|
||||||
|
|
||||||
/* If we failed or still are sending RCPT data then return */
|
if(!result)
|
||||||
if(result || smtp->rcpt)
|
state(conn, SMTP_DATA);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the DATA command */
|
|
||||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
state(conn, SMTP_DATA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1226,25 +1363,27 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
|
|||||||
static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
|
static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
|
||||||
smtpstate instate)
|
smtpstate instate)
|
||||||
{
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
(void)instate; /* no use for this yet */
|
(void)instate; /* no use for this yet */
|
||||||
|
|
||||||
if(smtpcode != 354) {
|
if(smtpcode != 354) {
|
||||||
|
failf(data, "DATA failed: %d", smtpcode);
|
||||||
|
result = CURLE_SEND_ERROR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Set the progress upload size */
|
||||||
|
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
||||||
|
|
||||||
|
/* SMTP upload */
|
||||||
|
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||||
|
|
||||||
|
/* End of DO phase */
|
||||||
state(conn, SMTP_STOP);
|
state(conn, SMTP_STOP);
|
||||||
return CURLE_SEND_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the progress upload size */
|
return result;
|
||||||
Curl_pgrsSetUploadSize(data, data->set.infilesize);
|
|
||||||
|
|
||||||
/* SMTP upload */
|
|
||||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
|
||||||
|
|
||||||
/* End of DO phase */
|
|
||||||
state(conn, SMTP_STOP);
|
|
||||||
|
|
||||||
return CURLE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For POSTDATA responses, which are received after the entire DATA
|
/* For POSTDATA responses, which are received after the entire DATA
|
||||||
@@ -1284,16 +1423,19 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
|
|||||||
if(pp->sendleft)
|
if(pp->sendleft)
|
||||||
return Curl_pp_flushsend(pp);
|
return Curl_pp_flushsend(pp);
|
||||||
|
|
||||||
/* Read the response from the server */
|
do {
|
||||||
result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
|
/* Read the response from the server */
|
||||||
if(result)
|
result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
|
||||||
return result;
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* Store the latest response for later retrieval */
|
/* Store the latest response for later retrieval if necessary */
|
||||||
if(smtpc->state != SMTP_QUIT)
|
if(smtpc->state != SMTP_QUIT && smtpcode != 1)
|
||||||
data->info.httpcode = smtpcode;
|
data->info.httpcode = smtpcode;
|
||||||
|
|
||||||
|
if(!smtpcode)
|
||||||
|
break;
|
||||||
|
|
||||||
if(smtpcode) {
|
|
||||||
/* We have now received a full SMTP server response */
|
/* We have now received a full SMTP server response */
|
||||||
switch(smtpc->state) {
|
switch(smtpc->state) {
|
||||||
case SMTP_SERVERGREET:
|
case SMTP_SERVERGREET:
|
||||||
@@ -1354,10 +1496,18 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
|
|||||||
result = smtp_state_auth_xoauth2_resp(conn, smtpcode, smtpc->state);
|
result = smtp_state_auth_xoauth2_resp(conn, smtpcode, smtpc->state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SMTP_AUTH_CANCEL:
|
||||||
|
result = smtp_state_auth_cancel_resp(conn, smtpcode, smtpc->state);
|
||||||
|
break;
|
||||||
|
|
||||||
case SMTP_AUTH_FINAL:
|
case SMTP_AUTH_FINAL:
|
||||||
result = smtp_state_auth_final_resp(conn, smtpcode, smtpc->state);
|
result = smtp_state_auth_final_resp(conn, smtpcode, smtpc->state);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SMTP_COMMAND:
|
||||||
|
result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
|
||||||
|
break;
|
||||||
|
|
||||||
case SMTP_MAIL:
|
case SMTP_MAIL:
|
||||||
result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
|
result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
|
||||||
break;
|
break;
|
||||||
@@ -1381,7 +1531,7 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
|
|||||||
state(conn, SMTP_STOP);
|
state(conn, SMTP_STOP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1521,7 +1671,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
|||||||
conn->bits.close = TRUE; /* marked for closure */
|
conn->bits.close = TRUE; /* marked for closure */
|
||||||
result = status; /* use the already set error code */
|
result = status; /* use the already set error code */
|
||||||
}
|
}
|
||||||
else if(!data->set.connect_only) {
|
else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) {
|
||||||
/* Calculate the EOB taking into account any terminating CRLF from the
|
/* Calculate the EOB taking into account any terminating CRLF from the
|
||||||
previous line of the email or the CRLF of the DATA command when there
|
previous line of the email or the CRLF of the DATA command when there
|
||||||
is "no mail data". RFC-5321, sect. 4.1.1.4. */
|
is "no mail data". RFC-5321, sect. 4.1.1.4. */
|
||||||
@@ -1560,6 +1710,9 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
|||||||
result = smtp_block_statemach(conn);
|
result = smtp_block_statemach(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cleanup our per-request based variables */
|
||||||
|
Curl_safefree(smtp->custom);
|
||||||
|
|
||||||
/* Clear the transfer mode for the next request */
|
/* Clear the transfer mode for the next request */
|
||||||
smtp->transfer = FTPTRANSFER_BODY;
|
smtp->transfer = FTPTRANSFER_BODY;
|
||||||
|
|
||||||
@@ -1570,31 +1723,41 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
|||||||
*
|
*
|
||||||
* smtp_perform()
|
* smtp_perform()
|
||||||
*
|
*
|
||||||
* This is the actual DO function for SMTP. Send a mail according to the
|
* This is the actual DO function for SMTP. Transfer a mail, send a command
|
||||||
* options previously setup.
|
* or get some data according to the options previously setup.
|
||||||
*/
|
*/
|
||||||
static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
|
static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
|
||||||
bool *dophase_done)
|
bool *dophase_done)
|
||||||
{
|
{
|
||||||
/* This is SMTP and no proxy */
|
/* This is SMTP and no proxy */
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct SMTP *smtp = data->req.protop;
|
||||||
|
|
||||||
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
DEBUGF(infof(conn->data, "DO phase starts\n"));
|
||||||
|
|
||||||
if(conn->data->set.opt_no_body) {
|
if(data->set.opt_no_body) {
|
||||||
/* Requested no body means no transfer */
|
/* Requested no body means no transfer */
|
||||||
struct SMTP *smtp = conn->data->req.protop;
|
|
||||||
smtp->transfer = FTPTRANSFER_INFO;
|
smtp->transfer = FTPTRANSFER_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dophase_done = FALSE; /* not done yet */
|
*dophase_done = FALSE; /* not done yet */
|
||||||
|
|
||||||
|
/* Store the first recipient (or NULL if not specified) */
|
||||||
|
smtp->rcpt = data->set.mail_rcpt;
|
||||||
|
|
||||||
/* Start the first command in the DO phase */
|
/* Start the first command in the DO phase */
|
||||||
result = smtp_perform_mail(conn);
|
if(data->set.upload && data->set.mail_rcpt)
|
||||||
|
/* MAIL transfer */
|
||||||
|
result = smtp_perform_mail(conn);
|
||||||
|
else
|
||||||
|
/* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
|
||||||
|
result = smtp_perform_command(conn);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* run the state-machine */
|
/* Run the state-machine */
|
||||||
result = smtp_multi_statemach(conn, dophase_done);
|
result = smtp_multi_statemach(conn, dophase_done);
|
||||||
|
|
||||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||||
@@ -1620,6 +1783,11 @@ static CURLcode smtp_do(struct connectdata *conn, bool *done)
|
|||||||
|
|
||||||
*done = FALSE; /* default to false */
|
*done = FALSE; /* default to false */
|
||||||
|
|
||||||
|
/* Parse the custom request */
|
||||||
|
result = smtp_parse_custom_request(conn);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
result = smtp_regular_transfer(conn, done);
|
result = smtp_regular_transfer(conn, done);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1632,8 +1800,7 @@ static CURLcode smtp_do(struct connectdata *conn, bool *done)
|
|||||||
* Disconnect from an SMTP server. Cleanup protocol-specific per-connection
|
* Disconnect from an SMTP server. Cleanup protocol-specific per-connection
|
||||||
* resources. BLOCKING.
|
* resources. BLOCKING.
|
||||||
*/
|
*/
|
||||||
static CURLcode smtp_disconnect(struct connectdata *conn,
|
static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||||
bool dead_connection)
|
|
||||||
{
|
{
|
||||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||||
|
|
||||||
@@ -1643,7 +1810,7 @@ static CURLcode smtp_disconnect(struct connectdata *conn,
|
|||||||
|
|
||||||
/* The SMTP session may or may not have been allocated/setup at this
|
/* The SMTP session may or may not have been allocated/setup at this
|
||||||
point! */
|
point! */
|
||||||
if(!dead_connection && smtpc->pp.conn)
|
if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
|
||||||
if(!smtp_perform_quit(conn))
|
if(!smtp_perform_quit(conn))
|
||||||
(void)smtp_block_statemach(conn); /* ignore errors on QUIT */
|
(void)smtp_block_statemach(conn); /* ignore errors on QUIT */
|
||||||
|
|
||||||
@@ -1836,6 +2003,26 @@ static CURLcode smtp_parse_url_path(struct connectdata *conn)
|
|||||||
return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
|
return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* smtp_parse_custom_request()
|
||||||
|
*
|
||||||
|
* Parse the custom request.
|
||||||
|
*/
|
||||||
|
static CURLcode smtp_parse_custom_request(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
struct SessionHandle *data = conn->data;
|
||||||
|
struct SMTP *smtp = data->req.protop;
|
||||||
|
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
|
||||||
|
|
||||||
|
/* URL decode the custom request */
|
||||||
|
if(custom)
|
||||||
|
result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
|
||||||
{
|
{
|
||||||
/* When sending a SMTP payload we must detect CRLF. sequences making sure
|
/* When sending a SMTP payload we must detect CRLF. sequences making sure
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ typedef enum {
|
|||||||
SMTP_AUTH_NTLM,
|
SMTP_AUTH_NTLM,
|
||||||
SMTP_AUTH_NTLM_TYPE2MSG,
|
SMTP_AUTH_NTLM_TYPE2MSG,
|
||||||
SMTP_AUTH_XOAUTH2,
|
SMTP_AUTH_XOAUTH2,
|
||||||
|
SMTP_AUTH_CANCEL,
|
||||||
SMTP_AUTH_FINAL,
|
SMTP_AUTH_FINAL,
|
||||||
|
SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */
|
||||||
SMTP_MAIL, /* MAIL FROM */
|
SMTP_MAIL, /* MAIL FROM */
|
||||||
SMTP_RCPT, /* RCPT TO */
|
SMTP_RCPT, /* RCPT TO */
|
||||||
SMTP_DATA,
|
SMTP_DATA,
|
||||||
@@ -60,6 +62,7 @@ typedef enum {
|
|||||||
used. */
|
used. */
|
||||||
struct SMTP {
|
struct SMTP {
|
||||||
curl_pp_transfer transfer;
|
curl_pp_transfer transfer;
|
||||||
|
char *custom; /* Custom Request */
|
||||||
struct curl_slist *rcpt; /* Recipient list */
|
struct curl_slist *rcpt; /* Recipient list */
|
||||||
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
size_t eob; /* Number of bytes of the EOB (End Of Body) that
|
||||||
have been received so far */
|
have been received so far */
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
|||||||
|
|
||||||
curlx_nonblock(sock, FALSE);
|
curlx_nonblock(sock, FALSE);
|
||||||
|
|
||||||
|
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compose socks4 request
|
* Compose socks4 request
|
||||||
*
|
*
|
||||||
@@ -182,6 +184,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
|||||||
else
|
else
|
||||||
hp = NULL; /* fail! */
|
hp = NULL; /* fail! */
|
||||||
|
|
||||||
|
infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
|
||||||
|
|
||||||
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
lib/ssh.c
12
lib/ssh.c
@@ -754,7 +754,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
|||||||
curlx_uztoui(strlen(conn->user)));
|
curlx_uztoui(strlen(conn->user)));
|
||||||
|
|
||||||
if(!sshc->authlist) {
|
if(!sshc->authlist) {
|
||||||
if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
|
if(libssh2_userauth_authenticated(sshc->ssh_session)) {
|
||||||
|
sshc->authed = TRUE;
|
||||||
|
infof(data, "SSH user accepted with no authentication\n");
|
||||||
|
state(conn, SSH_AUTH_DONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN) {
|
LIBSSH2_ERROR_EAGAIN) {
|
||||||
rc = LIBSSH2_ERROR_EAGAIN;
|
rc = LIBSSH2_ERROR_EAGAIN;
|
||||||
break;
|
break;
|
||||||
@@ -2719,6 +2725,10 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
|||||||
CURLcode result;
|
CURLcode result;
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
|
||||||
|
/* initialize per-handle data if not already */
|
||||||
|
if(!data->req.protop)
|
||||||
|
ssh_setup_connection(conn);
|
||||||
|
|
||||||
/* We default to persistent connections. We set this already in this connect
|
/* We default to persistent connections. We set this already in this connect
|
||||||
function to make the re-use checks properly be able to check this bit. */
|
function to make the re-use checks properly be able to check this bit. */
|
||||||
conn->bits.close = FALSE;
|
conn->bits.close = FALSE;
|
||||||
|
|||||||
17
lib/sslgen.c
17
lib/sslgen.c
@@ -611,6 +611,9 @@ int Curl_ssl_init_certinfo(struct SessionHandle * data,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'value' is NOT a zero terminated string
|
||||||
|
*/
|
||||||
CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
|
CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
|
||||||
int certnum,
|
int certnum,
|
||||||
const char *label,
|
const char *label,
|
||||||
@@ -621,12 +624,22 @@ CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
|
|||||||
char * output;
|
char * output;
|
||||||
struct curl_slist * nl;
|
struct curl_slist * nl;
|
||||||
CURLcode res = CURLE_OK;
|
CURLcode res = CURLE_OK;
|
||||||
|
size_t labellen = strlen(label);
|
||||||
|
size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
|
||||||
|
|
||||||
/* Add an information record for a particular certificate. */
|
output = malloc(outlen);
|
||||||
output = curl_maprintf("%s:%.*s", label, valuelen, value);
|
|
||||||
if(!output)
|
if(!output)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* sprintf the label and colon */
|
||||||
|
snprintf(output, outlen, "%s:", label);
|
||||||
|
|
||||||
|
/* memcpy the value (it might not be zero terminated) */
|
||||||
|
memcpy(&output[labellen+1], value, valuelen);
|
||||||
|
|
||||||
|
/* zero terminate the output */
|
||||||
|
output[labellen + 1 + valuelen] = 0;
|
||||||
|
|
||||||
nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
|
nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
|
||||||
if(!nl) {
|
if(!nl) {
|
||||||
free(output);
|
free(output);
|
||||||
|
|||||||
63
lib/ssluse.c
63
lib/ssluse.c
@@ -1431,19 +1431,12 @@ ossl_connect_step1(struct connectdata *conn,
|
|||||||
switch(data->set.ssl.version) {
|
switch(data->set.ssl.version) {
|
||||||
default:
|
default:
|
||||||
case CURL_SSLVERSION_DEFAULT:
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
#ifdef USE_TLS_SRP
|
|
||||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
|
||||||
infof(data, "Set version TLSv1 for SRP authorisation\n");
|
|
||||||
req_method = TLSv1_client_method() ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
/* we try to figure out version */
|
|
||||||
req_method = SSLv23_client_method();
|
|
||||||
use_sni(TRUE);
|
|
||||||
break;
|
|
||||||
case CURL_SSLVERSION_TLSv1:
|
case CURL_SSLVERSION_TLSv1:
|
||||||
req_method = TLSv1_client_method();
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
/* it will be handled later with the context options */
|
||||||
|
req_method = SSLv23_client_method();
|
||||||
use_sni(TRUE);
|
use_sni(TRUE);
|
||||||
break;
|
break;
|
||||||
case CURL_SSLVERSION_SSLv2:
|
case CURL_SSLVERSION_SSLv2:
|
||||||
@@ -1556,9 +1549,51 @@ ossl_connect_step1(struct connectdata *conn,
|
|||||||
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
|
switch(data->set.ssl.version) {
|
||||||
if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
|
case CURL_SSLVERSION_DEFAULT:
|
||||||
ctx_options |= SSL_OP_NO_SSLv2;
|
ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
#ifdef USE_TLS_SRP
|
||||||
|
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||||
|
infof(data, "Set version TLSv1.x for SRP authorisation\n");
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1:
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_0:
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1_1;
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
|
||||||
|
case CURL_SSLVERSION_TLSv1_1:
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1;
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1_2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURL_SSLVERSION_TLSv1_2:
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv2;
|
||||||
|
ctx_options |= SSL_OP_NO_SSLv3;
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1;
|
||||||
|
ctx_options |= SSL_OP_NO_TLSv1_1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
failf(data, "Unsupported SSL protocol version");
|
||||||
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
SSL_CTX_set_options(connssl->ctx, ctx_options);
|
SSL_CTX_set_options(connssl->ctx, ctx_options);
|
||||||
|
|
||||||
|
|||||||
@@ -1256,7 +1256,7 @@ static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
|
|||||||
if(*dophase_done) {
|
if(*dophase_done) {
|
||||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||||
}
|
}
|
||||||
else {
|
else if(!result) {
|
||||||
/* The multi code doesn't have this logic for the DOING state so we
|
/* The multi code doesn't have this logic for the DOING state so we
|
||||||
provide it for TFTP since it may do the entire transfer in this
|
provide it for TFTP since it may do the entire transfer in this
|
||||||
state. */
|
state. */
|
||||||
|
|||||||
@@ -1309,10 +1309,11 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
|||||||
Curl_pgrsStartNow(data);
|
Curl_pgrsStartNow(data);
|
||||||
|
|
||||||
if(data->set.timeout)
|
if(data->set.timeout)
|
||||||
Curl_expire(data, data->set.timeout);
|
Curl_expire(data, data->set.timeout + MULTI_TIMEOUT_INACCURACY_MS);
|
||||||
|
|
||||||
if(data->set.connecttimeout)
|
if(data->set.connecttimeout)
|
||||||
Curl_expire(data, data->set.connecttimeout);
|
Curl_expire(data, data->set.connecttimeout +
|
||||||
|
MULTI_TIMEOUT_INACCURACY_MS);
|
||||||
|
|
||||||
/* In case the handle is re-used and an authentication method was picked
|
/* In case the handle is re-used and an authentication method was picked
|
||||||
in the session we need to make sure we only use the one(s) we now
|
in the session we need to make sure we only use the one(s) we now
|
||||||
|
|||||||
152
lib/url.c
152
lib/url.c
@@ -299,13 +299,11 @@ static CURLcode setstropt(char **charp, char *s)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
|
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
|
||||||
char **optionsp)
|
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
char *user = NULL;
|
char *user = NULL;
|
||||||
char *passwd = NULL;
|
char *passwd = NULL;
|
||||||
char *options = NULL;
|
|
||||||
|
|
||||||
/* Parse the login details if specified. It not then we treat NULL as a hint
|
/* Parse the login details if specified. It not then we treat NULL as a hint
|
||||||
to clear the existing data */
|
to clear the existing data */
|
||||||
@@ -313,7 +311,7 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
|
|||||||
result = parse_login_details(option, strlen(option),
|
result = parse_login_details(option, strlen(option),
|
||||||
(userp ? &user : NULL),
|
(userp ? &user : NULL),
|
||||||
(passwdp ? &passwd : NULL),
|
(passwdp ? &passwd : NULL),
|
||||||
(optionsp ? &options : NULL));
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
@@ -335,12 +333,6 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
|
|||||||
Curl_safefree(*passwdp);
|
Curl_safefree(*passwdp);
|
||||||
*passwdp = passwd;
|
*passwdp = passwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the options part of option if required */
|
|
||||||
if(optionsp) {
|
|
||||||
Curl_safefree(*optionsp);
|
|
||||||
*optionsp = options;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1553,13 +1545,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
|
|
||||||
case CURLOPT_USERPWD:
|
case CURLOPT_USERPWD:
|
||||||
/*
|
/*
|
||||||
* user:password;options to use in the operation
|
* user:password to use in the operation
|
||||||
*/
|
*/
|
||||||
result = setstropt_userpwd(va_arg(param, char *),
|
result = setstropt_userpwd(va_arg(param, char *),
|
||||||
&data->set.str[STRING_USERNAME],
|
&data->set.str[STRING_USERNAME],
|
||||||
&data->set.str[STRING_PASSWORD],
|
&data->set.str[STRING_PASSWORD]);
|
||||||
&data->set.str[STRING_OPTIONS]);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_USERNAME:
|
case CURLOPT_USERNAME:
|
||||||
/*
|
/*
|
||||||
* authentication user name to use in the operation
|
* authentication user name to use in the operation
|
||||||
@@ -1567,6 +1559,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
result = setstropt(&data->set.str[STRING_USERNAME],
|
result = setstropt(&data->set.str[STRING_USERNAME],
|
||||||
va_arg(param, char *));
|
va_arg(param, char *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_PASSWORD:
|
case CURLOPT_PASSWORD:
|
||||||
/*
|
/*
|
||||||
* authentication password to use in the operation
|
* authentication password to use in the operation
|
||||||
@@ -1574,6 +1567,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
result = setstropt(&data->set.str[STRING_PASSWORD],
|
result = setstropt(&data->set.str[STRING_PASSWORD],
|
||||||
va_arg(param, char *));
|
va_arg(param, char *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CURLOPT_LOGIN_OPTIONS:
|
||||||
|
/*
|
||||||
|
* authentication options to use in the operation
|
||||||
|
*/
|
||||||
|
result = setstropt(&data->set.str[STRING_OPTIONS],
|
||||||
|
va_arg(param, char *));
|
||||||
|
break;
|
||||||
|
|
||||||
case CURLOPT_XOAUTH2_BEARER:
|
case CURLOPT_XOAUTH2_BEARER:
|
||||||
/*
|
/*
|
||||||
* XOAUTH2 bearer token to use in the operation
|
* XOAUTH2 bearer token to use in the operation
|
||||||
@@ -1581,6 +1583,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
result = setstropt(&data->set.str[STRING_BEARER],
|
result = setstropt(&data->set.str[STRING_BEARER],
|
||||||
va_arg(param, char *));
|
va_arg(param, char *));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CURLOPT_POSTQUOTE:
|
case CURLOPT_POSTQUOTE:
|
||||||
/*
|
/*
|
||||||
* List of RAW FTP commands to use after a transfer
|
* List of RAW FTP commands to use after a transfer
|
||||||
@@ -1650,7 +1653,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
*/
|
*/
|
||||||
result = setstropt_userpwd(va_arg(param, char *),
|
result = setstropt_userpwd(va_arg(param, char *),
|
||||||
&data->set.str[STRING_PROXYUSERNAME],
|
&data->set.str[STRING_PROXYUSERNAME],
|
||||||
&data->set.str[STRING_PROXYPASSWORD], NULL);
|
&data->set.str[STRING_PROXYPASSWORD]);
|
||||||
break;
|
break;
|
||||||
case CURLOPT_PROXYUSERNAME:
|
case CURLOPT_PROXYUSERNAME:
|
||||||
/*
|
/*
|
||||||
@@ -1926,7 +1929,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
data->set.ssl.fsslctxp = va_arg(param, void *);
|
data->set.ssl.fsslctxp = va_arg(param, void *);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT)
|
#if defined(USE_SSLEAY) || defined(USE_QSOSSL) || defined(USE_GSKIT) || \
|
||||||
|
defined(USE_NSS)
|
||||||
case CURLOPT_CERTINFO:
|
case CURLOPT_CERTINFO:
|
||||||
data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
|
data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
|
||||||
break;
|
break;
|
||||||
@@ -2502,6 +2506,10 @@ static void conn_free(struct connectdata *conn)
|
|||||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
|
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
|
||||||
Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
|
Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
|
||||||
|
if(CURL_SOCKET_BAD != conn->tempsock[0])
|
||||||
|
Curl_closesocket(conn, conn->tempsock[0]);
|
||||||
|
if(CURL_SOCKET_BAD != conn->tempsock[1])
|
||||||
|
Curl_closesocket(conn, conn->tempsock[1]);
|
||||||
|
|
||||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||||
Curl_ntlm_wb_cleanup(conn);
|
Curl_ntlm_wb_cleanup(conn);
|
||||||
@@ -3219,9 +3227,12 @@ static CURLcode ConnectionStore(struct SessionHandle *data,
|
|||||||
Note: this function's sub-functions call failf()
|
Note: this function's sub-functions call failf()
|
||||||
|
|
||||||
*/
|
*/
|
||||||
CURLcode Curl_connected_proxy(struct connectdata *conn)
|
CURLcode Curl_connected_proxy(struct connectdata *conn,
|
||||||
|
int sockindex)
|
||||||
{
|
{
|
||||||
if(!conn->bits.proxy)
|
if(!conn->bits.proxy || sockindex)
|
||||||
|
/* this magic only works for the primary socket as the secondary is used
|
||||||
|
for FTP only and it has FTP specific magic in ftp.c */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
switch(conn->proxytype) {
|
switch(conn->proxytype) {
|
||||||
@@ -3252,49 +3263,6 @@ CURLcode Curl_connected_proxy(struct connectdata *conn)
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode ConnectPlease(struct SessionHandle *data,
|
|
||||||
struct connectdata *conn,
|
|
||||||
bool *connected)
|
|
||||||
{
|
|
||||||
CURLcode result;
|
|
||||||
Curl_addrinfo *addr;
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
|
||||||
char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name;
|
|
||||||
|
|
||||||
infof(data, "About to connect() to %s%s port %ld (#%ld)\n",
|
|
||||||
conn->bits.proxy?"proxy ":"",
|
|
||||||
hostname, conn->port, conn->connection_id);
|
|
||||||
#else
|
|
||||||
(void)data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* Connect to server/proxy
|
|
||||||
*************************************************************/
|
|
||||||
result= Curl_connecthost(conn,
|
|
||||||
conn->dns_entry,
|
|
||||||
&conn->sock[FIRSTSOCKET],
|
|
||||||
&addr,
|
|
||||||
connected);
|
|
||||||
if(CURLE_OK == result) {
|
|
||||||
/* All is cool, we store the current information */
|
|
||||||
conn->ip_addr = addr;
|
|
||||||
|
|
||||||
if(*connected) {
|
|
||||||
result = Curl_connected_proxy(conn);
|
|
||||||
if(!result) {
|
|
||||||
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
|
|
||||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result)
|
|
||||||
*connected = FALSE; /* mark it as not connected */
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* verboseconnect() displays verbose information after a connect
|
* verboseconnect() displays verbose information after a connect
|
||||||
*/
|
*/
|
||||||
@@ -3561,6 +3529,8 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
|
|||||||
|
|
||||||
conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
|
conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
|
||||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
|
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
|
||||||
|
conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
|
||||||
|
conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
|
||||||
conn->connection_id = -1; /* no ID */
|
conn->connection_id = -1; /* no ID */
|
||||||
conn->port = -1; /* unknown at this point */
|
conn->port = -1; /* unknown at this point */
|
||||||
|
|
||||||
@@ -4857,7 +4827,7 @@ static CURLcode override_login(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set password so it's available in the connection.
|
* Set the login details so they're available in the connection
|
||||||
*/
|
*/
|
||||||
static CURLcode set_login(struct connectdata *conn,
|
static CURLcode set_login(struct connectdata *conn,
|
||||||
const char *user, const char *passwd,
|
const char *user, const char *passwd,
|
||||||
@@ -5598,53 +5568,19 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
|
|||||||
is later set again for the progress meter purpose */
|
is later set again for the progress meter purpose */
|
||||||
conn->now = Curl_tvnow();
|
conn->now = Curl_tvnow();
|
||||||
|
|
||||||
for(;;) {
|
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
|
||||||
/* loop for CURL_SERVER_CLOSED_CONNECTION */
|
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
|
||||||
|
result = Curl_connecthost(conn, conn->dns_entry);
|
||||||
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
|
if(result)
|
||||||
/* Try to connect only if not already connected */
|
return result;
|
||||||
bool connected = FALSE;
|
}
|
||||||
|
else {
|
||||||
result = ConnectPlease(data, conn, &connected);
|
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
|
||||||
|
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
|
||||||
if(result && !conn->ip_addr) {
|
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
|
||||||
/* transport connection failure not related with authentication */
|
*protocol_done = TRUE;
|
||||||
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
|
Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
|
||||||
return result;
|
Curl_verboseconnect(conn);
|
||||||
}
|
|
||||||
|
|
||||||
if(connected) {
|
|
||||||
result = Curl_protocol_connect(conn, protocol_done);
|
|
||||||
if(CURLE_OK == result)
|
|
||||||
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
|
|
||||||
|
|
||||||
/* if the connection was closed by the server while exchanging
|
|
||||||
authentication informations, retry with the new set
|
|
||||||
authentication information */
|
|
||||||
if(conn->bits.proxy_connect_closed) {
|
|
||||||
/* reset the error buffer */
|
|
||||||
if(data->set.errorbuffer)
|
|
||||||
data->set.errorbuffer[0] = '\0';
|
|
||||||
data->state.errorbuf = FALSE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CURLE_OK != result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
|
|
||||||
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
|
|
||||||
conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
|
|
||||||
*protocol_done = TRUE;
|
|
||||||
Curl_verboseconnect(conn);
|
|
||||||
Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
|
|
||||||
}
|
|
||||||
/* Stop the loop now */
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
|
conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ void Curl_close_connections(struct SessionHandle *data);
|
|||||||
#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
|
#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
|
||||||
service */
|
service */
|
||||||
|
|
||||||
CURLcode Curl_connected_proxy(struct connectdata *conn);
|
CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
|
||||||
|
|
||||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||||
#define Curl_verboseconnect(x) Curl_nop_stmt
|
#define Curl_verboseconnect(x) Curl_nop_stmt
|
||||||
|
|||||||
@@ -838,6 +838,7 @@ struct connectdata {
|
|||||||
within the DNS cache, so this pointer is only valid as long as the DNS
|
within the DNS cache, so this pointer is only valid as long as the DNS
|
||||||
cache entry remains locked. It gets unlocked in Curl_done() */
|
cache entry remains locked. It gets unlocked in Curl_done() */
|
||||||
Curl_addrinfo *ip_addr;
|
Curl_addrinfo *ip_addr;
|
||||||
|
Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
|
||||||
|
|
||||||
/* 'ip_addr_str' is the ip_addr data as a human readable string.
|
/* 'ip_addr_str' is the ip_addr data as a human readable string.
|
||||||
It remains available as long as the connection does, which is longer than
|
It remains available as long as the connection does, which is longer than
|
||||||
@@ -889,6 +890,7 @@ struct connectdata {
|
|||||||
struct timeval created; /* creation time */
|
struct timeval created; /* creation time */
|
||||||
curl_socket_t sock[2]; /* two sockets, the second is used for the data
|
curl_socket_t sock[2]; /* two sockets, the second is used for the data
|
||||||
transfer when doing FTP */
|
transfer when doing FTP */
|
||||||
|
curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
|
||||||
bool sock_accepted[2]; /* TRUE if the socket on this index was created with
|
bool sock_accepted[2]; /* TRUE if the socket on this index was created with
|
||||||
accept() */
|
accept() */
|
||||||
Curl_recv *recv[2];
|
Curl_recv *recv[2];
|
||||||
@@ -1635,6 +1637,8 @@ struct SessionHandle {
|
|||||||
other dynamic purposes */
|
other dynamic purposes */
|
||||||
struct WildcardData wildcard; /* wildcard download state info */
|
struct WildcardData wildcard; /* wildcard download state info */
|
||||||
struct PureInfo info; /* stats, reports and info data */
|
struct PureInfo info; /* stats, reports and info data */
|
||||||
|
struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
|
||||||
|
valid after a client has asked for it */
|
||||||
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
|
||||||
iconv_t outbound_cd; /* for translating to the network encoding */
|
iconv_t outbound_cd; /* for translating to the network encoding */
|
||||||
iconv_t inbound_cd; /* for translating from the network encoding */
|
iconv_t inbound_cd; /* for translating from the network encoding */
|
||||||
|
|||||||
112
lib/x509asn1.c
112
lib/x509asn1.c
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#if defined(USE_QSOSSL) || defined(USE_GSKIT)
|
#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
@@ -252,7 +252,7 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
|
|||||||
size_t inlength = end - from;
|
size_t inlength = end - from;
|
||||||
int size = 1;
|
int size = 1;
|
||||||
size_t outlength;
|
size_t outlength;
|
||||||
int chsize;
|
int charsize;
|
||||||
unsigned int wc;
|
unsigned int wc;
|
||||||
char * buf;
|
char * buf;
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
|
|||||||
default: /* case 1: */
|
default: /* case 1: */
|
||||||
wc = (wc << 8) | *(const unsigned char *) from++;
|
wc = (wc << 8) | *(const unsigned char *) from++;
|
||||||
}
|
}
|
||||||
chsize = 1;
|
charsize = 1;
|
||||||
if(wc >= 0x00000080) {
|
if(wc >= 0x00000080) {
|
||||||
if(wc >= 0x00000800) {
|
if(wc >= 0x00000800) {
|
||||||
if(wc >= 0x00010000) {
|
if(wc >= 0x00010000) {
|
||||||
@@ -315,18 +315,18 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
|
|||||||
}
|
}
|
||||||
buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
|
buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
|
||||||
wc = (wc >> 6) | 0x00010000;
|
wc = (wc >> 6) | 0x00010000;
|
||||||
chsize++;
|
charsize++;
|
||||||
}
|
}
|
||||||
buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
|
buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
|
||||||
wc = (wc >> 6) | 0x00000800;
|
wc = (wc >> 6) | 0x00000800;
|
||||||
chsize++;
|
charsize++;
|
||||||
}
|
}
|
||||||
buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
|
buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
|
||||||
wc = (wc >> 6) | 0x000000C0;
|
wc = (wc >> 6) | 0x000000C0;
|
||||||
chsize++;
|
charsize++;
|
||||||
}
|
}
|
||||||
buf[outlength] = (char) wc;
|
buf[outlength] = (char) wc;
|
||||||
outlength += chsize;
|
outlength += charsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[outlength] = '\0';
|
buf[outlength] = '\0';
|
||||||
@@ -803,7 +803,7 @@ static const char * dumpAlgo(curl_asn1Element * param,
|
|||||||
return OID2str(oid.beg, oid.end, TRUE);
|
return OID2str(oid.beg, oid.end, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_pubkey_field(struct SessionHandle *data, int certnum,
|
static void do_pubkey_field(struct SessionHandle * data, int certnum,
|
||||||
const char * label, curl_asn1Element * elem)
|
const char * label, curl_asn1Element * elem)
|
||||||
{
|
{
|
||||||
const char * output;
|
const char * output;
|
||||||
@@ -812,8 +812,10 @@ static void do_pubkey_field(struct SessionHandle *data, int certnum,
|
|||||||
|
|
||||||
output = Curl_ASN1tostr(elem, 0);
|
output = Curl_ASN1tostr(elem, 0);
|
||||||
if(output) {
|
if(output) {
|
||||||
Curl_ssl_push_certinfo(data, certnum, label, output);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " %s: %s\n", label, output);
|
Curl_ssl_push_certinfo(data, certnum, label, output);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " %s: %s\n", label, output);
|
||||||
free((char *) output);
|
free((char *) output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,11 +847,14 @@ static void do_pubkey(struct SessionHandle * data, int certnum,
|
|||||||
len--;
|
len--;
|
||||||
if(len > 32)
|
if(len > 32)
|
||||||
elem.beg = q; /* Strip leading zero bytes. */
|
elem.beg = q; /* Strip leading zero bytes. */
|
||||||
infof(data, " RSA Public Key (%lu bits)\n", len);
|
if(!certnum)
|
||||||
q = curl_maprintf("%lu", len);
|
infof(data, " RSA Public Key (%lu bits)\n", len);
|
||||||
if(q) {
|
if(data->set.ssl.certinfo) {
|
||||||
Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
|
q = curl_maprintf("%lu", len);
|
||||||
free((char *) q);
|
if(q) {
|
||||||
|
Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
|
||||||
|
free((char *) q);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Generate coefficients. */
|
/* Generate coefficients. */
|
||||||
do_pubkey_field(data, certnum, "rsa(n)", &elem);
|
do_pubkey_field(data, certnum, "rsa(n)", &elem);
|
||||||
@@ -896,6 +901,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
size_t i;
|
size_t i;
|
||||||
size_t j;
|
size_t j;
|
||||||
|
|
||||||
|
if(!data->set.ssl.certinfo)
|
||||||
|
if(certnum)
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
/* Prepare the certificate information for curl_easy_getinfo(). */
|
/* Prepare the certificate information for curl_easy_getinfo(). */
|
||||||
|
|
||||||
/* Extract the certificate ASN.1 elements. */
|
/* Extract the certificate ASN.1 elements. */
|
||||||
@@ -905,35 +914,44 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
ccp = Curl_DNtostr(&cert.subject);
|
ccp = Curl_DNtostr(&cert.subject);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, "%2d Subject: %s\n", certnum, ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, "%2d Subject: %s\n", certnum, ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Issuer. */
|
/* Issuer. */
|
||||||
ccp = Curl_DNtostr(&cert.issuer);
|
ccp = Curl_DNtostr(&cert.issuer);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Issuer: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Issuer: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Version (always fits in less than 32 bits). */
|
/* Version (always fits in less than 32 bits). */
|
||||||
version = 0;
|
version = 0;
|
||||||
for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
|
for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
|
||||||
version = (version << 8) | *(const unsigned char *) ccp;
|
version = (version << 8) | *(const unsigned char *) ccp;
|
||||||
ccp = curl_maprintf("%lx", version);
|
if(data->set.ssl.certinfo) {
|
||||||
if(!ccp)
|
ccp = curl_maprintf("%lx", version);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
if(!ccp)
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
|
return CURLE_OUT_OF_MEMORY;
|
||||||
free((char *) ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
|
||||||
infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
|
free((char *) ccp);
|
||||||
|
}
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
|
||||||
|
|
||||||
/* Serial number. */
|
/* Serial number. */
|
||||||
ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
|
ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Serial Number: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Serial Number: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Signature algorithm .*/
|
/* Signature algorithm .*/
|
||||||
@@ -941,24 +959,30 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
cert.signatureAlgorithm.end);
|
cert.signatureAlgorithm.end);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Signature Algorithm: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Signature Algorithm: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Start Date. */
|
/* Start Date. */
|
||||||
ccp = Curl_ASN1tostr(&cert.notBefore, 0);
|
ccp = Curl_ASN1tostr(&cert.notBefore, 0);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Start Date: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Start Date: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Expire Date. */
|
/* Expire Date. */
|
||||||
ccp = Curl_ASN1tostr(&cert.notAfter, 0);
|
ccp = Curl_ASN1tostr(&cert.notAfter, 0);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Expire Date: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Expire Date: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Public Key Algorithm. */
|
/* Public Key Algorithm. */
|
||||||
@@ -966,8 +990,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
cert.subjectPublicKeyAlgorithm.end);
|
cert.subjectPublicKeyAlgorithm.end);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Public Key Algorithm: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Public Key Algorithm: %s\n", ccp);
|
||||||
do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);
|
do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
@@ -977,8 +1003,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
ccp = Curl_ASN1tostr(&cert.signature, 0);
|
ccp = Curl_ASN1tostr(&cert.signature, 0);
|
||||||
if(!ccp)
|
if(!ccp)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, " Signature: %s\n", ccp);
|
Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, " Signature: %s\n", ccp);
|
||||||
free((char *) ccp);
|
free((char *) ccp);
|
||||||
|
|
||||||
/* Generate PEM certificate. */
|
/* Generate PEM certificate. */
|
||||||
@@ -987,7 +1015,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
&cp1, &cl1);
|
&cp1, &cl1);
|
||||||
if(cc != CURLE_OK)
|
if(cc != CURLE_OK)
|
||||||
return cc;
|
return cc;
|
||||||
/* Compute the number of charaters in final certificate string. Format is:
|
/* Compute the number of characters in final certificate string. Format is:
|
||||||
-----BEGIN CERTIFICATE-----\n
|
-----BEGIN CERTIFICATE-----\n
|
||||||
<max 64 base64 characters>\n
|
<max 64 base64 characters>\n
|
||||||
.
|
.
|
||||||
@@ -1008,8 +1036,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
|
i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
|
||||||
cp2[i] = '\0';
|
cp2[i] = '\0';
|
||||||
free(cp1);
|
free(cp1);
|
||||||
Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
|
if(data->set.ssl.certinfo)
|
||||||
infof(data, "%s\n", cp2);
|
Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
|
||||||
|
if(!certnum)
|
||||||
|
infof(data, "%s\n", cp2);
|
||||||
free(cp2);
|
free(cp2);
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@@ -1148,4 +1178,4 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
|
|||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
return CURLE_PEER_FAILED_VERIFICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_QSOSSL or USE_GSKIT */
|
#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#if defined(USE_QSOSSL) || defined(USE_GSKIT)
|
#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
|
|
||||||
@@ -125,5 +125,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
|
|||||||
CURLcode Curl_verifyhost(struct connectdata * conn,
|
CURLcode Curl_verifyhost(struct connectdata * conn,
|
||||||
const char * beg, const char * end);
|
const char * beg, const char * end);
|
||||||
|
|
||||||
#endif /* USE_QSOSSL or USE_GSKIT */
|
#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */
|
||||||
#endif /* HEADER_CURL_X509ASN1_H */
|
#endif /* HEADER_CURL_X509ASN1_H */
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ options:
|
|||||||
CURLOPT_ISSUERCERT
|
CURLOPT_ISSUERCERT
|
||||||
CURLOPT_KEYPASSWD
|
CURLOPT_KEYPASSWD
|
||||||
CURLOPT_KRBLEVEL
|
CURLOPT_KRBLEVEL
|
||||||
|
CURLOPT_LOGIN_OPTIONS
|
||||||
CURLOPT_MAIL_FROM
|
CURLOPT_MAIL_FROM
|
||||||
CURLOPT_MAIL_AUTH
|
CURLOPT_MAIL_AUTH
|
||||||
CURLOPT_NETRC_FILE
|
CURLOPT_NETRC_FILE
|
||||||
@@ -118,6 +119,7 @@ options:
|
|||||||
CURLOPT_USERAGENT
|
CURLOPT_USERAGENT
|
||||||
CURLOPT_USERNAME
|
CURLOPT_USERNAME
|
||||||
CURLOPT_USERPWD
|
CURLOPT_USERPWD
|
||||||
|
CURLOPT_XOAUTH2_BEARER
|
||||||
Else it is the same as for curl_easy_setopt().
|
Else it is the same as for curl_easy_setopt().
|
||||||
Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
|
Note that CURLOPT_ERRORBUFFER is not in the list above, since it gives the
|
||||||
address of an (empty) character buffer, not the address of a string.
|
address of an (empty) character buffer, not the address of a string.
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
|
|||||||
|
|
||||||
|
|
||||||
static iconv_t
|
static iconv_t
|
||||||
iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin, unsigned int cstr)
|
iconv_open_CCSID(unsigned int ccsidout, unsigned int ccsidin,
|
||||||
|
unsigned int cstr)
|
||||||
|
|
||||||
{
|
{
|
||||||
char fromcode[ICONV_ID_SIZE];
|
char fromcode[ICONV_ID_SIZE];
|
||||||
@@ -218,7 +219,7 @@ slist_convert(int dccsid, struct curl_slist * from, int sccsid)
|
|||||||
struct curl_slist * to = (struct curl_slist *) NULL;
|
struct curl_slist * to = (struct curl_slist *) NULL;
|
||||||
char * cp;
|
char * cp;
|
||||||
|
|
||||||
for (; from; from = from->next) {
|
for(; from; from = from->next) {
|
||||||
if(!(cp = dynconvert(dccsid, from->data, -1, sccsid))) {
|
if(!(cp = dynconvert(dccsid, from->data, -1, sccsid))) {
|
||||||
curl_slist_free_all(to);
|
curl_slist_free_all(to);
|
||||||
return (struct curl_slist *) NULL;
|
return (struct curl_slist *) NULL;
|
||||||
@@ -407,7 +408,7 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
|
|||||||
compiler seems to compare string values after substitution. */
|
compiler seems to compare string values after substitution. */
|
||||||
|
|
||||||
#if CURLVERSION_NOW != CURLVERSION_FOURTH
|
#if CURLVERSION_NOW != CURLVERSION_FOURTH
|
||||||
#error curl_version_info_data structure has changed: upgrade this procedure too.
|
#error curl_version_info_data structure has changed: upgrade this procedure.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If caller has been compiled with a new version, error. */
|
/* If caller has been compiled with a new version, error. */
|
||||||
@@ -426,7 +427,7 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
|
|||||||
nproto = 0;
|
nproto = 0;
|
||||||
|
|
||||||
if(p->protocols) {
|
if(p->protocols) {
|
||||||
while (p->protocols[nproto])
|
while(p->protocols[nproto])
|
||||||
n += strlen(p->protocols[nproto++]);
|
n += strlen(p->protocols[nproto++]);
|
||||||
|
|
||||||
n += nproto++;
|
n += nproto++;
|
||||||
@@ -478,7 +479,7 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
|
|||||||
cp += i;
|
cp += i;
|
||||||
n -= i;
|
n -= i;
|
||||||
|
|
||||||
for (i = 0; id->protocols[i]; i++)
|
for(i = 0; id->protocols[i]; i++)
|
||||||
if(convert_version_info_string(((const char * *) id->protocols) + i,
|
if(convert_version_info_string(((const char * *) id->protocols) + i,
|
||||||
&cp, &n, ccsid))
|
&cp, &n, ccsid))
|
||||||
return (curl_version_info_data *) NULL;
|
return (curl_version_info_data *) NULL;
|
||||||
@@ -593,7 +594,7 @@ curl_certinfo_free_all(struct curl_certinfo *info)
|
|||||||
/* Free all memory used by certificate info. */
|
/* Free all memory used by certificate info. */
|
||||||
if(info) {
|
if(info) {
|
||||||
if(info->certinfo) {
|
if(info->certinfo) {
|
||||||
for (i = 0; i < info->num_of_certs; i++)
|
for(i = 0; i < info->num_of_certs; i++)
|
||||||
curl_slist_free_all(info->certinfo[i]);
|
curl_slist_free_all(info->certinfo[i]);
|
||||||
free((char *) info->certinfo);
|
free((char *) info->certinfo);
|
||||||
}
|
}
|
||||||
@@ -647,19 +648,21 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
|
|||||||
|
|
||||||
case CURLINFO_SLIST:
|
case CURLINFO_SLIST:
|
||||||
ccsid = va_arg(arg, unsigned int);
|
ccsid = va_arg(arg, unsigned int);
|
||||||
if(info == CURLINFO_CERTINFO) {
|
switch (info) {
|
||||||
|
case CURLINFO_CERTINFO:
|
||||||
cipf = *(struct curl_certinfo * *) paramp;
|
cipf = *(struct curl_certinfo * *) paramp;
|
||||||
if(cipf) {
|
if(cipf) {
|
||||||
if(!(cipt = (struct curl_certinfo *) malloc(sizeof *cipt)))
|
if(!(cipt = (struct curl_certinfo *) malloc(sizeof *cipt)))
|
||||||
ret = CURLE_OUT_OF_MEMORY;
|
ret = CURLE_OUT_OF_MEMORY;
|
||||||
else {
|
else {
|
||||||
cipt->certinfo = (struct curl_slist * *) calloc(cipf->num_of_certs +
|
cipt->certinfo = (struct curl_slist * *)
|
||||||
1, sizeof(struct curl_slist *));
|
calloc(cipf->num_of_certs +
|
||||||
|
1, sizeof(struct curl_slist *));
|
||||||
if(!cipt->certinfo)
|
if(!cipt->certinfo)
|
||||||
ret = CURLE_OUT_OF_MEMORY;
|
ret = CURLE_OUT_OF_MEMORY;
|
||||||
else {
|
else {
|
||||||
cipt->num_of_certs = cipf->num_of_certs;
|
cipt->num_of_certs = cipf->num_of_certs;
|
||||||
for (i = 0; i < cipf->num_of_certs; i++)
|
for(i = 0; i < cipf->num_of_certs; i++)
|
||||||
if(cipf->certinfo[i])
|
if(cipf->certinfo[i])
|
||||||
if(!(cipt->certinfo[i] = slist_convert(ccsid,
|
if(!(cipt->certinfo[i] = slist_convert(ccsid,
|
||||||
cipf->certinfo[i],
|
cipf->certinfo[i],
|
||||||
@@ -677,12 +680,18 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
|
|||||||
|
|
||||||
*(struct curl_certinfo * *) paramp = cipt;
|
*(struct curl_certinfo * *) paramp = cipt;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
break;
|
||||||
|
|
||||||
|
case CURLINFO_TLS_SESSION:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
slp = (struct curl_slist * *) paramp;
|
slp = (struct curl_slist * *) paramp;
|
||||||
if(*slp)
|
if(*slp)
|
||||||
if(!(*slp = slist_convert(ccsid, *slp, ASCII_CCSID)))
|
if(!(*slp = slist_convert(ccsid, *slp, ASCII_CCSID)))
|
||||||
ret = CURLE_OUT_OF_MEMORY;
|
ret = CURLE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +724,7 @@ static void
|
|||||||
Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
|
Curl_formadd_release_local(struct curl_forms * forms, int nargs, int skip)
|
||||||
|
|
||||||
{
|
{
|
||||||
while (nargs--)
|
while(nargs--)
|
||||||
if(nargs != skip)
|
if(nargs != skip)
|
||||||
if(Curl_is_formadd_string(forms[nargs].option))
|
if(Curl_is_formadd_string(forms[nargs].option))
|
||||||
if(forms[nargs].value)
|
if(forms[nargs].value)
|
||||||
@@ -755,7 +764,7 @@ Curl_formadd_convert(struct curl_forms * forms,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cp2 = realloc(cp, l); /* Shorten buffer to the string size. */
|
cp2 = realloc(cp, l); /* Shorten buffer to the string size. */
|
||||||
|
|
||||||
if(cp2)
|
if(cp2)
|
||||||
cp = cp2;
|
cp = cp2;
|
||||||
@@ -763,7 +772,7 @@ Curl_formadd_convert(struct curl_forms * forms,
|
|||||||
forms[formx].value = cp;
|
forms[formx].value = cp;
|
||||||
|
|
||||||
if(lengthx >= 0)
|
if(lengthx >= 0)
|
||||||
forms[lengthx].value = (char *) l; /* Update to length after conversion. */
|
forms[lengthx].value = (char *) l; /* Update length after conversion. */
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -826,7 +835,7 @@ curl_formadd_ccsid(struct curl_httppost * * httppost,
|
|||||||
forms = (struct curl_forms *) NULL;
|
forms = (struct curl_forms *) NULL;
|
||||||
va_start(arg, last_post);
|
va_start(arg, last_post);
|
||||||
|
|
||||||
for (;;) {
|
for(;;) {
|
||||||
/* Make sure there is still room for an item in local array. */
|
/* Make sure there is still room for an item in local array. */
|
||||||
|
|
||||||
if(nargs >= lformlen) {
|
if(nargs >= lformlen) {
|
||||||
@@ -1111,11 +1120,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
|||||||
if(testwarn) {
|
if(testwarn) {
|
||||||
testwarn = 0;
|
testwarn = 0;
|
||||||
|
|
||||||
#ifdef USE_TLS_SRP
|
if((int) STRING_LAST != (int) STRING_BEARER + 1)
|
||||||
if((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
|
|
||||||
#else
|
|
||||||
if((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
|
|
||||||
#endif
|
|
||||||
curl_mfprintf(stderr,
|
curl_mfprintf(stderr,
|
||||||
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
|
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
|
||||||
}
|
}
|
||||||
@@ -1143,6 +1148,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
|||||||
case CURLOPT_ISSUERCERT:
|
case CURLOPT_ISSUERCERT:
|
||||||
case CURLOPT_KEYPASSWD:
|
case CURLOPT_KEYPASSWD:
|
||||||
case CURLOPT_KRBLEVEL:
|
case CURLOPT_KRBLEVEL:
|
||||||
|
case CURLOPT_LOGIN_OPTIONS:
|
||||||
case CURLOPT_MAIL_FROM:
|
case CURLOPT_MAIL_FROM:
|
||||||
case CURLOPT_MAIL_AUTH:
|
case CURLOPT_MAIL_AUTH:
|
||||||
case CURLOPT_NETRC_FILE:
|
case CURLOPT_NETRC_FILE:
|
||||||
@@ -1176,6 +1182,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
|||||||
case CURLOPT_USERAGENT:
|
case CURLOPT_USERAGENT:
|
||||||
case CURLOPT_USERNAME:
|
case CURLOPT_USERNAME:
|
||||||
case CURLOPT_USERPWD:
|
case CURLOPT_USERPWD:
|
||||||
|
case CURLOPT_XOAUTH2_BEARER:
|
||||||
s = va_arg(arg, char *);
|
s = va_arg(arg, char *);
|
||||||
ccsid = va_arg(arg, unsigned int);
|
ccsid = va_arg(arg, unsigned int);
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ CURL_EXTERN char * curl_easy_unescape_ccsid(CURL * handle, const char * string,
|
|||||||
int length, int * outlength,
|
int length, int * outlength,
|
||||||
unsigned int sccsid,
|
unsigned int sccsid,
|
||||||
unsigned int dccsid);
|
unsigned int dccsid);
|
||||||
CURL_EXTERN struct curl_slist * curl_slist_append_ccsid(struct curl_slist * lst,
|
CURL_EXTERN struct curl_slist * curl_slist_append_ccsid(struct curl_slist * l,
|
||||||
const char * data,
|
const char * data,
|
||||||
unsigned int ccsid);
|
unsigned int ccsid);
|
||||||
CURL_EXTERN time_t curl_getdate_ccsid(const char * p, const time_t * unused,
|
CURL_EXTERN time_t curl_getdate_ccsid(const char * p, const time_t * unused,
|
||||||
unsigned int ccsid);
|
unsigned int ccsid);
|
||||||
CURL_EXTERN curl_version_info_data * curl_version_info_ccsid(CURLversion stamp,
|
CURL_EXTERN curl_version_info_data * curl_version_info_ccsid(CURLversion stamp,
|
||||||
unsigned int csid);
|
unsigned int cid);
|
||||||
CURL_EXTERN const char * curl_easy_strerror_ccsid(CURLcode error,
|
CURL_EXTERN const char * curl_easy_strerror_ccsid(CURLcode error,
|
||||||
unsigned int ccsid);
|
unsigned int ccsid);
|
||||||
CURL_EXTERN const char * curl_share_strerror_ccsid(CURLSHcode error,
|
CURL_EXTERN const char * curl_share_strerror_ccsid(CURLSHcode error,
|
||||||
|
|||||||
@@ -115,6 +115,8 @@
|
|||||||
d c X'00004000'
|
d c X'00004000'
|
||||||
d CURL_VERSION_NTLM_WB...
|
d CURL_VERSION_NTLM_WB...
|
||||||
d c X'00008000'
|
d c X'00008000'
|
||||||
|
d CURL_VERSION_HTTP2...
|
||||||
|
d c X'00010000'
|
||||||
*
|
*
|
||||||
d HTTPPOST_FILENAME...
|
d HTTPPOST_FILENAME...
|
||||||
d c X'00000001'
|
d c X'00000001'
|
||||||
@@ -212,6 +214,8 @@
|
|||||||
d c 1
|
d c 1
|
||||||
d CURL_HTTP_VERSION_1_1...
|
d CURL_HTTP_VERSION_1_1...
|
||||||
d c 2
|
d c 2
|
||||||
|
d CURL_HTTP_VERSION_2_0...
|
||||||
|
d c 3
|
||||||
*
|
*
|
||||||
d CURL_NETRC_IGNORED...
|
d CURL_NETRC_IGNORED...
|
||||||
d c 0
|
d c 0
|
||||||
@@ -228,6 +232,12 @@
|
|||||||
d c 2
|
d c 2
|
||||||
d CURL_SSLVERSION_SSLv3...
|
d CURL_SSLVERSION_SSLv3...
|
||||||
d c 3
|
d c 3
|
||||||
|
d CURL_SSLVERSION_TLSv1_0...
|
||||||
|
d c 4
|
||||||
|
d CURL_SSLVERSION_TLSv1_1...
|
||||||
|
d c 5
|
||||||
|
d CURL_SSLVERSION_TLSv1_2...
|
||||||
|
d c 6
|
||||||
*
|
*
|
||||||
d CURL_TLSAUTH_NONE...
|
d CURL_TLSAUTH_NONE...
|
||||||
d c 0
|
d c 0
|
||||||
@@ -1162,6 +1172,16 @@
|
|||||||
d c 00218
|
d c 00218
|
||||||
d CURLOPT_XFERINFOFUNCTION...
|
d CURLOPT_XFERINFOFUNCTION...
|
||||||
d c 20219
|
d c 20219
|
||||||
|
d CURLOPT_XOAUTH2_BEARER...
|
||||||
|
d c 10220
|
||||||
|
d CURLOPT_DNS_INTERFACE...
|
||||||
|
d c 10221
|
||||||
|
d CURLOPT_DNS_LOCAL_IP4...
|
||||||
|
d c 10222
|
||||||
|
d CURLOPT_DNS_LOCAL_IP6...
|
||||||
|
d c 10223
|
||||||
|
d CURLOPT_LOGIN_OPTIONS...
|
||||||
|
d c 10224
|
||||||
*
|
*
|
||||||
/if not defined(CURL_NO_OLDIES)
|
/if not defined(CURL_NO_OLDIES)
|
||||||
d CURLOPT_SSLKEYPASSWD...
|
d CURLOPT_SSLKEYPASSWD...
|
||||||
@@ -1329,10 +1349,35 @@
|
|||||||
d c X'00100029'
|
d c X'00100029'
|
||||||
d CURLINFO_LOCAL_PORT... CURLINFO_LONG + 42
|
d CURLINFO_LOCAL_PORT... CURLINFO_LONG + 42
|
||||||
d c X'0020002A'
|
d c X'0020002A'
|
||||||
|
d CURLINFO_TLS_SESSION... CURLINFO_SLIST + 43
|
||||||
|
d c X'0040002B'
|
||||||
*
|
*
|
||||||
d CURLINFO_HTTP_CODE... Old ...RESPONSE_CODE
|
d CURLINFO_HTTP_CODE... Old ...RESPONSE_CODE
|
||||||
d c X'00200002'
|
d c X'00200002'
|
||||||
*
|
*
|
||||||
|
d curl_sslbackend...
|
||||||
|
d s 10i 0 based(######ptr######) Enum
|
||||||
|
d CURLSSLBACKEND_NONE...
|
||||||
|
d c 0
|
||||||
|
d CURLSSLBACKEND_OPENSSL...
|
||||||
|
d c 1
|
||||||
|
d CURLSSLBACKEND_GNUTLS...
|
||||||
|
d c 2
|
||||||
|
d CURLSSLBACKEND_NSS...
|
||||||
|
d c 3
|
||||||
|
d CURLSSLBACKEND_QSOSSL...
|
||||||
|
d c 4
|
||||||
|
d CURLSSLBACKEND_GSKIT...
|
||||||
|
d c 5
|
||||||
|
d CURLSSLBACKEND_POLARSSL...
|
||||||
|
d c 6
|
||||||
|
d CURLSSLBACKEND_CYASSL...
|
||||||
|
d c 7
|
||||||
|
d CURLSSLBACKEND_SCHANNEL...
|
||||||
|
d c 8
|
||||||
|
d CURLSSLBACKEND_DARWINSSL...
|
||||||
|
d c 9
|
||||||
|
*
|
||||||
d curl_closepolicy...
|
d curl_closepolicy...
|
||||||
d s 10i 0 based(######ptr######) Enum
|
d s 10i 0 based(######ptr######) Enum
|
||||||
d CURLCLOSEPOLICY_OLDEST...
|
d CURLCLOSEPOLICY_OLDEST...
|
||||||
@@ -1451,7 +1496,9 @@
|
|||||||
d c 5
|
d c 5
|
||||||
d CURLM_UNKNOWN_OPTION...
|
d CURLM_UNKNOWN_OPTION...
|
||||||
d c 6
|
d c 6
|
||||||
d CURLM_LAST c 7
|
d CURLM_ADDED_ALREADY...
|
||||||
|
d c 7
|
||||||
|
d CURLM_LAST c 8
|
||||||
*
|
*
|
||||||
d CURLMSG s 10i 0 based(######ptr######) Enum
|
d CURLMSG s 10i 0 based(######ptr######) Enum
|
||||||
d CURLMSG_NONE c 0
|
d CURLMSG_NONE c 0
|
||||||
@@ -1560,12 +1607,7 @@
|
|||||||
d addrlen 10u 0
|
d addrlen 10u 0
|
||||||
d addr 16 struct sockaddr
|
d addr 16 struct sockaddr
|
||||||
*
|
*
|
||||||
d curl_khkey ds based(######ptr######)
|
d curl_khtype s 10i 0 based(######ptr######) enum
|
||||||
d qualified
|
|
||||||
d key * const char *
|
|
||||||
d len 10u 0
|
|
||||||
d keytype 10i 0
|
|
||||||
*
|
|
||||||
d CURLKHTYPE_UNKNOWN...
|
d CURLKHTYPE_UNKNOWN...
|
||||||
d c 0
|
d c 0
|
||||||
d CURLKHTYPE_RSA1...
|
d CURLKHTYPE_RSA1...
|
||||||
@@ -1575,6 +1617,12 @@
|
|||||||
d CURLKHTYPE_DSS...
|
d CURLKHTYPE_DSS...
|
||||||
d c 3
|
d c 3
|
||||||
*
|
*
|
||||||
|
d curl_khkey ds based(######ptr######)
|
||||||
|
d qualified
|
||||||
|
d key * const char *
|
||||||
|
d len 10u 0
|
||||||
|
d keytype like(curl_khtype)
|
||||||
|
*
|
||||||
d curl_forms ds based(######ptr######)
|
d curl_forms ds based(######ptr######)
|
||||||
d qualified
|
d qualified
|
||||||
d option like(CURLformoption)
|
d option like(CURLformoption)
|
||||||
@@ -1622,6 +1670,12 @@
|
|||||||
d group * char *
|
d group * char *
|
||||||
d target * char *
|
d target * char *
|
||||||
*
|
*
|
||||||
|
d curl_tlssessioninfo...
|
||||||
|
d ds based(######ptr######)
|
||||||
|
d qualified
|
||||||
|
d backend like(curl_sslbackend)
|
||||||
|
d internals * void *
|
||||||
|
*
|
||||||
d curl_fileinfo ds based(######ptr######)
|
d curl_fileinfo ds based(######ptr######)
|
||||||
d qualified
|
d qualified
|
||||||
d filename * char *
|
d filename * char *
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
|
||||||
|
setenv()
|
||||||
|
|
||||||
|
{
|
||||||
|
# Define and export.
|
||||||
|
|
||||||
|
eval ${1}="${2}"
|
||||||
|
export ${1}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case "${SCRIPTDIR}" in
|
case "${SCRIPTDIR}" in
|
||||||
/*) ;;
|
/*) ;;
|
||||||
*) SCRIPTDIR="`pwd`/${SCRIPTDIR}"
|
*) SCRIPTDIR="`pwd`/${SCRIPTDIR}"
|
||||||
@@ -32,18 +42,23 @@ export SONAME
|
|||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
TARGETLIB='CURL' # Target OS/400 program library
|
setenv TARGETLIB 'CURL' # Target OS/400 program library.
|
||||||
STATBNDDIR='CURL_A' # Static binding directory.
|
setenv STATBNDDIR 'CURL_A' # Static binding directory.
|
||||||
DYNBNDDIR='CURL' # Dynamic binding directory.
|
setenv DYNBNDDIR 'CURL' # Dynamic binding directory.
|
||||||
SRVPGM="CURL.${SONAME}" # Service program.
|
setenv SRVPGM "CURL.${SONAME}" # Service program.
|
||||||
TGTCCSID='500' # Target CCSID of objects
|
setenv TGTCCSID '500' # Target CCSID of objects.
|
||||||
DEBUG='*ALL' # Debug level
|
setenv DEBUG '*ALL' # Debug level.
|
||||||
OPTIMIZE='10' # Optimisation level
|
setenv OPTIMIZE '10' # Optimisation level
|
||||||
OUTPUT='*NONE' # Compilation output option.
|
setenv OUTPUT '*NONE' # Compilation output option.
|
||||||
TGTRLS='V5R3M0' # Target OS release
|
setenv TGTRLS 'V5R3M0' # Target OS release.
|
||||||
|
setenv IFSDIR '/curl' # Installation IFS directory.
|
||||||
|
|
||||||
export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM TGTCCSID DEBUG OPTIMIZE OUTPUT
|
# Define ZLIB availability and locations.
|
||||||
export TGTRLS
|
|
||||||
|
setenv WITH_ZLIB 0 # Define to 1 to enable.
|
||||||
|
setenv ZLIB_INCLUDE '/zlib/include' # ZLIB include IFS directory.
|
||||||
|
setenv ZLIB_LIB 'ZLIB' # ZLIB library.
|
||||||
|
setenv ZLIB_BNDDIR 'ZLIB_A' # ZLIB binding directory.
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -133,14 +148,26 @@ make_module()
|
|||||||
CMD="${CMD} LOCALETYPE(*LOCALE)"
|
CMD="${CMD} LOCALETYPE(*LOCALE)"
|
||||||
CMD="${CMD} INCDIR('/qibm/proddata/qadrt/include'"
|
CMD="${CMD} INCDIR('/qibm/proddata/qadrt/include'"
|
||||||
CMD="${CMD} '${TOPDIR}/include/curl' '${TOPDIR}/include'"
|
CMD="${CMD} '${TOPDIR}/include/curl' '${TOPDIR}/include'"
|
||||||
CMD="${CMD} '${TOPDIR}/packages/OS400' ${INCLUDES})"
|
CMD="${CMD} '${TOPDIR}/packages/OS400'"
|
||||||
|
|
||||||
|
if [ "${WITH_ZLIB}" != "0" ]
|
||||||
|
then CMD="${CMD} '${ZLIB_INCLUDE}'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
CMD="${CMD} ${INCLUDES})"
|
||||||
CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})"
|
CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})"
|
||||||
CMD="${CMD} OUTPUT(${OUTPUT})"
|
CMD="${CMD} OUTPUT(${OUTPUT})"
|
||||||
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
|
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
|
||||||
CMD="${CMD} DBGVIEW(${DEBUG})"
|
CMD="${CMD} DBGVIEW(${DEBUG})"
|
||||||
|
|
||||||
if [ "${3}" ]
|
DEFINES="${3}"
|
||||||
then CMD="${CMD} DEFINE(${3})"
|
|
||||||
|
if [ "${WITH_ZLIB}" != "0" ]
|
||||||
|
then DEFINES="${DEFINES} HAVE_LIBZ HAVE_ZLIB_H"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${DEFINES}" ]
|
||||||
|
then CMD="${CMD} DEFINE(${DEFINES})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
system "${CMD}"
|
system "${CMD}"
|
||||||
@@ -154,11 +181,17 @@ make_module()
|
|||||||
db2_name()
|
db2_name()
|
||||||
|
|
||||||
{
|
{
|
||||||
basename "${1}" |
|
if [ "${2}" = 'nomangle' ]
|
||||||
tr 'a-z-' 'A-Z_' |
|
then basename "${1}" |
|
||||||
sed -e 's/\..*//' \
|
tr 'a-z-' 'A-Z_' |
|
||||||
-e 's/^CURL_*/C/' \
|
sed -e 's/\..*//' \
|
||||||
-e 's/^\(.\).*\(.........\)$/\1\2/'
|
-e 's/^\(.\).*\(.........\)$/\1\2/'
|
||||||
|
else basename "${1}" |
|
||||||
|
tr 'a-z-' 'A-Z_' |
|
||||||
|
sed -e 's/\..*//' \
|
||||||
|
-e 's/^CURL_*/C/' \
|
||||||
|
-e 's/^\(.\).*\(.........\)$/\1\2/'
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Installation of the include files in the OS/400 library.
|
# Installation of the header files in the OS/400 library.
|
||||||
#
|
#
|
||||||
|
|
||||||
SCRIPTDIR=`dirname "${0}"`
|
SCRIPTDIR=`dirname "${0}"`
|
||||||
@@ -8,16 +8,16 @@ SCRIPTDIR=`dirname "${0}"`
|
|||||||
cd "${TOPDIR}/include"
|
cd "${TOPDIR}/include"
|
||||||
|
|
||||||
|
|
||||||
# Produce the curlbuild.h include file if not yet in distribution (CVS).
|
# Produce the curlbuild.h header file if not yet in distribution (CVS).
|
||||||
|
|
||||||
if action_needed curl/curlbuild.h
|
if action_needed curl/curlbuild.h
|
||||||
then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
|
then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
|
||||||
then cp -p curl/curlbuild.h.dist curl/curlbuild.h
|
then cp -p curl/curlbuild.h.dist curl/curlbuild.h
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Create the OS/400 source program file for the include files.
|
# Create the OS/400 source program file for the header files.
|
||||||
|
|
||||||
SRCPF="${LIBIFSNAME}/H.FILE"
|
SRCPF="${LIBIFSNAME}/H.FILE"
|
||||||
|
|
||||||
@@ -28,16 +28,25 @@ then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)"
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Create the IFS directory for the header files.
|
||||||
|
|
||||||
|
IFSINCLUDE="${IFSDIR}/include/curl"
|
||||||
|
|
||||||
|
if action_needed "${IFSINCLUDE}"
|
||||||
|
then mkdir -p "${IFSINCLUDE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Enumeration values are used as va_arg tagfields, so they MUST be
|
# Enumeration values are used as va_arg tagfields, so they MUST be
|
||||||
# integers.
|
# integers.
|
||||||
|
|
||||||
copy_hfile()
|
copy_hfile()
|
||||||
|
|
||||||
{
|
{
|
||||||
destfile="${1}"
|
destfile="${1}"
|
||||||
srcfile="${2}"
|
srcfile="${2}"
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
sed -e '1i\
|
sed -e '1i\
|
||||||
#pragma enum(int)\
|
#pragma enum(int)\
|
||||||
' "${@}" -e '$a\
|
' "${@}" -e '$a\
|
||||||
@@ -48,23 +57,34 @@ copy_hfile()
|
|||||||
# Copy the header files.
|
# Copy the header files.
|
||||||
|
|
||||||
for HFILE in curl/*.h ${SCRIPTDIR}/ccsidcurl.h
|
for HFILE in curl/*.h ${SCRIPTDIR}/ccsidcurl.h
|
||||||
do DEST="${SRCPF}/`db2_name \"${HFILE}\"`.MBR"
|
do case "`basename \"${HFILE}\" .h`" in
|
||||||
|
stdcheaders|typecheck-gcc)
|
||||||
|
continue;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
DEST="${SRCPF}/`db2_name \"${HFILE}\" nomangle`.MBR"
|
||||||
|
|
||||||
if action_needed "${DEST}" "${HFILE}"
|
if action_needed "${DEST}" "${HFILE}"
|
||||||
then copy_hfile "${DEST}" "${HFILE}"
|
then copy_hfile "${DEST}" "${HFILE}"
|
||||||
|
IFSDEST="${IFSINCLUDE}/`basename \"${HFILE}\"`"
|
||||||
|
rm -f "${IFSDEST}"
|
||||||
|
ln -s "${DEST}" "${IFSDEST}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# Copy the ILE/RPG include file, setting-up version number.
|
# Copy the ILE/RPG header file, setting-up version number.
|
||||||
|
|
||||||
versioned_copy "${SCRIPTDIR}/curl.inc.in" "${SRCPF}/CURL.INC.MBR"
|
versioned_copy "${SCRIPTDIR}/curl.inc.in" "${SRCPF}/CURL.INC.MBR"
|
||||||
|
rm -f "${IFSINCLUDE}/curl.inc.rpgle"
|
||||||
|
ln -s "${SRCPF}/CURL.INC.MBR" "${IFSINCLUDE}/curl.inc.rpgle"
|
||||||
|
|
||||||
|
|
||||||
# Duplicate file H as CURL to support more include path forms.
|
# Duplicate file H as CURL to support more include path forms.
|
||||||
|
|
||||||
if action_needed "${LIBIFSNAME}/CURL.FILE"
|
if action_needed "${LIBIFSNAME}/CURL.FILE"
|
||||||
then :
|
then :
|
||||||
else system "DLTF FILE(${TARGETLIB}/CURL)"
|
else system "DLTF FILE(${TARGETLIB}/CURL)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CMD="CRTDUPOBJ OBJ(H) FROMLIB(${TARGETLIB}) OBJTYPE(*FILE) TOLIB(*FROMLIB)"
|
CMD="CRTDUPOBJ OBJ(H) FROMLIB(${TARGETLIB}) OBJTYPE(*FILE) TOLIB(*FROMLIB)"
|
||||||
|
|||||||
@@ -83,12 +83,12 @@ fi
|
|||||||
|
|
||||||
# Gather the list of symbols to export.
|
# Gather the list of symbols to export.
|
||||||
|
|
||||||
EXPORTS=`grep '^CURL_EXTERN[ ]' \
|
EXPORTS=`grep '^CURL_EXTERN[[:space:]]' \
|
||||||
"${TOPDIR}"/include/curl/*.h \
|
"${TOPDIR}"/include/curl/*.h \
|
||||||
"${SCRIPTDIR}/ccsidcurl.h" |
|
"${SCRIPTDIR}/ccsidcurl.h" |
|
||||||
sed -e 's/^.*CURL_EXTERN[ ]\(.*\)(.*$/\1/' \
|
sed -e 's/^.*CURL_EXTERN[[:space:]]\(.*\)(.*$/\1/' \
|
||||||
-e 's/[ ]*$//' \
|
-e 's/[[:space:]]*$//' \
|
||||||
-e 's/^.*[ ][ ]*//' \
|
-e 's/^.*[[:space:]][[:space:]]*//' \
|
||||||
-e 's/^\*//' \
|
-e 's/^\*//' \
|
||||||
-e 's/(\(.*\))/\1/'`
|
-e 's/(\(.*\))/\1/'`
|
||||||
|
|
||||||
@@ -121,7 +121,11 @@ if [ "${LINK}" ]
|
|||||||
then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})"
|
then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})"
|
||||||
CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)"
|
CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)"
|
||||||
CMD="${CMD} MODULE(${TARGETLIB}/OS400)"
|
CMD="${CMD} MODULE(${TARGETLIB}/OS400)"
|
||||||
CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR})"
|
CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR}"
|
||||||
|
if [ "${WITH_ZLIB}" != 0 ]
|
||||||
|
then CMD="${CMD} ${ZLIB_LIB}/${ZLIB_BNDDIR}"
|
||||||
|
fi
|
||||||
|
CMD="${CMD})"
|
||||||
CMD="${CMD} BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)"
|
CMD="${CMD} BNDSRVPGM(QADRTTS QGLDCLNT QGLDBRDR)"
|
||||||
CMD="${CMD} TEXT('curl API library')"
|
CMD="${CMD} TEXT('curl API library')"
|
||||||
CMD="${CMD} TGTRLS(${TGTRLS})"
|
CMD="${CMD} TGTRLS(${TGTRLS})"
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ eval "`sed -e ': begin' \
|
|||||||
-e 's/\\\\\\n/ /' \
|
-e 's/\\\\\\n/ /' \
|
||||||
-e 'b begin' \
|
-e 'b begin' \
|
||||||
-e '}' \
|
-e '}' \
|
||||||
-e '/^[A-Za-z_][A-Za-z0-9_]*[ ]*[=]/b keep' \
|
-e '/^[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[=]/b keep' \
|
||||||
-e 'd' \
|
-e 'd' \
|
||||||
-e ': keep' \
|
-e ': keep' \
|
||||||
-e 's/[ ]*=[ ]*/=/' \
|
-e 's/[[:space:]]*=[[:space:]]*/=/' \
|
||||||
-e 's/=\\(.*[^ ]\\)[ ]*$/=\\"\\1\\"/' \
|
-e 's/=\\(.*[^[:space:]]\\)[[:space:]]*$/=\\"\\1\\"/' \
|
||||||
-e 's/\\$(\\([^)]*\\))/${\\1}/g' \
|
-e 's/\\$(\\([^)]*\\))/${\\1}/g' \
|
||||||
< Makefile.inc`"
|
< Makefile.inc`"
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,10 @@
|
|||||||
#include <qadrt.h>
|
#include <qadrt.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_QSOSSL
|
#ifdef USE_QSOSSL
|
||||||
#include <qsossl.h>
|
#include <qsossl.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -97,11 +101,11 @@ thdbufdestroy(void * private)
|
|||||||
localkey_t i;
|
localkey_t i;
|
||||||
buffer_t * p;
|
buffer_t * p;
|
||||||
|
|
||||||
if (private) {
|
if(private) {
|
||||||
p = (buffer_t *) private;
|
p = (buffer_t *) private;
|
||||||
|
|
||||||
for (i = (localkey_t) 0; i < LK_LAST; i++) {
|
for(i = (localkey_t) 0; i < LK_LAST; i++) {
|
||||||
if (p->buf)
|
if(p->buf)
|
||||||
free(p->buf);
|
free(p->buf);
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
@@ -116,13 +120,13 @@ static void
|
|||||||
terminate(void)
|
terminate(void)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (Curl_thread_buffer == buffer_threaded) {
|
if(Curl_thread_buffer == buffer_threaded) {
|
||||||
locbufs = pthread_getspecific(thdkey);
|
locbufs = pthread_getspecific(thdkey);
|
||||||
pthread_setspecific(thdkey, (void *) NULL);
|
pthread_setspecific(thdkey, (void *) NULL);
|
||||||
pthread_key_delete(thdkey);
|
pthread_key_delete(thdkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Curl_thread_buffer != buffer_undef) {
|
if(Curl_thread_buffer != buffer_undef) {
|
||||||
thdbufdestroy((void *) locbufs);
|
thdbufdestroy((void *) locbufs);
|
||||||
locbufs = (buffer_t *) NULL;
|
locbufs = (buffer_t *) NULL;
|
||||||
}
|
}
|
||||||
@@ -140,31 +144,31 @@ get_buffer(buffer_t * buf, long size)
|
|||||||
/* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
|
/* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
|
||||||
Return the buffer address. */
|
Return the buffer address. */
|
||||||
|
|
||||||
if (size < 0)
|
if(size < 0)
|
||||||
return buf->buf;
|
return buf->buf;
|
||||||
|
|
||||||
if (!buf->buf) {
|
if(!buf->buf) {
|
||||||
if ((buf->buf = malloc(size)))
|
if((buf->buf = malloc(size)))
|
||||||
buf->size = size;
|
buf->size = size;
|
||||||
|
|
||||||
return buf->buf;
|
return buf->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((unsigned long) size <= buf->size) {
|
if((unsigned long) size <= buf->size) {
|
||||||
/* Shorten the buffer only if it frees a significant byte count. This
|
/* Shorten the buffer only if it frees a significant byte count. This
|
||||||
avoids some realloc() overhead. */
|
avoids some realloc() overhead. */
|
||||||
|
|
||||||
if (buf->size - size < MIN_BYTE_GAIN)
|
if(buf->size - size < MIN_BYTE_GAIN)
|
||||||
return buf->buf;
|
return buf->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize the buffer. */
|
/* Resize the buffer. */
|
||||||
|
|
||||||
if ((cp = realloc(buf->buf, size))) {
|
if((cp = realloc(buf->buf, size))) {
|
||||||
buf->buf = cp;
|
buf->buf = cp;
|
||||||
buf->size = size;
|
buf->size = size;
|
||||||
}
|
}
|
||||||
else if (size <= buf->size)
|
else if(size <= buf->size)
|
||||||
cp = buf->buf;
|
cp = buf->buf;
|
||||||
|
|
||||||
return cp;
|
return cp;
|
||||||
@@ -191,16 +195,16 @@ buffer_threaded(localkey_t key, long size)
|
|||||||
|
|
||||||
bufs = (buffer_t *) pthread_getspecific(thdkey);
|
bufs = (buffer_t *) pthread_getspecific(thdkey);
|
||||||
|
|
||||||
if (!bufs) {
|
if(!bufs) {
|
||||||
if (size < 0)
|
if(size < 0)
|
||||||
return (char *) NULL; /* No buffer yet. */
|
return (char *) NULL; /* No buffer yet. */
|
||||||
|
|
||||||
/* Allocate buffer descriptors for the current thread. */
|
/* Allocate buffer descriptors for the current thread. */
|
||||||
|
|
||||||
if (!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
|
if(!(bufs = calloc((size_t) LK_LAST, sizeof *bufs)))
|
||||||
return (char *) NULL;
|
return (char *) NULL;
|
||||||
|
|
||||||
if (pthread_setspecific(thdkey, (void *) bufs)) {
|
if(pthread_setspecific(thdkey, (void *) bufs)) {
|
||||||
free(bufs);
|
free(bufs);
|
||||||
return (char *) NULL;
|
return (char *) NULL;
|
||||||
}
|
}
|
||||||
@@ -222,11 +226,10 @@ buffer_undef(localkey_t key, long size)
|
|||||||
|
|
||||||
/* Determine if we can use pthread-specific data. */
|
/* Determine if we can use pthread-specific data. */
|
||||||
|
|
||||||
if (Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
|
if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
|
||||||
if (!pthread_key_create(&thdkey, thdbufdestroy))
|
if(!pthread_key_create(&thdkey, thdbufdestroy))
|
||||||
Curl_thread_buffer = buffer_threaded;
|
Curl_thread_buffer = buffer_threaded;
|
||||||
else if (!(locbufs = calloc((size_t) LK_LAST,
|
else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
|
||||||
sizeof *locbufs))) {
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
return (char *) NULL;
|
return (char *) NULL;
|
||||||
}
|
}
|
||||||
@@ -241,6 +244,28 @@ buffer_undef(localkey_t key, long size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
set_thread_string(localkey_t key, const char * s)
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char * cp;
|
||||||
|
|
||||||
|
if(!s)
|
||||||
|
return (char *) NULL;
|
||||||
|
|
||||||
|
i = strlen(s) + 1;
|
||||||
|
cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
|
||||||
|
|
||||||
|
if(cp) {
|
||||||
|
i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
|
||||||
|
cp[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
|
Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
|
||||||
char * nodename, curl_socklen_t nodenamelen,
|
char * nodename, curl_socklen_t nodenamelen,
|
||||||
@@ -256,13 +281,13 @@ Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
|
|||||||
enodename = (char *) NULL;
|
enodename = (char *) NULL;
|
||||||
eservname = (char *) NULL;
|
eservname = (char *) NULL;
|
||||||
|
|
||||||
if (nodename && nodenamelen)
|
if(nodename && nodenamelen)
|
||||||
if (!(enodename = malloc(nodenamelen)))
|
if(!(enodename = malloc(nodenamelen)))
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
|
|
||||||
if (servname && servnamelen)
|
if(servname && servnamelen)
|
||||||
if (!(eservname = malloc(servnamelen))) {
|
if(!(eservname = malloc(servnamelen))) {
|
||||||
if (enodename)
|
if(enodename)
|
||||||
free(enodename);
|
free(enodename);
|
||||||
|
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
@@ -271,24 +296,24 @@ Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
|
|||||||
status = getnameinfo(sa, salen, enodename, nodenamelen,
|
status = getnameinfo(sa, salen, enodename, nodenamelen,
|
||||||
eservname, servnamelen, flags);
|
eservname, servnamelen, flags);
|
||||||
|
|
||||||
if (!status) {
|
if(!status) {
|
||||||
if (enodename) {
|
if(enodename) {
|
||||||
i = QadrtConvertE2A(nodename, enodename,
|
i = QadrtConvertE2A(nodename, enodename,
|
||||||
nodenamelen - 1, strlen(enodename));
|
nodenamelen - 1, strlen(enodename));
|
||||||
nodename[i] = '\0';
|
nodename[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eservname) {
|
if(eservname) {
|
||||||
i = QadrtConvertE2A(servname, eservname,
|
i = QadrtConvertE2A(servname, eservname,
|
||||||
servnamelen - 1, strlen(eservname));
|
servnamelen - 1, strlen(eservname));
|
||||||
servname[i] = '\0';
|
servname[i] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enodename)
|
if(enodename)
|
||||||
free(enodename);
|
free(enodename);
|
||||||
|
|
||||||
if (eservname)
|
if(eservname)
|
||||||
free(eservname);
|
free(eservname);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -309,21 +334,21 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
|
|||||||
enodename = (char *) NULL;
|
enodename = (char *) NULL;
|
||||||
eservname = (char *) NULL;
|
eservname = (char *) NULL;
|
||||||
|
|
||||||
if (nodename) {
|
if(nodename) {
|
||||||
i = strlen(nodename);
|
i = strlen(nodename);
|
||||||
|
|
||||||
if (!(enodename = malloc(i + 1)))
|
if(!(enodename = malloc(i + 1)))
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
|
|
||||||
i = QadrtConvertA2E(enodename, nodename, i, i);
|
i = QadrtConvertA2E(enodename, nodename, i, i);
|
||||||
enodename[i] = '\0';
|
enodename[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servname) {
|
if(servname) {
|
||||||
i = strlen(servname);
|
i = strlen(servname);
|
||||||
|
|
||||||
if (!(eservname = malloc(i + 1))) {
|
if(!(eservname = malloc(i + 1))) {
|
||||||
if (enodename)
|
if(enodename)
|
||||||
free(enodename);
|
free(enodename);
|
||||||
|
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
@@ -335,10 +360,10 @@ Curl_getaddrinfo_a(const char * nodename, const char * servname,
|
|||||||
|
|
||||||
status = getaddrinfo(enodename, eservname, hints, res);
|
status = getaddrinfo(enodename, eservname, hints, res);
|
||||||
|
|
||||||
if (enodename)
|
if(enodename)
|
||||||
free(enodename);
|
free(enodename);
|
||||||
|
|
||||||
if (eservname)
|
if(eservname)
|
||||||
free(eservname);
|
free(eservname);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -357,13 +382,13 @@ Curl_SSL_Init_Application_a(SSLInitApp * init_app)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
SSLInitApp ia;
|
SSLInitApp ia;
|
||||||
|
|
||||||
if (!init_app || !init_app->applicationID || !init_app->applicationIDLen)
|
if(!init_app || !init_app->applicationID || !init_app->applicationIDLen)
|
||||||
return SSL_Init_Application(init_app);
|
return SSL_Init_Application(init_app);
|
||||||
|
|
||||||
memcpy((char *) &ia, (char *) init_app, sizeof ia);
|
memcpy((char *) &ia, (char *) init_app, sizeof ia);
|
||||||
i = ia.applicationIDLen;
|
i = ia.applicationIDLen;
|
||||||
|
|
||||||
if (!(ia.applicationID = malloc(i + 1))) {
|
if(!(ia.applicationID = malloc(i + 1))) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return SSL_ERROR_IO;
|
return SSL_ERROR_IO;
|
||||||
}
|
}
|
||||||
@@ -386,15 +411,15 @@ Curl_SSL_Init_a(SSLInit * init)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
SSLInit ia;
|
SSLInit ia;
|
||||||
|
|
||||||
if (!init || (!init->keyringFileName && !init->keyringPassword))
|
if(!init || (!init->keyringFileName && !init->keyringPassword))
|
||||||
return SSL_Init(init);
|
return SSL_Init(init);
|
||||||
|
|
||||||
memcpy((char *) &ia, (char *) init, sizeof ia);
|
memcpy((char *) &ia, (char *) init, sizeof ia);
|
||||||
|
|
||||||
if (ia.keyringFileName) {
|
if(ia.keyringFileName) {
|
||||||
i = strlen(ia.keyringFileName);
|
i = strlen(ia.keyringFileName);
|
||||||
|
|
||||||
if (!(ia.keyringFileName = malloc(i + 1))) {
|
if(!(ia.keyringFileName = malloc(i + 1))) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return SSL_ERROR_IO;
|
return SSL_ERROR_IO;
|
||||||
}
|
}
|
||||||
@@ -403,11 +428,11 @@ Curl_SSL_Init_a(SSLInit * init)
|
|||||||
ia.keyringFileName[i] = '\0';
|
ia.keyringFileName[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ia.keyringPassword) {
|
if(ia.keyringPassword) {
|
||||||
i = strlen(ia.keyringPassword);
|
i = strlen(ia.keyringPassword);
|
||||||
|
|
||||||
if (!(ia.keyringPassword = malloc(i + 1))) {
|
if(!(ia.keyringPassword = malloc(i + 1))) {
|
||||||
if (ia.keyringFileName)
|
if(ia.keyringFileName)
|
||||||
free(ia.keyringFileName);
|
free(ia.keyringFileName);
|
||||||
|
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
@@ -420,10 +445,10 @@ Curl_SSL_Init_a(SSLInit * init)
|
|||||||
|
|
||||||
rc = SSL_Init(&ia);
|
rc = SSL_Init(&ia);
|
||||||
|
|
||||||
if (ia.keyringFileName)
|
if(ia.keyringFileName)
|
||||||
free(ia.keyringFileName);
|
free(ia.keyringFileName);
|
||||||
|
|
||||||
if (ia.keyringPassword)
|
if(ia.keyringPassword)
|
||||||
free(ia.keyringPassword);
|
free(ia.keyringPassword);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -434,23 +459,8 @@ char *
|
|||||||
Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
|
Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
|
||||||
|
|
||||||
{
|
{
|
||||||
int i;
|
return set_thread_string(LK_SSL_ERROR,
|
||||||
char * cp;
|
SSL_Strerror(sslreturnvalue, serrmsgp));
|
||||||
char * cp2;
|
|
||||||
|
|
||||||
cp = SSL_Strerror(sslreturnvalue, serrmsgp);
|
|
||||||
|
|
||||||
if (!cp)
|
|
||||||
return cp;
|
|
||||||
|
|
||||||
i = strlen(cp);
|
|
||||||
|
|
||||||
if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1)))
|
|
||||||
return cp2;
|
|
||||||
|
|
||||||
i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
|
|
||||||
cp2[i] = '\0';
|
|
||||||
return cp2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_QSOSSL */
|
#endif /* USE_QSOSSL */
|
||||||
@@ -534,7 +544,7 @@ gsk_free_handle(struct Curl_gsk_descriptor * p)
|
|||||||
{
|
{
|
||||||
struct gskstrlist * q;
|
struct gskstrlist * q;
|
||||||
|
|
||||||
while ((q = p->strlist)) {
|
while((q = p->strlist)) {
|
||||||
p->strlist = q;
|
p->strlist = q;
|
||||||
free((void *) q->asciistr);
|
free((void *) q->asciistr);
|
||||||
free(q);
|
free(q);
|
||||||
@@ -555,7 +565,7 @@ Curl_gsk_environment_close(gsk_handle * my_env_handle)
|
|||||||
if(!*my_env_handle)
|
if(!*my_env_handle)
|
||||||
return GSK_INVALID_HANDLE;
|
return GSK_INVALID_HANDLE;
|
||||||
p = (struct Curl_gsk_descriptor *) *my_env_handle;
|
p = (struct Curl_gsk_descriptor *) *my_env_handle;
|
||||||
if ((rc = gsk_environment_close(&p->h)) == GSK_OK) {
|
if((rc = gsk_environment_close(&p->h)) == GSK_OK) {
|
||||||
gsk_free_handle(p);
|
gsk_free_handle(p);
|
||||||
*my_env_handle = (gsk_handle) NULL;
|
*my_env_handle = (gsk_handle) NULL;
|
||||||
}
|
}
|
||||||
@@ -575,7 +585,7 @@ Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
|
|||||||
if(!*my_session_handle)
|
if(!*my_session_handle)
|
||||||
return GSK_INVALID_HANDLE;
|
return GSK_INVALID_HANDLE;
|
||||||
p = (struct Curl_gsk_descriptor *) *my_session_handle;
|
p = (struct Curl_gsk_descriptor *) *my_session_handle;
|
||||||
if ((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
|
if((rc = gsk_secure_soc_close(&p->h)) == GSK_OK) {
|
||||||
gsk_free_handle(p);
|
gsk_free_handle(p);
|
||||||
*my_session_handle = (gsk_handle) NULL;
|
*my_session_handle = (gsk_handle) NULL;
|
||||||
}
|
}
|
||||||
@@ -627,7 +637,7 @@ Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
|
|||||||
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
|
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
|
||||||
if(!bufSize)
|
if(!bufSize)
|
||||||
bufSize = strlen(buffer);
|
bufSize = strlen(buffer);
|
||||||
if (!(ebcdicbuf = malloc(bufSize + 1)))
|
if(!(ebcdicbuf = malloc(bufSize + 1)))
|
||||||
return GSK_INSUFFICIENT_STORAGE;
|
return GSK_INSUFFICIENT_STORAGE;
|
||||||
QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
|
QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
|
||||||
ebcdicbuf[bufSize] = '\0';
|
ebcdicbuf[bufSize] = '\0';
|
||||||
@@ -689,7 +699,7 @@ cachestring(struct Curl_gsk_descriptor * p,
|
|||||||
char * asciibuf;
|
char * asciibuf;
|
||||||
struct gskstrlist * sp;
|
struct gskstrlist * sp;
|
||||||
|
|
||||||
for (sp = p->strlist; sp; sp = sp->next)
|
for(sp = p->strlist; sp; sp = sp->next)
|
||||||
if(sp->ebcdicstr == ebcdicbuf)
|
if(sp->ebcdicstr == ebcdicbuf)
|
||||||
break;
|
break;
|
||||||
if(!sp) {
|
if(!sp) {
|
||||||
@@ -726,7 +736,7 @@ Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
|
|||||||
if(!buffer || !bufSize)
|
if(!buffer || !bufSize)
|
||||||
return GSK_OS400_ERROR_INVALID_POINTER;
|
return GSK_OS400_ERROR_INVALID_POINTER;
|
||||||
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
|
p = (struct Curl_gsk_descriptor *) my_gsk_handle;
|
||||||
if ((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
|
if((rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen)) != GSK_OK)
|
||||||
return rc;
|
return rc;
|
||||||
if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
|
if((rc = cachestring(p, mybuf, mylen, buffer)) == GSK_OK)
|
||||||
*bufSize = mylen;
|
*bufSize = mylen;
|
||||||
@@ -825,23 +835,7 @@ const char *
|
|||||||
Curl_gsk_strerror_a(int gsk_return_value)
|
Curl_gsk_strerror_a(int gsk_return_value)
|
||||||
|
|
||||||
{
|
{
|
||||||
int i;
|
return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
|
||||||
const char * cp;
|
|
||||||
char * cp2;
|
|
||||||
|
|
||||||
cp = gsk_strerror(gsk_return_value);
|
|
||||||
|
|
||||||
if (!cp)
|
|
||||||
return cp;
|
|
||||||
|
|
||||||
i = strlen(cp);
|
|
||||||
|
|
||||||
if (!(cp2 = Curl_thread_buffer(LK_GSK_ERROR, MAX_CONV_EXPANSION * i + 1)))
|
|
||||||
return cp2;
|
|
||||||
|
|
||||||
i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
|
|
||||||
cp2[i] = '\0';
|
|
||||||
return cp2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -878,11 +872,11 @@ Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
|
|||||||
|
|
||||||
i = buf->length;
|
i = buf->length;
|
||||||
|
|
||||||
if (i) {
|
if(i) {
|
||||||
if (!(t = malloc(i))) {
|
if(!(t = malloc(i))) {
|
||||||
gss_release_buffer(minor_status, buf);
|
gss_release_buffer(minor_status, buf);
|
||||||
|
|
||||||
if (minor_status)
|
if(minor_status)
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -906,14 +900,14 @@ Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
gss_buffer_desc in;
|
gss_buffer_desc in;
|
||||||
|
|
||||||
if (!in_name || !in_name->value || !in_name->length)
|
if(!in_name || !in_name->value || !in_name->length)
|
||||||
return gss_import_name(minor_status, in_name, in_name_type, out_name);
|
return gss_import_name(minor_status, in_name, in_name_type, out_name);
|
||||||
|
|
||||||
memcpy((char *) &in, (char *) in_name, sizeof in);
|
memcpy((char *) &in, (char *) in_name, sizeof in);
|
||||||
i = in.length;
|
i = in.length;
|
||||||
|
|
||||||
if (!(in.value = malloc(i + 1))) {
|
if(!(in.value = malloc(i + 1))) {
|
||||||
if (minor_status)
|
if(minor_status)
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
|
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
@@ -938,15 +932,15 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
|
|||||||
rc = gss_display_status(minor_status, status_value, status_type,
|
rc = gss_display_status(minor_status, status_value, status_type,
|
||||||
mech_type, message_context, status_string);
|
mech_type, message_context, status_string);
|
||||||
|
|
||||||
if (rc != GSS_S_COMPLETE || !status_string ||
|
if(rc != GSS_S_COMPLETE || !status_string ||
|
||||||
!status_string->length || !status_string->value)
|
!status_string->length || !status_string->value)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* No way to allocate a buffer here, because it will be released by
|
/* No way to allocate a buffer here, because it will be released by
|
||||||
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
||||||
with ASCII to return it. */
|
with ASCII to return it. */
|
||||||
|
|
||||||
if (Curl_gss_convert_in_place(minor_status, status_string))
|
if(Curl_gss_convert_in_place(minor_status, status_string))
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -954,7 +948,8 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
|
|||||||
|
|
||||||
|
|
||||||
OM_uint32
|
OM_uint32
|
||||||
Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
|
Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
|
||||||
|
gss_cred_id_t cred_handle,
|
||||||
gss_ctx_id_t * context_handle,
|
gss_ctx_id_t * context_handle,
|
||||||
gss_name_t target_name, gss_OID mech_type,
|
gss_name_t target_name, gss_OID mech_type,
|
||||||
gss_flags_t req_flags, OM_uint32 time_req,
|
gss_flags_t req_flags, OM_uint32 time_req,
|
||||||
@@ -972,12 +967,12 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
|
|||||||
|
|
||||||
in.value = NULL;
|
in.value = NULL;
|
||||||
|
|
||||||
if ((inp = input_token))
|
if((inp = input_token))
|
||||||
if (inp->length && inp->value) {
|
if(inp->length && inp->value) {
|
||||||
i = inp->length;
|
i = inp->length;
|
||||||
|
|
||||||
if (!(in.value = malloc(i + 1))) {
|
if(!(in.value = malloc(i + 1))) {
|
||||||
if (minor_status)
|
if(minor_status)
|
||||||
*minor_status = ENOMEM;
|
*minor_status = ENOMEM;
|
||||||
|
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
@@ -994,10 +989,10 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
|
|||||||
input_chan_bindings, inp, actual_mech_type,
|
input_chan_bindings, inp, actual_mech_type,
|
||||||
output_token, ret_flags, time_rec);
|
output_token, ret_flags, time_rec);
|
||||||
|
|
||||||
if (in.value)
|
if(in.value)
|
||||||
free(in.value);
|
free(in.value);
|
||||||
|
|
||||||
if (rc != GSS_S_COMPLETE || !output_token ||
|
if(rc != GSS_S_COMPLETE || !output_token ||
|
||||||
!output_token->length || !output_token->value)
|
!output_token->length || !output_token->value)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -1005,7 +1000,7 @@ Curl_gss_init_sec_context_a(OM_uint32 * minor_status, gss_cred_id_t cred_handle,
|
|||||||
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
||||||
with ASCII to return it. */
|
with ASCII to return it. */
|
||||||
|
|
||||||
if (Curl_gss_convert_in_place(minor_status, output_token))
|
if(Curl_gss_convert_in_place(minor_status, output_token))
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1022,7 +1017,7 @@ Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
|
|||||||
|
|
||||||
rc = gss_delete_sec_context(minor_status, context_handle, output_token);
|
rc = gss_delete_sec_context(minor_status, context_handle, output_token);
|
||||||
|
|
||||||
if (rc != GSS_S_COMPLETE || !output_token ||
|
if(rc != GSS_S_COMPLETE || !output_token ||
|
||||||
!output_token->length || !output_token->value)
|
!output_token->length || !output_token->value)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@@ -1030,7 +1025,7 @@ Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
|
|||||||
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
|
||||||
with ASCII to return it. */
|
with ASCII to return it. */
|
||||||
|
|
||||||
if (Curl_gss_convert_in_place(minor_status, output_token))
|
if(Curl_gss_convert_in_place(minor_status, output_token))
|
||||||
return GSS_S_FAILURE;
|
return GSS_S_FAILURE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -1051,12 +1046,12 @@ Curl_ldap_init_a(char * host, int port)
|
|||||||
char * ehost;
|
char * ehost;
|
||||||
void * result;
|
void * result;
|
||||||
|
|
||||||
if (!host)
|
if(!host)
|
||||||
return (void *) ldap_init(host, port);
|
return (void *) ldap_init(host, port);
|
||||||
|
|
||||||
i = strlen(host);
|
i = strlen(host);
|
||||||
|
|
||||||
if (!(ehost = malloc(i + 1)))
|
if(!(ehost = malloc(i + 1)))
|
||||||
return (void *) NULL;
|
return (void *) NULL;
|
||||||
|
|
||||||
QadrtConvertA2E(ehost, host, i, i);
|
QadrtConvertA2E(ehost, host, i, i);
|
||||||
@@ -1078,21 +1073,21 @@ Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
|
|||||||
edn = (char *) NULL;
|
edn = (char *) NULL;
|
||||||
epasswd = (char *) NULL;
|
epasswd = (char *) NULL;
|
||||||
|
|
||||||
if (dn) {
|
if(dn) {
|
||||||
i = strlen(dn);
|
i = strlen(dn);
|
||||||
|
|
||||||
if (!(edn = malloc(i + 1)))
|
if(!(edn = malloc(i + 1)))
|
||||||
return LDAP_NO_MEMORY;
|
return LDAP_NO_MEMORY;
|
||||||
|
|
||||||
QadrtConvertA2E(edn, dn, i, i);
|
QadrtConvertA2E(edn, dn, i, i);
|
||||||
edn[i] = '\0';
|
edn[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passwd) {
|
if(passwd) {
|
||||||
i = strlen(passwd);
|
i = strlen(passwd);
|
||||||
|
|
||||||
if (!(epasswd = malloc(i + 1))) {
|
if(!(epasswd = malloc(i + 1))) {
|
||||||
if (edn)
|
if(edn)
|
||||||
free(edn);
|
free(edn);
|
||||||
|
|
||||||
return LDAP_NO_MEMORY;
|
return LDAP_NO_MEMORY;
|
||||||
@@ -1104,10 +1099,10 @@ Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
|
|||||||
|
|
||||||
i = ldap_simple_bind_s(ld, edn, epasswd);
|
i = ldap_simple_bind_s(ld, edn, epasswd);
|
||||||
|
|
||||||
if (epasswd)
|
if(epasswd)
|
||||||
free(epasswd);
|
free(epasswd);
|
||||||
|
|
||||||
if (edn)
|
if(edn)
|
||||||
free(edn);
|
free(edn);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
@@ -1131,10 +1126,10 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
|
|||||||
eattrs = (char * *) NULL;
|
eattrs = (char * *) NULL;
|
||||||
status = LDAP_SUCCESS;
|
status = LDAP_SUCCESS;
|
||||||
|
|
||||||
if (base) {
|
if(base) {
|
||||||
i = strlen(base);
|
i = strlen(base);
|
||||||
|
|
||||||
if (!(ebase = malloc(i + 1)))
|
if(!(ebase = malloc(i + 1)))
|
||||||
status = LDAP_NO_MEMORY;
|
status = LDAP_NO_MEMORY;
|
||||||
else {
|
else {
|
||||||
QadrtConvertA2E(ebase, base, i, i);
|
QadrtConvertA2E(ebase, base, i, i);
|
||||||
@@ -1142,10 +1137,10 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter && status == LDAP_SUCCESS) {
|
if(filter && status == LDAP_SUCCESS) {
|
||||||
i = strlen(filter);
|
i = strlen(filter);
|
||||||
|
|
||||||
if (!(efilter = malloc(i + 1)))
|
if(!(efilter = malloc(i + 1)))
|
||||||
status = LDAP_NO_MEMORY;
|
status = LDAP_NO_MEMORY;
|
||||||
else {
|
else {
|
||||||
QadrtConvertA2E(efilter, filter, i, i);
|
QadrtConvertA2E(efilter, filter, i, i);
|
||||||
@@ -1153,17 +1148,17 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs && status == LDAP_SUCCESS) {
|
if(attrs && status == LDAP_SUCCESS) {
|
||||||
for (i = 0; attrs[i++];)
|
for(i = 0; attrs[i++];)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!(eattrs = calloc(i, sizeof *eattrs)))
|
if(!(eattrs = calloc(i, sizeof *eattrs)))
|
||||||
status = LDAP_NO_MEMORY;
|
status = LDAP_NO_MEMORY;
|
||||||
else {
|
else {
|
||||||
for (j = 0; attrs[j]; j++) {
|
for(j = 0; attrs[j]; j++) {
|
||||||
i = strlen(attrs[j]);
|
i = strlen(attrs[j]);
|
||||||
|
|
||||||
if (!(eattrs[j] = malloc(i + 1))) {
|
if(!(eattrs[j] = malloc(i + 1))) {
|
||||||
status = LDAP_NO_MEMORY;
|
status = LDAP_NO_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1174,22 +1169,22 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == LDAP_SUCCESS)
|
if(status == LDAP_SUCCESS)
|
||||||
status = ldap_search_s(ld, ebase? ebase: "", scope,
|
status = ldap_search_s(ld, ebase? ebase: "", scope,
|
||||||
efilter? efilter: "(objectclass=*)",
|
efilter? efilter: "(objectclass=*)",
|
||||||
eattrs, attrsonly, res);
|
eattrs, attrsonly, res);
|
||||||
|
|
||||||
if (eattrs) {
|
if(eattrs) {
|
||||||
for (j = 0; eattrs[j]; j++)
|
for(j = 0; eattrs[j]; j++)
|
||||||
free(eattrs[j]);
|
free(eattrs[j]);
|
||||||
|
|
||||||
free(eattrs);
|
free(eattrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (efilter)
|
if(efilter)
|
||||||
free(efilter);
|
free(efilter);
|
||||||
|
|
||||||
if (ebase)
|
if(ebase)
|
||||||
free(ebase);
|
free(ebase);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -1206,10 +1201,10 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
|
|||||||
|
|
||||||
cp = (char *) NULL;
|
cp = (char *) NULL;
|
||||||
|
|
||||||
if (attr) {
|
if(attr) {
|
||||||
i = strlen(attr);
|
i = strlen(attr);
|
||||||
|
|
||||||
if (!(cp = malloc(i + 1))) {
|
if(!(cp = malloc(i + 1))) {
|
||||||
ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
|
ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
|
||||||
ldap_err2string(LDAP_NO_MEMORY));
|
ldap_err2string(LDAP_NO_MEMORY));
|
||||||
return (struct berval * *) NULL;
|
return (struct berval * *) NULL;
|
||||||
@@ -1221,11 +1216,11 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
|
|||||||
|
|
||||||
result = ldap_get_values_len(ld, entry, cp);
|
result = ldap_get_values_len(ld, entry, cp);
|
||||||
|
|
||||||
if (cp)
|
if(cp)
|
||||||
free(cp);
|
free(cp);
|
||||||
|
|
||||||
/* Result data are binary in nature, so they haven't been converted to EBCDIC.
|
/* Result data are binary in nature, so they haven't been
|
||||||
Therefore do not convert. */
|
converted to EBCDIC. Therefore do not convert. */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1235,23 +1230,7 @@ char *
|
|||||||
Curl_ldap_err2string_a(int error)
|
Curl_ldap_err2string_a(int error)
|
||||||
|
|
||||||
{
|
{
|
||||||
int i;
|
return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
|
||||||
char * cp;
|
|
||||||
char * cp2;
|
|
||||||
|
|
||||||
cp = ldap_err2string(error);
|
|
||||||
|
|
||||||
if (!cp)
|
|
||||||
return cp;
|
|
||||||
|
|
||||||
i = strlen(cp);
|
|
||||||
|
|
||||||
if (!(cp2 = Curl_thread_buffer(LK_LDAP_ERROR, MAX_CONV_EXPANSION * i + 1)))
|
|
||||||
return cp2;
|
|
||||||
|
|
||||||
i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i);
|
|
||||||
cp2[i] = '\0';
|
|
||||||
return cp2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1265,12 +1244,12 @@ Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
|
|||||||
|
|
||||||
cp = ldap_get_dn(ld, entry);
|
cp = ldap_get_dn(ld, entry);
|
||||||
|
|
||||||
if (!cp)
|
if(!cp)
|
||||||
return cp;
|
return cp;
|
||||||
|
|
||||||
i = strlen(cp);
|
i = strlen(cp);
|
||||||
|
|
||||||
if (!(cp2 = malloc(i + 1)))
|
if(!(cp2 = malloc(i + 1)))
|
||||||
return cp2;
|
return cp2;
|
||||||
|
|
||||||
QadrtConvertE2A(cp2, cp, i, i);
|
QadrtConvertE2A(cp2, cp, i, i);
|
||||||
@@ -1297,12 +1276,12 @@ Curl_ldap_first_attribute_a(void * ld,
|
|||||||
|
|
||||||
cp = ldap_first_attribute(ld, entry, berptr);
|
cp = ldap_first_attribute(ld, entry, berptr);
|
||||||
|
|
||||||
if (!cp)
|
if(!cp)
|
||||||
return cp;
|
return cp;
|
||||||
|
|
||||||
i = strlen(cp);
|
i = strlen(cp);
|
||||||
|
|
||||||
if (!(cp2 = malloc(i + 1)))
|
if(!(cp2 = malloc(i + 1)))
|
||||||
return cp2;
|
return cp2;
|
||||||
|
|
||||||
QadrtConvertE2A(cp2, cp, i, i);
|
QadrtConvertE2A(cp2, cp, i, i);
|
||||||
@@ -1329,12 +1308,12 @@ Curl_ldap_next_attribute_a(void * ld,
|
|||||||
|
|
||||||
cp = ldap_next_attribute(ld, entry, berptr);
|
cp = ldap_next_attribute(ld, entry, berptr);
|
||||||
|
|
||||||
if (!cp)
|
if(!cp)
|
||||||
return cp;
|
return cp;
|
||||||
|
|
||||||
i = strlen(cp);
|
i = strlen(cp);
|
||||||
|
|
||||||
if (!(cp2 = malloc(i + 1)))
|
if(!(cp2 = malloc(i + 1)))
|
||||||
return cp2;
|
return cp2;
|
||||||
|
|
||||||
QadrtConvertE2A(cp2, cp, i, i);
|
QadrtConvertE2A(cp2, cp, i, i);
|
||||||
@@ -1364,8 +1343,8 @@ convert_sockaddr(struct sockaddr_storage * dstaddr,
|
|||||||
|
|
||||||
/* Convert a socket address into job CCSID, if needed. */
|
/* Convert a socket address into job CCSID, if needed. */
|
||||||
|
|
||||||
if (!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
|
if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
|
||||||
sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
|
sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1398,7 +1377,7 @@ Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
|
|||||||
|
|
||||||
i = convert_sockaddr(&laddr, destaddr, addrlen);
|
i = convert_sockaddr(&laddr, destaddr, addrlen);
|
||||||
|
|
||||||
if (i < 0)
|
if(i < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return connect(sd, (struct sockaddr *) &laddr, i);
|
return connect(sd, (struct sockaddr *) &laddr, i);
|
||||||
@@ -1414,7 +1393,7 @@ Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
|
|||||||
|
|
||||||
i = convert_sockaddr(&laddr, localaddr, addrlen);
|
i = convert_sockaddr(&laddr, localaddr, addrlen);
|
||||||
|
|
||||||
if (i < 0)
|
if(i < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return bind(sd, (struct sockaddr *) &laddr, i);
|
return bind(sd, (struct sockaddr *) &laddr, i);
|
||||||
@@ -1431,7 +1410,7 @@ Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
|
|||||||
|
|
||||||
i = convert_sockaddr(&laddr, dstaddr, addrlen);
|
i = convert_sockaddr(&laddr, dstaddr, addrlen);
|
||||||
|
|
||||||
if (i < 0)
|
if(i < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
|
return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
|
||||||
@@ -1450,7 +1429,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
struct sockaddr_un * dstu;
|
struct sockaddr_un * dstu;
|
||||||
struct sockaddr_storage laddr;
|
struct sockaddr_storage laddr;
|
||||||
|
|
||||||
if (!fromaddr || !addrlen || *addrlen <= 0)
|
if(!fromaddr || !addrlen || *addrlen <= 0)
|
||||||
return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
|
return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
|
||||||
|
|
||||||
laddrlen = sizeof laddr;
|
laddrlen = sizeof laddr;
|
||||||
@@ -1458,7 +1437,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
rcvlen = recvfrom(sd, buffer, buflen, flags,
|
rcvlen = recvfrom(sd, buffer, buflen, flags,
|
||||||
(struct sockaddr *) &laddr, &laddrlen);
|
(struct sockaddr *) &laddr, &laddrlen);
|
||||||
|
|
||||||
if (rcvlen < 0)
|
if(rcvlen < 0)
|
||||||
return rcvlen;
|
return rcvlen;
|
||||||
|
|
||||||
switch (laddr.ss_family) {
|
switch (laddr.ss_family) {
|
||||||
@@ -1471,7 +1450,7 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
|
i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
|
||||||
laddrlen = i + offsetof(struct sockaddr_un, sun_path);
|
laddrlen = i + offsetof(struct sockaddr_un, sun_path);
|
||||||
|
|
||||||
if (laddrlen < *addrlen)
|
if(laddrlen < *addrlen)
|
||||||
dstu->sun_path[i] = '\0';
|
dstu->sun_path[i] = '\0';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1480,10 +1459,10 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (laddrlen > *addrlen)
|
if(laddrlen > *addrlen)
|
||||||
laddrlen = *addrlen;
|
laddrlen = *addrlen;
|
||||||
|
|
||||||
if (laddrlen)
|
if(laddrlen)
|
||||||
memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
|
memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1492,3 +1471,79 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
|
|||||||
*addrlen = laddrlen;
|
*addrlen = laddrlen;
|
||||||
return rcvlen;
|
return rcvlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBZ
|
||||||
|
const char *
|
||||||
|
Curl_os400_zlibVersion(void)
|
||||||
|
|
||||||
|
{
|
||||||
|
return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
|
||||||
|
|
||||||
|
{
|
||||||
|
z_const char * msgb4 = strm->msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = inflateInit(strm);
|
||||||
|
|
||||||
|
if(strm->msg != msgb4)
|
||||||
|
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
|
||||||
|
const char * version, int stream_size)
|
||||||
|
|
||||||
|
{
|
||||||
|
z_const char * msgb4 = strm->msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = inflateInit2(strm, windowBits);
|
||||||
|
|
||||||
|
if(strm->msg != msgb4)
|
||||||
|
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Curl_os400_inflate(z_streamp strm, int flush)
|
||||||
|
|
||||||
|
{
|
||||||
|
z_const char * msgb4 = strm->msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = inflate(strm, flush);
|
||||||
|
|
||||||
|
if(strm->msg != msgb4)
|
||||||
|
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
Curl_os400_inflateEnd(z_streamp strm)
|
||||||
|
|
||||||
|
{
|
||||||
|
z_const char * msgb4 = strm->msg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = inflateEnd(strm);
|
||||||
|
|
||||||
|
if(strm->msg != msgb4)
|
||||||
|
strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ typedef enum {
|
|||||||
LK_EASY_STRERROR,
|
LK_EASY_STRERROR,
|
||||||
LK_SHARE_STRERROR,
|
LK_SHARE_STRERROR,
|
||||||
LK_MULTI_STRERROR,
|
LK_MULTI_STRERROR,
|
||||||
|
LK_ZLIB_VERSION,
|
||||||
|
LK_ZLIB_MSG,
|
||||||
LK_LAST
|
LK_LAST
|
||||||
} localkey_t;
|
} localkey_t;
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,14 @@
|
|||||||
#include "memdebug.h" /* keep this as LAST include */
|
#include "memdebug.h" /* keep this as LAST include */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** callback for CURLOPT_PROGRESSFUNCTION
|
** callback for CURLOPT_XFERINFOFUNCTION
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_BARLENGTH 256
|
#define MAX_BARLENGTH 256
|
||||||
|
|
||||||
int tool_progress_cb(void *clientp,
|
int tool_progress_cb(void *clientp,
|
||||||
double dltotal, double dlnow,
|
curl_off_t dltotal, curl_off_t dlnow,
|
||||||
double ultotal, double ulnow)
|
curl_off_t ultotal, curl_off_t ulnow)
|
||||||
{
|
{
|
||||||
/* The original progress-bar source code was written for curl by Lars Aas,
|
/* The original progress-bar source code was written for curl by Lars Aas,
|
||||||
and this new edition inherits some of his concepts. */
|
and this new edition inherits some of his concepts. */
|
||||||
@@ -60,10 +60,10 @@ int tool_progress_cb(void *clientp,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* expected transfer size */
|
/* expected transfer size */
|
||||||
total = (curl_off_t)dltotal + (curl_off_t)ultotal + bar->initial_size;
|
total = dltotal + ultotal + bar->initial_size;
|
||||||
|
|
||||||
/* we've come this far */
|
/* we've come this far */
|
||||||
point = (curl_off_t)dlnow + (curl_off_t)ulnow + bar->initial_size;
|
point = dlnow + ulnow + bar->initial_size;
|
||||||
|
|
||||||
if(point > total)
|
if(point > total)
|
||||||
/* we have got more than the expected total! */
|
/* we have got more than the expected total! */
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ void progressbarinit(struct ProgressData *bar,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int tool_progress_cb(void *clientp,
|
int tool_progress_cb(void *clientp,
|
||||||
double dltotal, double dlnow,
|
curl_off_t dltotal, curl_off_t dlnow,
|
||||||
double ultotal, double ulnow);
|
curl_off_t ultotal, curl_off_t ulnow);
|
||||||
|
|
||||||
#endif /* HEADER_CURL_TOOL_CB_PRG_H */
|
#endif /* HEADER_CURL_TOOL_CB_PRG_H */
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ struct Configurable {
|
|||||||
0 => -s is used to NOT show errors
|
0 => -s is used to NOT show errors
|
||||||
1 => -S has been used to show errors */
|
1 => -S has been used to show errors */
|
||||||
char *userpwd;
|
char *userpwd;
|
||||||
|
char *login_options;
|
||||||
char *tls_username;
|
char *tls_username;
|
||||||
char *tls_password;
|
char *tls_password;
|
||||||
char *tls_authtype;
|
char *tls_authtype;
|
||||||
|
|||||||
@@ -184,6 +184,9 @@ static const struct LongShort aliases[]= {
|
|||||||
{"01", "http1.1", FALSE},
|
{"01", "http1.1", FALSE},
|
||||||
{"02", "http2.0", FALSE},
|
{"02", "http2.0", FALSE},
|
||||||
{"1", "tlsv1", FALSE},
|
{"1", "tlsv1", FALSE},
|
||||||
|
{"10", "tlsv1.0", FALSE},
|
||||||
|
{"11", "tlsv1.1", FALSE},
|
||||||
|
{"12", "tlsv1.2", FALSE},
|
||||||
{"2", "sslv2", FALSE},
|
{"2", "sslv2", FALSE},
|
||||||
{"3", "sslv3", FALSE},
|
{"3", "sslv3", FALSE},
|
||||||
{"4", "ipv4", FALSE},
|
{"4", "ipv4", FALSE},
|
||||||
@@ -215,6 +218,7 @@ static const struct LongShort aliases[]= {
|
|||||||
{"El", "tlspassword", TRUE},
|
{"El", "tlspassword", TRUE},
|
||||||
{"Em", "tlsauthtype", TRUE},
|
{"Em", "tlsauthtype", TRUE},
|
||||||
{"En", "ssl-allow-beast", FALSE},
|
{"En", "ssl-allow-beast", FALSE},
|
||||||
|
{"Eo", "login-options", TRUE},
|
||||||
{"f", "fail", FALSE},
|
{"f", "fail", FALSE},
|
||||||
{"F", "form", TRUE},
|
{"F", "form", TRUE},
|
||||||
{"Fs", "form-string", TRUE},
|
{"Fs", "form-string", TRUE},
|
||||||
@@ -1023,9 +1027,25 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1': /* --tlsv1* options */
|
||||||
/* TLS version 1 */
|
switch(subletter) {
|
||||||
config->ssl_version = CURL_SSLVERSION_TLSv1;
|
case '\0':
|
||||||
|
/* TLS version 1.x */
|
||||||
|
config->ssl_version = CURL_SSLVERSION_TLSv1;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
/* TLS version 1.0 */
|
||||||
|
config->ssl_version = CURL_SSLVERSION_TLSv1_0;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
/* TLS version 1.1 */
|
||||||
|
config->ssl_version = CURL_SSLVERSION_TLSv1_1;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
/* TLS version 1.2 */
|
||||||
|
config->ssl_version = CURL_SSLVERSION_TLSv1_2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
/* SSL version 2 */
|
/* SSL version 2 */
|
||||||
@@ -1347,10 +1367,15 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
else
|
else
|
||||||
return PARAM_LIBCURL_DOESNT_SUPPORT;
|
return PARAM_LIBCURL_DOESNT_SUPPORT;
|
||||||
break;
|
break;
|
||||||
case 'n': /* no empty SSL fragments */
|
case 'n': /* no empty SSL fragments, --ssl-allow-beast */
|
||||||
if(curlinfo->features & CURL_VERSION_SSL)
|
if(curlinfo->features & CURL_VERSION_SSL)
|
||||||
config->ssl_allow_beast = toggle;
|
config->ssl_allow_beast = toggle;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'o': /* --login-options */
|
||||||
|
GetStr(&config->login_options, nextarg);
|
||||||
|
break;
|
||||||
|
|
||||||
default: /* certificate file */
|
default: /* certificate file */
|
||||||
{
|
{
|
||||||
char *certname, *passphrase;
|
char *certname, *passphrase;
|
||||||
@@ -1668,7 +1693,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
/* user:password;options */
|
/* user:password */
|
||||||
GetStr(&config->userpwd, nextarg);
|
GetStr(&config->userpwd, nextarg);
|
||||||
cleanarg(nextarg);
|
cleanarg(nextarg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ static const char *const helptext[] = {
|
|||||||
" --libcurl FILE Dump libcurl equivalent code of this command line",
|
" --libcurl FILE Dump libcurl equivalent code of this command line",
|
||||||
#endif
|
#endif
|
||||||
" --limit-rate RATE Limit transfer speed to this rate",
|
" --limit-rate RATE Limit transfer speed to this rate",
|
||||||
" -l, --list-only List only names of an FTP directory (F)",
|
" -l, --list-only List only mode (F/POP3)",
|
||||||
" --local-port RANGE Force use of these local port numbers",
|
" --local-port RANGE Force use of these local port numbers",
|
||||||
" -L, --location Follow redirects (H)",
|
" -L, --location Follow redirects (H)",
|
||||||
" --location-trusted like --location and send auth to other hosts (H)",
|
" --location-trusted like --location and send auth to other hosts (H)",
|
||||||
@@ -141,7 +141,7 @@ static const char *const helptext[] = {
|
|||||||
" --no-sessionid Disable SSL session-ID reusing (SSL)",
|
" --no-sessionid Disable SSL session-ID reusing (SSL)",
|
||||||
" --noproxy List of hosts which do not use proxy",
|
" --noproxy List of hosts which do not use proxy",
|
||||||
" --ntlm Use HTTP NTLM authentication (H)",
|
" --ntlm Use HTTP NTLM authentication (H)",
|
||||||
" --oauth2-bearer BEARER XOAUTH2 Bearer Token (IMAP, POP3, SMTP)",
|
" --oauth2-bearer TOKEN OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
|
||||||
" -o, --output FILE Write output to <file> instead of stdout",
|
" -o, --output FILE Write output to <file> instead of stdout",
|
||||||
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
||||||
" --post301 "
|
" --post301 "
|
||||||
@@ -215,7 +215,8 @@ static const char *const helptext[] = {
|
|||||||
" -T, --upload-file FILE Transfer FILE to destination",
|
" -T, --upload-file FILE Transfer FILE to destination",
|
||||||
" --url URL URL to work with",
|
" --url URL URL to work with",
|
||||||
" -B, --use-ascii Use ASCII/text transfer",
|
" -B, --use-ascii Use ASCII/text transfer",
|
||||||
" -u, --user USER[:PASSWORD] Server user and password",
|
" -u, --user USER[:PASSWORD][;OPTIONS] Server user, password and login"
|
||||||
|
" options",
|
||||||
" --tlsuser USER TLS username",
|
" --tlsuser USER TLS username",
|
||||||
" --tlspassword STRING TLS password",
|
" --tlspassword STRING TLS password",
|
||||||
" --tlsauthtype STRING TLS authentication type (default SRP)",
|
" --tlsauthtype STRING TLS authentication type (default SRP)",
|
||||||
|
|||||||
@@ -54,9 +54,7 @@
|
|||||||
# define MD5_CTX void *
|
# define MD5_CTX void *
|
||||||
# define SHA_CTX void *
|
# define SHA_CTX void *
|
||||||
# define SHA256_CTX void *
|
# define SHA256_CTX void *
|
||||||
# ifdef HAVE_NSS_INITCONTEXT
|
static NSSInitContext *nss_context;
|
||||||
static NSSInitContext *nss_context;
|
|
||||||
# endif
|
|
||||||
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
|
||||||
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
|
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
|
||||||
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
|
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
|
||||||
@@ -240,7 +238,6 @@ static int nss_hash_init(void **pctx, SECOidTag hash_alg)
|
|||||||
PK11Context *ctx;
|
PK11Context *ctx;
|
||||||
|
|
||||||
/* we have to initialize NSS if not initialized alraedy */
|
/* we have to initialize NSS if not initialized alraedy */
|
||||||
#ifdef HAVE_NSS_INITCONTEXT
|
|
||||||
if(!NSS_IsInitialized() && !nss_context) {
|
if(!NSS_IsInitialized() && !nss_context) {
|
||||||
static NSSInitParameters params;
|
static NSSInitParameters params;
|
||||||
params.length = sizeof params;
|
params.length = sizeof params;
|
||||||
@@ -248,7 +245,6 @@ static int nss_hash_init(void **pctx, SECOidTag hash_alg)
|
|||||||
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
|
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
|
||||||
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
|
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ctx = PK11_CreateDigestContext(hash_alg);
|
ctx = PK11_CreateDigestContext(hash_alg);
|
||||||
if(!ctx)
|
if(!ctx)
|
||||||
@@ -894,7 +890,7 @@ void clean_metalink(struct Configurable *config)
|
|||||||
|
|
||||||
void metalink_cleanup(void)
|
void metalink_cleanup(void)
|
||||||
{
|
{
|
||||||
#if defined(USE_NSS) && defined(HAVE_NSS_INITCONTEXT)
|
#ifdef USE_NSS
|
||||||
if(nss_context) {
|
if(nss_context) {
|
||||||
NSS_ShutdownContext(nss_context);
|
NSS_ShutdownContext(nss_context);
|
||||||
nss_context = NULL;
|
nss_context = NULL;
|
||||||
|
|||||||
@@ -1051,6 +1051,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
|
|||||||
my_setopt(curl, CURLOPT_NETRC_FILE, config->netrc_file);
|
my_setopt(curl, CURLOPT_NETRC_FILE, config->netrc_file);
|
||||||
|
|
||||||
my_setopt(curl, CURLOPT_TRANSFERTEXT, config->use_ascii?1L:0L);
|
my_setopt(curl, CURLOPT_TRANSFERTEXT, config->use_ascii?1L:0L);
|
||||||
|
if(config->login_options)
|
||||||
|
my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options);
|
||||||
my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
|
my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
|
||||||
my_setopt_str(curl, CURLOPT_RANGE, config->range);
|
my_setopt_str(curl, CURLOPT_RANGE, config->range);
|
||||||
my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
|
||||||
@@ -1235,8 +1237,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
|
|||||||
!config->noprogress && !config->mute) {
|
!config->noprogress && !config->mute) {
|
||||||
/* we want the alternative style, then we have to implement it
|
/* we want the alternative style, then we have to implement it
|
||||||
ourselves! */
|
ourselves! */
|
||||||
my_setopt(curl, CURLOPT_PROGRESSFUNCTION, tool_progress_cb);
|
my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
|
||||||
my_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
|
my_setopt(curl, CURLOPT_XFERINFODATA, &progressbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* new in libcurl 7.24.0: */
|
/* new in libcurl 7.24.0: */
|
||||||
|
|||||||
@@ -35,7 +35,10 @@
|
|||||||
#include "memdebug.h" /* keep this as LAST include */
|
#include "memdebug.h" /* keep this as LAST include */
|
||||||
|
|
||||||
#define CURLRC DOT_CHAR "curlrc"
|
#define CURLRC DOT_CHAR "curlrc"
|
||||||
#define ISSEP(x) (((x) == '=') || ((x) == ':'))
|
|
||||||
|
/* only acknowledge colon or equals as separators if the option was not
|
||||||
|
specified with an initial dash! */
|
||||||
|
#define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':')))
|
||||||
|
|
||||||
static const char *unslashquote(const char *line, char *param);
|
static const char *unslashquote(const char *line, char *param);
|
||||||
static char *my_get_line(FILE *fp);
|
static char *my_get_line(FILE *fp);
|
||||||
@@ -123,6 +126,7 @@ int parseconfig(const char *filename,
|
|||||||
char *param;
|
char *param;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
bool alloced_param;
|
bool alloced_param;
|
||||||
|
bool dashed_option;
|
||||||
|
|
||||||
while(NULL != (aline = my_get_line(file))) {
|
while(NULL != (aline = my_get_line(file))) {
|
||||||
lineno++;
|
lineno++;
|
||||||
@@ -146,7 +150,11 @@ int parseconfig(const char *filename,
|
|||||||
|
|
||||||
/* the option keywords starts here */
|
/* the option keywords starts here */
|
||||||
option = line;
|
option = line;
|
||||||
while(*line && !ISSPACE(*line) && !ISSEP(*line))
|
|
||||||
|
/* the option starts with a dash? */
|
||||||
|
dashed_option = option[0]=='-'?TRUE:FALSE;
|
||||||
|
|
||||||
|
while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option))
|
||||||
line++;
|
line++;
|
||||||
/* ... and has ended here */
|
/* ... and has ended here */
|
||||||
|
|
||||||
@@ -158,7 +166,7 @@ int parseconfig(const char *filename,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* pass spaces and separator(s) */
|
/* pass spaces and separator(s) */
|
||||||
while(*line && (ISSPACE(*line) || ISSEP(*line)))
|
while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option)))
|
||||||
line++;
|
line++;
|
||||||
|
|
||||||
/* the parameter starts here (unless quoted) */
|
/* the parameter starts here (unless quoted) */
|
||||||
@@ -180,6 +188,24 @@ int parseconfig(const char *filename,
|
|||||||
while(*line && !ISSPACE(*line))
|
while(*line && !ISSPACE(*line))
|
||||||
line++;
|
line++;
|
||||||
*line = '\0'; /* zero terminate */
|
*line = '\0'; /* zero terminate */
|
||||||
|
|
||||||
|
/* to detect mistakes better, see if there's data following */
|
||||||
|
line++;
|
||||||
|
/* pass all spaces */
|
||||||
|
while(*line && ISSPACE(*line))
|
||||||
|
line++;
|
||||||
|
|
||||||
|
switch(*line) {
|
||||||
|
case '\0':
|
||||||
|
case '\r':
|
||||||
|
case '\n':
|
||||||
|
case '#': /* comment */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warnf(config, "%s:%d: warning: '%s' uses unquoted white space in the"
|
||||||
|
" line that may cause side-effects!\n",
|
||||||
|
filename, lineno, option);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(param && !*param) {
|
if(param && !*param) {
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = {
|
|||||||
NV(CURL_SSLVERSION_TLSv1),
|
NV(CURL_SSLVERSION_TLSv1),
|
||||||
NV(CURL_SSLVERSION_SSLv2),
|
NV(CURL_SSLVERSION_SSLv2),
|
||||||
NV(CURL_SSLVERSION_SSLv3),
|
NV(CURL_SSLVERSION_SSLv3),
|
||||||
|
NV(CURL_SSLVERSION_TLSv1_0),
|
||||||
|
NV(CURL_SSLVERSION_TLSv1_1),
|
||||||
|
NV(CURL_SSLVERSION_TLSv1_2),
|
||||||
NVEND,
|
NVEND,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ typedef enum {
|
|||||||
|
|
||||||
void glob_cleanup(URLGlob* glob);
|
void glob_cleanup(URLGlob* glob);
|
||||||
|
|
||||||
static GlobCode glob_fixed(URLGlob *glob, unsigned long *amount)
|
static GlobCode glob_fixed(URLGlob *glob, char *fixed, size_t len)
|
||||||
{
|
{
|
||||||
URLPattern *pat = &glob->pattern[glob->size];
|
URLPattern *pat = &glob->pattern[glob->size];
|
||||||
pat->type = UPTSet;
|
pat->type = UPTSet;
|
||||||
@@ -48,17 +48,18 @@ static GlobCode glob_fixed(URLGlob *glob, unsigned long *amount)
|
|||||||
pat->content.Set.ptr_s = 0;
|
pat->content.Set.ptr_s = 0;
|
||||||
pat->globindex = -1;
|
pat->globindex = -1;
|
||||||
|
|
||||||
(*amount)++;
|
|
||||||
|
|
||||||
pat->content.Set.elements = malloc(sizeof(char*));
|
pat->content.Set.elements = malloc(sizeof(char*));
|
||||||
|
|
||||||
if(!pat->content.Set.elements)
|
if(!pat->content.Set.elements)
|
||||||
return GLOBERROR("out of memory", 0, GLOB_NO_MEM);
|
return GLOBERROR("out of memory", 0, GLOB_NO_MEM);
|
||||||
|
|
||||||
pat->content.Set.elements[0] = strdup(glob->glob_buffer);
|
pat->content.Set.elements[0] = malloc(len+1);
|
||||||
if(!pat->content.Set.elements[0])
|
if(!pat->content.Set.elements[0])
|
||||||
return GLOBERROR("out of memory", 0, GLOB_NO_MEM);
|
return GLOBERROR("out of memory", 0, GLOB_NO_MEM);
|
||||||
|
|
||||||
|
memcpy(pat->content.Set.elements[0], fixed, len);
|
||||||
|
pat->content.Set.elements[0][len] = 0;
|
||||||
|
|
||||||
return GLOB_OK;
|
return GLOB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +212,7 @@ static GlobCode glob_range(URLGlob *glob, char **patternp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pattern+=3;
|
pattern += 4;
|
||||||
|
|
||||||
*posp += (pattern - *patternp);
|
*posp += (pattern - *patternp);
|
||||||
|
|
||||||
@@ -307,11 +308,13 @@ static GlobCode glob_parse(URLGlob *glob, char *pattern,
|
|||||||
/* processes a literal string component of a URL
|
/* processes a literal string component of a URL
|
||||||
special characters '{' and '[' branch to set/range processing functions
|
special characters '{' and '[' branch to set/range processing functions
|
||||||
*/
|
*/
|
||||||
char* buf = glob->glob_buffer;
|
|
||||||
GlobCode res = GLOB_OK;
|
GlobCode res = GLOB_OK;
|
||||||
int globindex = 0; /* count "actual" globs */
|
int globindex = 0; /* count "actual" globs */
|
||||||
|
|
||||||
|
*amount = 1;
|
||||||
|
|
||||||
while(*pattern && !res) {
|
while(*pattern && !res) {
|
||||||
|
char *buf = glob->glob_buffer;
|
||||||
int sublen = 0;
|
int sublen = 0;
|
||||||
while(*pattern && *pattern != '{' && *pattern != '[') {
|
while(*pattern && *pattern != '{' && *pattern != '[') {
|
||||||
if(*pattern == '}' || *pattern == ']')
|
if(*pattern == '}' || *pattern == ']')
|
||||||
@@ -333,12 +336,9 @@ static GlobCode glob_parse(URLGlob *glob, char *pattern,
|
|||||||
if(sublen) {
|
if(sublen) {
|
||||||
/* we got a literal string, add it as a single-item list */
|
/* we got a literal string, add it as a single-item list */
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
res = glob_fixed(glob, amount);
|
res = glob_fixed(glob, glob->glob_buffer, sublen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!*amount)
|
|
||||||
*amount = 1;
|
|
||||||
|
|
||||||
switch (*pattern) {
|
switch (*pattern) {
|
||||||
case '\0': /* done */
|
case '\0': /* done */
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
# per line.
|
# per line.
|
||||||
# Lines starting with '#' letters are treated as comments.
|
# Lines starting with '#' letters are treated as comments.
|
||||||
594
|
594
|
||||||
|
815
|
||||||
|
816
|
||||||
1209
|
1209
|
||||||
1211
|
1211
|
||||||
1512
|
1512
|
||||||
|
|||||||
@@ -64,14 +64,19 @@ test700 test701 test702 test703 test704 test705 test706 test707 test708 \
|
|||||||
test709 test710 test711 test712 \
|
test709 test710 test711 test712 \
|
||||||
\
|
\
|
||||||
test800 test801 test802 test803 test804 test805 test806 test807 test808 \
|
test800 test801 test802 test803 test804 test805 test806 test807 test808 \
|
||||||
test809 test810 test811 test812 test813 test814 \
|
test809 test810 test811 test812 test813 test814 test815 test816 test817 \
|
||||||
|
test818 test819 test820 test821 test822 test823 test824 test825 test826 \
|
||||||
|
test827 test828 test829 test830 test831 test832 \
|
||||||
\
|
\
|
||||||
test850 test851 test852 test853 test854 test855 test856 test857 test858 \
|
test850 test851 test852 test853 test854 test855 test856 test857 test858 \
|
||||||
test859 test860 test861 test862 \
|
test859 test860 test861 test862 test863 test864 test865 test866 test867 \
|
||||||
|
test868 test869 test870 test871 test872 test873 test874 test875 test876 \
|
||||||
|
test877 test878 \
|
||||||
\
|
\
|
||||||
test900 test901 test902 test903 test904 test905 test906 test907 test908 \
|
test900 test901 test902 test903 test904 test905 test906 test907 test908 \
|
||||||
test909 test910 test911 test912 test913 test914 test915 test916 test917 \
|
test909 test910 test911 test912 test913 test914 test915 test916 test917 \
|
||||||
test918 \
|
test918 test919 test920 test921 test922 test923 test924 test925 test926 \
|
||||||
|
test927 test928 test929 test930 test931 test932 test933 test934 \
|
||||||
\
|
\
|
||||||
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
|
test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \
|
||||||
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
|
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
|
||||||
@@ -96,12 +101,12 @@ test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
|
|||||||
test1216 test1217 test1218 test1219 \
|
test1216 test1217 test1218 test1219 \
|
||||||
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
|
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
|
||||||
test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
|
test1228 test1229 test1230 test1231 test1232 test1233 test1234 test1235 \
|
||||||
test1236 test1237 test1238 test1239 \
|
test1236 test1237 test1238 test1239 test1240 \
|
||||||
\
|
\
|
||||||
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
|
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
|
||||||
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
|
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
|
||||||
test1316 test1317 test1318 test1319 test1320 test1321 test1322 test1323 \
|
test1316 test1317 test1318 test1319 test1320 test1321 \
|
||||||
test1324 test1325 test1326 test1327 test1328 test1329 test1330 test1331 \
|
test1325 test1326 test1327 test1328 test1329 test1330 test1331 \
|
||||||
test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 \
|
test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 \
|
||||||
test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 \
|
test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 \
|
||||||
test1348 test1349 test1350 test1351 test1352 test1353 test1354 test1355 \
|
test1348 test1349 test1350 test1351 test1352 test1353 test1354 test1355 \
|
||||||
|
|||||||
48
tests/data/test1240
Normal file
48
tests/data/test1240
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
globbing
|
||||||
|
HTTP
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
glob [0-1] with stuff after range (7.33.0 regression)
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
"%HOSTIP:%HTTPPORT/0[0-1]/1240"
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /00/1240 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
GET /01/1240 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
||||||
@@ -27,7 +27,7 @@ imap
|
|||||||
IMAP doesn't perform SELECT if re-using the same mailbox
|
IMAP doesn't perform SELECT if re-using the same mailbox
|
||||||
</name>
|
</name>
|
||||||
<command>
|
<command>
|
||||||
-u user:secret 'imap://%HOSTIP:%IMAPPORT/804/;UID=123/;SECTION=1' 'imap://%HOSTIP:%IMAPPORT/804/;UID=456/;SECTION=2.3'
|
'imap://%HOSTIP:%IMAPPORT/804/;UID=123/;SECTION=1' 'imap://%HOSTIP:%IMAPPORT/804/;UID=456/;SECTION=2.3' -u user:secret
|
||||||
</command>
|
</command>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user