Compare commits

...

246 Commits

Author SHA1 Message Date
Daniel Stenberg
0966b324d9 RELEASE-NOTES: synced with c0ef05e67
... for the pending 7.34.0 release

Upped the contributor count
2013-12-16 22:54:00 +01:00
Daniel Stenberg
c0ef05e675 THANKS: add contributors from 7.34.0 release
24 new great friends
2013-12-16 22:53:20 +01:00
Daniel Stenberg
1dc43de0dc gtls: respect *VERIFYHOST independently of *VERIFYPEER
Security flaw CVE-2013-6422

This is conceptually the same problem and fix that 3c3622b6 brought to the
OpenSSL backend and that resulted in CVE-2013-4545.

This version of the problem was independently introduced to the GnuTLS
backend with commit 59cf93cc, present in the code since the libcurl
7.21.4 release.

Advisory: http://curl.haxx.se/docs/adv_20131217.html
Bug: http://curl.haxx.se/mail/lib-2013-11/0214.html
Reported-by: Marc Deslauriers
2013-12-16 22:47:31 +01:00
Daniel Stenberg
8a8f9a5d57 curl.1 document -J doesn't %-decode
...also added as KNOWN_BUG #87 with reference to bug #1294
2013-12-15 23:38:37 +01:00
Daniel Stenberg
be28223f35 multi: add timer inaccuracy margin to timeout/connecttimeout
Since all systems have inaccuracy in the timeout handling it is
imperative that we add an inaccuracy margin to the general timeout and
connecttimeout handling with the multi interface. This way, when the
timeout fires we should be fairly sure that it has passed the timeout
value and will be suitably detected.

For cases where the timeout fire before the actual timeout, we would
otherwise consume the timeout action and still not run the timeout code
since the condition wasn't met.

Reported-by: He Qin
Bug: http://curl.haxx.se/bug/view.cgi?id=1298
2013-12-15 22:53:41 +01:00
Daniel Stenberg
8e2d73bbde RELEASE-NOTES: synced with dd4d9ea542 2013-12-14 23:22:52 +01:00
Daniel Stenberg
dd4d9ea542 curl_easy_setopt: clarify some USERPWD and PROXYUSERPWD details 2013-12-14 23:09:05 +01:00
Daniel Stenberg
169fedbdce login options: remove the ;[options] support from CURLOPT_USERPWD
To avoid the regression when users pass in passwords containing semi-
colons, we now drop the ability to set the login options with the same
options. Support for login options in CURLOPT_USERPWD was added in
7.31.0.

Test case 83 was modified to verify that colons and semi-colons can be
used as part of the password when using -u (CURLOPT_USERPWD).

Bug: http://curl.haxx.se/bug/view.cgi?id=1311
Reported-by: Petr Bahula
Assisted-by: Steve Holme
Signed-off-by: Daniel Stenberg <daniel@haxx.se>
2013-12-14 22:40:37 +01:00
Steve Holme
32b9c30e67 imap: Fixed exclude of clear text when using auth=* in commit 75cd7fd667
It is not 100% clear whether * should include clear text LOGIN or not
from RFC-5092, however, including it is then consistent with current
POP3 behaviour where clear text, APOP or SASL may be chosen.
2013-12-14 12:24:17 +00:00
Steve Holme
75cd7fd667 imap: Fixed incorrect fallback to clear text authentication
If a specific SASL authentication mechanism was requested by the user
as part of the login options but wasn't supported by the server then
curl would fallback to clear text, when it shouldn't, rather than
reporting "No known authentication mechanisms supported" as the POP3
and SMTP protocols do.
2013-12-13 23:15:43 +00:00
Eric Lubin
7246dffff5 parsedate: avoid integer overflow
In C, signed integer overflow is undefined behavior. Thus, the compiler
is allowed to assume that it will not occur. In the check for an
overflow, the developer assumes that the signed integer of type time_t
will wrap around if it overflows. However, this behavior is undefined in
the C standard. Thus, when the compiler sees this, it simplifies t +
delta < t to delta < 0. Since delta > 0 and delta < 0 can't both be
true, the entire if statement is optimized out under certain
optimization levels. Thus, the parsedate function would return
PARSEDATE_OK with an undefined value in the time, instead of return -1 =
PARSEDATE_FAIL.
2013-12-11 16:32:21 +01:00
Daniel Stenberg
41d21e460f parseconfig: warn if unquoted white spaces are detected
Commit 0db811b6 made some existing config files pass on unexpected
values to libcurl that made it somewhat hard to track down what was
really going on.

This code detects unquoted white spaces in the parameter when parsing a
config file as that would be one symptom and it is generally a bad
syntax anyway.
2013-12-09 23:30:09 +01:00
Daniel Stenberg
aadca7f418 RELEASE-NOTES: recount contributors and libcurl options 2013-12-09 11:56:01 +01:00
Daniel Stenberg
3905bd637d RELEASE-NOTES: synced with c4f46e97ca 2013-12-07 22:52:31 +01:00
James Dury
c4f46e97ca TFTP: let tftp_multi_statemach()'s return codes through
It would otherwise always clobber the return code with new function
calls and it couldn't return timeout etc.

Bug: http://curl.haxx.se/bug/view.cgi?id=1310
2013-12-07 15:53:08 +01:00
Melissa Mears
bd3ca6630a darwinssl: Fix #if 10.6.0 for SecKeychainSearch
The comment here says that SecKeychainSearch causes a deprecation
warning when used with a minimum Mac OS X SDK version of 10.7.0, which
is correct.  However, the #if guard did not match.  It was intended to
only use the code if 10.6.0 support was enabled, but it had 10.7.0
instead.  This caused a warning if the minimum was exactly 10.7.0.
2013-12-07 00:10:04 -06:00
Christian Weisgerber
92e607abfa curl.h: <sys/select.h> for OpenBSD
curl.h should also include <sys/select.h> on OpenBSD to reliably
pull in select().  Typically, including <sys/time.h> will be enough,
but not if strict standards-compliance is requested (e.g. by defining
_XOPEN_SOURCE).
2013-12-06 13:28:27 +01:00
Daniel Stenberg
ef118c13ba digest: fix CURLAUTH_DIGEST_IE
The URI that is passed in as part of the Authorization: header needs to
be cut off at '?' if CURLAUTH_DIGEST_IE is set. Previously the code only
did when calculating the MD5sum.

Bug: http://curl.haxx.se/bug/view.cgi?id=1308
Patched-by: Sergey Tatarincev
2013-12-04 23:08:17 +01:00
Daniel Stenberg
1cf71bd76e Curl_is_connected: use proxy name in error message when proxy is used
(bug introduced in 255826c4, never present in a release)

Reported-by: Dima Tisnek
Bug: http://curl.haxx.se/mail/lib-2013-12/0006.html
2013-12-04 22:51:37 +01:00
Steve Holme
2c0ecac9d3 imap/pop3: Post graceful cancellation consistency changes 2013-12-04 20:19:36 +00:00
Melissa Mears
b0b5b51193 pop3: Fix POP3_TYPE_ANY signed compilation warning
POP3_TYPE_ANY, or ~0, is written to pop3c->preftype in lib/pop3c.c, an
unsigned int variable.  The result of ~0 is -1, which caused a warning
due to writing a negative number to an unsigned variable.  To fix this,
make the expression ~0U so that its value is considered the unsigned
number UINT_MAX which is what SASL_AUTH_ANY does in curl_sasl.h.
2013-12-04 20:18:44 +00:00
Kamil Dudka
ff9b66a8d4 tool_metalink: do not use HAVE_NSS_INITCONTEXT
... no longer provided by the configure script
2013-12-02 17:03:23 +01:00
Kamil Dudka
e221b55f67 nss: make sure that 'sslver' is always initialized 2013-12-02 16:09:12 +01:00
Kamil Dudka
865666afca nss: unconditionally require NSS_InitContext()
... since we depend on NSS 3.14+ because of SSL_VersionRangeSet() anyway
2013-12-02 15:00:13 +01:00
Kamil Dudka
7fc9325a52 nss: allow to use TLS > 1.0 if built against recent NSS
Bug: http://curl.haxx.se/mail/lib-2013-11/0162.html
2013-12-02 15:00:13 +01:00
Kamil Dudka
4fb8241add nss: put SSL version selection into separate fnc 2013-12-02 15:00:13 +01:00
Kamil Dudka
30e7e7552b nss: use a better API for controlling SSL version
This change introduces a dependency on NSS 3.14+.
2013-12-02 15:00:13 +01:00
Patrick Monnerat
f58f843f66 OS400: sync wrappers and RPG binding. 2013-12-02 14:33:51 +01:00
Steve Holme
d92de3a7e9 multi.c: Fixed compilation warning
warning: declaration of 'pipe' shadows a global declaration
2013-12-01 20:22:57 +00:00
Steve Holme
fe7fc61c6e RELEASE-NOTES: Synced with ad3836448e 2013-12-01 16:51:32 +00:00
Steve Holme
ad3836448e base64: Corrected typo from commit f3ee587775 2013-12-01 16:43:57 +00:00
Steve Holme
f3ee587775 base64: Post extended extended validation tidy up
Reduced the separate processing of the last quantum to be performed in
the main decoding loop and renamed some variables for consistency.
2013-12-01 13:59:47 +00:00
Steve Holme
c92c30edbd base64: Extended validation to look for invalid characters
Extended the basic validation in commit e17c1b25bc to return a
failure when invalid base64 characters are included.
2013-12-01 11:12:23 +00:00
Steve Holme
4d10f48629 base64: Post basic validation tidy up
Due to the length checks introduced in commit e17c1b25bc there is no
need to allow for extra space in the output buffer for a non-padded last
quantum.
2013-11-30 19:14:29 +00:00
Steve Holme
dc68120e63 curl_easy_getinfo: Post CURLINFO_TLS_SESSION tidy up
1) Renamed curl_tlsinfo to curl_tlssessioninfo as discussed on the
mailing list.
2) Renamed curl_ssl_backend to curl_sslbackend so it doesn't follow our
function naming convention.
3) Updated sessioninfo.c example accordingly.
2013-11-30 11:08:56 +00:00
Daniel Stenberg
0db811b69b parseconfig: dash options can't specified with colon or equals
Bug: http://curl.haxx.se/bug/view.cgi?id=1297
Reported-by: Michael Osipov
2013-11-29 15:17:08 +01:00
Daniel Stenberg
d81cbbcc2c curl.1: -G also takes --data-urlencode data 2013-11-29 15:10:53 +01:00
Daniel Stenberg
0dd6522036 globbing: curl glob counter mismatch with {} list use
The "fixed string" function wrongly bumped the "urlnum" counter which
made curl output the total number of URLs wrong when using
{one,two,three} lists in globs.

Reported-by: Michael-O
Bug: http://curl.haxx.se/bug/view.cgi?id=1305
2013-11-28 23:31:31 +01:00
Christian Grothoff
889cb9c982 sessioninfo.c: Added sample code for CURLINFO_TLS_SESSION
Added a simple example to show how one can use CURLINFO_TLS_SESSION for
obtaining extensive TLS certificate information.
2013-11-28 07:05:07 +00:00
Steve Holme
26ff1ea6c3 multi.c: Fixed compilation error introduced in commit a900d45489
Systems that define SIGPIPE_VARIABLE as a noop would not compile as
restore_pipe was defined afterwards.
2013-11-27 23:45:45 +00:00
Christian Grothoff
59f1209fad curl_easy_getopt: Handle API violation gracefully
This fixes a NULL dereference in the case where the client asks for
CURLINFO_TLS_SESSION data after the (TLS) session has already been
destroyed (i.e. curl_easy_perform has already completed for this
handle). Instead of crashing, we now return a CURLSSLBACKEND_NONE
error.
2013-11-27 23:35:34 +00:00
Steve Holme
7b9365c65f KNOWN_BUGS: #86: Disconnect commands may not be sent by IMAP, POP3 and SMTP 2013-11-27 22:35:08 +00:00
Jeff King
a900d45489 curl_multi_cleanup: ignore SIGPIPE
This is an extension to the fix in 7d80ed64e4. We may
call Curl_disconnect() while cleaning up the multi handle,
which could lead to openssl sending packets, which could get
a SIGPIPE.

Signed-off-by: Jeff King <peff@peff.net>
2013-11-27 22:47:12 +01:00
Jeff King
e64f91feb7 sigpipe: factor out sigpipe_reset from easy.c
Commit 7d80ed64e4 introduced some helpers to handle
sigpipe in easy.c. However, that fix was incomplete, and we
need to add more callers in other files. The first step is
making the helpers globally accessible.

Since the functions are small and should generally end up
inlined anyway, we simply define them in the header as
static functions.

Signed-off-by: Jeff King <peff@peff.net>
2013-11-27 22:46:55 +01:00
Björn Stenberg
b2a55c8106 connect: Try next ip directly after immediate connect fail
This fixes a rare Happy Eyeballs bug where if the first IP family runs
out of addresses before the second-family-timer fires, and the second
IP family's first connect fails immediately, no further IPs of the
second family are attempted.
2013-11-27 22:26:43 +01:00
Daniel Stenberg
030a2b8cb8 hostip: don't prune DNS cache entries that are in use
When adding entries to the DNS cache with CURLOPT_RESOLVE, they are
marked 'inuse' forever to prevent them from ever being removed in normal
operations. Still, the code that pruned out-of-date DNS entries didn't
care for the 'inuse' struct field and pruned it anyway!

Reported-by: Romulo A. Ceccon
Bug: http://curl.haxx.se/bug/view.cgi?id=1303
2013-11-25 00:10:23 +01:00
Steve Holme
edce855943 RELEASE-NOTES: Synced with 35e476a3f6 2013-11-24 18:05:54 +00:00
Steve Holme
35e476a3f6 tests: Re-ordered test arguments to match other IMAP tests 2013-11-24 17:59:17 +00:00
Steve Holme
0434a19431 tests: Corrected login "username" authentication responses 2013-11-24 16:25:44 +00:00
Steve Holme
2ff0c6f5f3 tests: Added error code explanation comments 2013-11-24 12:35:45 +00:00
Steve Holme
8a94aedbd6 tests: Removed expected QUIT response from graceful cancellation tests
A failure during authentication, which is performed as part of the
CONNECT phrase (for IMAP, POP3 and SMTP) is considered by the multi-
interface as being closed prematurely (aka a dead connection). As such
these protocols cannot issue the relevant QUIT or LOGOUT command.

Temporarily fixed the test cases until we can fix this properly.
2013-11-24 11:03:40 +00:00
Steve Holme
95877cf8ae tests: Added SMTP graceful authentication cancellation tests 2013-11-24 10:37:41 +00:00
Steve Holme
d3325ae40a tests: Added POP3 graceful authentication cancellation tests 2013-11-24 10:37:30 +00:00
Steve Holme
23fabf8dea ftpserver.pl: Reworked fix from commit 7a36b2abc0 2013-11-23 22:14:34 +00:00
Steve Holme
7a36b2abc0 ftpserver.pl: Fixed unknown IMAP command "*" 2013-11-23 19:19:12 +00:00
Steve Holme
e1c255f388 ftpserver.pl: Fixed servercmd REPLY with * detection 2013-11-23 16:28:28 +00:00
Steve Holme
6d3c832a30 tests: Added IMAP graceful authentication cancellation tests 2013-11-23 15:03:18 +00:00
Steve Holme
7935478397 tests: Moved CR LF in URL tests to their respective protocol groups 2013-11-23 14:49:50 +00:00
Steve Holme
5ee64be9c6 smtp: Post SMTP command expansion tidy up
Removed unnecessary SMTP_STOP state changes on failure.

Removed hard return on failure in smtp_state_data_resp().
2013-11-23 09:35:44 +00:00
Steve Holme
9f18cf15d5 symbols-in-versions: Added missing CURLSSLBACKEND_* symbols 2013-11-22 13:22:18 +00:00
Steve Holme
bf05da183e symbols-in-versions: Fixed missing CURLINFO_TLS_SESSION 2013-11-22 07:30:00 +00:00
Christian Grothoff
2c04e8d80c curl_easy_getinfo: Added CURLINFO_TLS_SESSION for accessing TLS internals
Added new API for returning a SSL backend type and pointer, in order to
allow access to the TLS internals, that may then be used to obtain X509
certificate information for example.
2013-11-21 20:40:04 +00:00
Steve Holme
925df53580 RELEASE-NOTES: Synced with 8191800a0c 2013-11-17 16:55:56 +00:00
Steve Holme
8191800a0c smtp: Fixed space being sent in non --mail-rcpt based requests
Commands such as NOOP, RSET and HELP would be sent with a space at the
end of the command, for example: "NOOP ".
2013-11-17 16:39:02 +00:00
Steve Holme
2165298fe6 tests: Added SMTP NOOP and RSET tests 2013-11-17 12:52:42 +00:00
Steve Holme
e885dc85a1 test928: Corrected typo in expected data from commit df58084695 2013-11-17 12:49:10 +00:00
Steve Holme
df58084695 tests: Added SMTP HELP test 2013-11-17 10:11:27 +00:00
Steve Holme
3c8c9b2779 smtp: Changed the default command to HELP when no options are specified
Otherwise a NOOP operation would be performed which a) only returns a
single line response and not a multiline response where -I needs to be
used, and b) provides an inconsistent user experience compared to that
of the POP3 and IMAP protocols.
2013-11-17 10:09:07 +00:00
Steve Holme
b27dc009cf smtp:Fixed memory leak from commit dac01ff6d7
The buffer allocated by smtp_parse_custom_request() was not freed.
2013-11-17 09:00:21 +00:00
Steve Holme
2c7a5578e1 connect: Close open but unconnected socket in singleipconnect()
singleipconnect() could return the file descriptor of an open socket
even though the function returned a CURLE_COULDNT_CONNECT error code
from commit ed1662c374 and 02fbc26d59.

This could cause tests 19, 704 and 1233 to fail on FreeBSD, AIX and
Solaris.
2013-11-17 00:27:18 +00:00
Steve Holme
b56d7cda74 tests: Added SMTP EXPN command test 2013-11-17 00:20:58 +00:00
Steve Holme
8896b56488 test926: Corrected unknown user reply from commit 0d735c29f9
The error code should not be sent as data as it isn't passed onto the
client as body data, so cannot be compared in the test suite against
expected data.
2013-11-16 20:33:08 +00:00
Steve Holme
0d735c29f9 tests: Corrected missing data reply sections from 3d50e91aee 2013-11-16 17:19:26 +00:00
Steve Holme
3d50e91aee tests: Added SMTP VRFY command tests 2013-11-16 12:20:22 +00:00
Steve Holme
0cbfe5a7d5 ftpserver.pl: Added support for new SMTP commands 2013-11-16 11:17:23 +00:00
Steve Holme
eedca5055e smtp: Fixed broken RCPT TO from commit 0ea4a80bb2 2013-11-15 22:20:56 +00:00
Daniel Stenberg
5d040632ac smtp_state_mail_resp: removed unused variable 'smtp' 2013-11-15 22:43:34 +01:00
Steve Holme
314c3b8480 DOCS: Updated curl_easy_setopt.3 following recent SMTP changes
* Added information about the verify and expand commands to
  CURLOPT_MAIL_RCPT.
* Reworked CURLOPT_CUSTOMREQUEST section, adding information about IMAP
  and SMTP custom commands.
2013-11-15 21:25:26 +00:00
Steve Holme
d630e1f389 DOCS: Updated manpage following recent SMTP modifications
* Added SMTP section to --request
* Expanded --mail-rcpt to describe the usage when using the verify and
  expand commands.
2013-11-15 21:23:56 +00:00
Steve Holme
0ea4a80bb2 smtp: Simplified the next RCPT TO logic 2013-11-15 21:05:45 +00:00
Steve Holme
ed4ce23c23 lib1507.c: Added missing set of CURLOPT_UPLOAD option
Although this option should have already been set, the SMTP module can
now download information from and send instructional commands to, an
SMTP server, requiring the option to be set in order to perform a mail
transfer.
2013-11-15 21:01:10 +00:00
Steve Holme
168aa59705 smtp.c: Fixed trailing whitespace 2013-11-15 20:43:04 +00:00
Steve Holme
f71b1ad908 smtp: Added support for VRFY and EXPN commands 2013-11-15 18:25:29 +00:00
Steve Holme
dac01ff6d7 smtp: Added support for NOOP and RSET commands 2013-11-15 16:14:01 +00:00
Steve Holme
4a9fe26837 smtp: Fixed handling of multiline server greeting responses
Incorrectly processed multiline server greeting responses as "wanted"
continue responses in smtp_endofresp(), from commit f16c0de4e9,
which in turn broke the SMTP server detection in the test suite,
because the EHLO command would not be sent.
2013-11-15 12:50:37 +00:00
Steve Holme
90ec8763a5 smtp.c: Fixed compilation error from commit f16c0de4e9
warning: unused variable 'smtpc'
2013-11-15 12:14:09 +00:00
Steve Holme
796333bc5e smtp: Fixed processing of more than one response when sent in same packet
Added a loop to smtp_statemach_act() in which Curl_pp_readresp() is
called until the cache is drained. Without this multiple responses
received in a single packet could result in a hang or delay.
2013-11-15 10:54:23 +00:00
Steve Holme
f16c0de4e9 smtp: Moved EHLO response handling to smtp_state_ehlo_resp()
Similar to the processing of untagged CAPABILITY responses in IMAP moved
the processing of multiline EHLO responses to smtp_state_ehlo_resp() and
introduced an internal response code of one to differentiate a multiline
continuation from the end of command. This also allows for the separate
processing of multiline responses from commands such as VRFY and EXPN.
2013-11-15 10:49:17 +00:00
Steve Holme
786cba1ada connect: Forgot to correct line endings before push in commit ed1662c374 2013-11-14 20:43:15 +00:00
Björn Stenberg
ed1662c374 connect: Return the socket descriptor even on fail
singleipconnect() did not return the open socket descriptor on some
errors, thereby sometimes causing a socket leak. This patch ensures
the socket is always returned.
2013-11-14 19:56:59 +00:00
Daniel Stenberg
1f0616ea1a configure: Fix test with -Werror=implicit-function-declaration
The ipv6 auto-detect test in configure returns a false negative when
CFLAGS contains -Werror=implicit-function-declaration. (I have been
using this flag to detect code issues that would result in SEGVs on
x86_64-cygwin.)

Patch-by: Yaakov Selkowitz
Bug: http://curl.haxx.se/bug/view.cgi?id=1304
2013-11-13 19:00:22 -08:00
Steve Holme
55250d2d02 test825: Corrected typo from commit b29217d0d6 2013-11-13 17:31:42 +00:00
Steve Holme
c5d73167a6 RELEASE-NOTES: Synced with bde901ad89 2013-11-13 10:12:01 +00:00
Steve Holme
bde901ad89 test922: Corrected title to match other OAuth 2.0 tests 2013-11-13 09:17:50 +00:00
Steve Holme
79c77f7c31 tests: Added IMAP OAuth 2.0 authentication with initial response test 2013-11-13 09:14:30 +00:00
Steve Holme
986c249f2f tests: Added IMAP NTLM authentication with initial response test 2013-11-13 09:14:10 +00:00
Steve Holme
3b8c3eb911 tests: Added IMAP login authentication with initial response test 2013-11-13 09:12:59 +00:00
Steve Holme
b29217d0d6 tests: Added IMAP plain authentication with initial response test 2013-11-13 09:12:32 +00:00
Steve Holme
534f90f9bf test873: Use proper padding in NTLM responses 2013-11-13 09:12:11 +00:00
Nick Zitzmann
dbe228353d darwinssl: check for SSLSetSessionOption() presence when toggling BEAST
Even though this is only a formality (since not many people build on
Mavericks while targeting Leopard), since we still support Leopard
at the earliest, we might as well be pedantic.
2013-11-12 20:26:20 -06:00
Nick Zitzmann
bf77101e5c darwinssl: PKCS#12 import feature now requires Lion or later
It turns out that some of the constants necessary to make this feature
work are missing from Snow Leopard's Security framework even though
they are defined in the headers.

Bug: http://curl.haxx.se/mail/lib-2013-11/0076.html
Reported by: myriachan
2013-11-12 20:18:04 -06:00
Steve Holme
2ea9a125a6 tests: Added POP3 OAuth 2.0 authentication with initial response test 2013-11-13 00:29:05 +00:00
Steve Holme
58a00d6d9f tests: Added POP3 NTLM authentication with initial response test 2013-11-13 00:24:06 +00:00
Steve Holme
57a27528e6 tests: Added POP3 login authentication with initial response test 2013-11-13 00:11:19 +00:00
Steve Holme
632c1edd06 tests: Added POP3 plain authentication with initial response test 2013-11-13 00:07:02 +00:00
Steve Holme
434bc09263 TODO: Added auth= in URLs to the wish list for HTTP 2013-11-12 20:32:25 +00:00
Steve Holme
f2584627c8 curl_easy_setopt: Added the ability to set the login options separately
Rather than set the authentication options as part of the login details
specified in the URL, or via the older CURLOPT_USERPWD option, added a
new libcurl option to allow the login options to be set separately.
2013-11-12 19:08:55 +00:00
Daniel Stenberg
6901861fc9 curl.1: mention that -O does no URL decoding 2013-11-12 09:28:07 -08:00
Tomas Hoger
d7d8a8f922 curl_easy_setopt.3: clarify CURLOPT_SSL_VERIFYHOST documentation
- better describe what happens when 1 is specified as parameter
- clarify what "is ignored" means for NSS builds
2013-11-12 17:03:13 +01:00
Steve Holme
c19cfb79db runtests.pl: Added SSPI detection 2013-11-12 12:48:28 +00:00
Steve Holme
65ce9b6d6c multi: Small code tidy up to avoid hard return 2013-11-12 09:59:22 +00:00
Steve Holme
5f34a10445 tests: Updated CRAM-MD5 tests to use test user details 2013-11-12 09:46:30 +00:00
Björn Stenberg
fa1253aee1 multi: Set read socket when returning READSOCK(0)
This patch fixes and issue introduced in commit 7d7df83198, if the
tunnel state was TUNNEL_CONNECT, waitconnect_getsock() would return a
bitmask indicating a readable socket but never stored the socket in the
return array.
2013-11-11 23:41:44 +00:00
Daniel Stenberg
f833f54979 bump: next release will be 7.34.0
Due to all the news and changes.
2013-11-11 08:46:27 +01:00
Björn Stenberg
e7d77fb3ef connect: Close temporary sockets in conn_free()
The temporary sockets used for Happy Eyeballs were not closed properly,
if curl exited prematurely, which this patch fixes.
2013-11-10 22:49:56 +00:00
Steve Holme
c8e63f247a tests: Corrected titles of POP3 and SMTP OAuth 2.0 tests 2013-11-10 20:26:57 +00:00
Steve Holme
7396ad6e09 test823: Fixed expected authentication text from commit e10a26a9d6
Fixed authentication text due to incorrect digest-uri property.
2013-11-10 20:21:18 +00:00
Steve Holme
6d295f8d7d test821: Fixed expected authentication text from commit 2d5455feac 2013-11-10 20:17:30 +00:00
Steve Holme
5bd999d0c5 RELEASE-NOTES: Synced with 0f81fbe5da 2013-11-10 18:16:21 +00:00
Kim Vandry
0f81fbe5da ares: Fixed compilation under Visual Studio 2012 2013-11-10 17:37:32 +00:00
Steve Holme
9b67960421 tests: Added IMAP OAuth 2.0 authentication test 2013-11-10 17:04:32 +00:00
Steve Holme
e10a26a9d6 tests: Added IMAP DIGEST-MD5 authentication test 2013-11-10 16:53:58 +00:00
Steve Holme
7b68b58bc0 tests: Added IMAP NTLM authentication test 2013-11-10 16:44:19 +00:00
Steve Holme
2d5455feac tests: Added IMAP CRAM-MD5 authentication test 2013-11-10 16:42:21 +00:00
Steve Holme
ac05c80f19 test819: Fixed expected authentication text from commit 76f924131c 2013-11-10 16:24:38 +00:00
Steve Holme
460adfef93 ftpserver.pl: Reworked custom reply handling code
1) To fix issues with IMAP custom replies
2) So initial space is not required in IMAP display text
3) To be more readable and understandable
2013-11-10 15:18:04 +00:00
Steve Holme
c876f6ae6d ftpserver.pl: Reworked unrecognised command responses
As the IMAP regex could fail and $1 would not contain the command id
updated the unrecognised command response to be more generic and
realistic (like those used in the command handlers).

Additionally updated the POP3, SMTP and FTP responses.
2013-11-10 10:20:50 +00:00
Steve Holme
f49276bfcb ftpserver.pl: Fixed processing of IMAP authentication strings 2013-11-10 10:08:32 +00:00
Daniel Stenberg
d08ee3c83d cmake: fix Windows build with IPv6 support
Patch-by: "Z98"
2013-11-09 00:07:32 +01:00
Steve Holme
cf7008670b Revert "ftpserver.pl: Corrected logic from commit 27b7b1062f9d97"
This reverts commit 558034ab70 as it appears to break the auto
builds. More thought is required for this!
2013-11-06 12:31:46 +00:00
Steve Holme
558034ab70 ftpserver.pl: Corrected logic from commit 27b7b1062f 2013-11-06 09:52:24 +00:00
Steve Holme
27b7b1062f ftpserver.pl: Fixed IMAP cmdid being sent on custom responses 2013-11-06 07:19:01 +00:00
Steve Holme
af82661dbd tests: Added IMAP login authentication test 2013-11-05 23:48:16 +00:00
Steve Holme
76f924131c tests: Added IMAP plain authentication test 2013-11-05 23:48:01 +00:00
Steve Holme
98a5fdaf29 url.c: Very small amount of policing 2013-11-05 23:30:12 +00:00
Björn Stenberg
1ea05be46d url.c: Remove superfluous for loop
The reason for this loop's existence was removed in commit
02fbc26d59.
2013-11-05 23:15:33 +00:00
Daniel Stenberg
c9d8c00a41 KNOWN_BUGS: STARTTRANSFER for POST requests
added 85. Wrong STARTTRANSFER timer accounting for POST requests
2013-11-05 10:21:30 +01:00
Daniel Stenberg
5aa290f0f2 Curl_ssl_push_certinfo_len: don't %.*s non-zero-terminated string
Our own printf() replacement clearly can't properly handle %.*s with a
string that isn't zero terminated. Instead of fixing the printf code or
even figuring out what the proper posix behavior is, I reverted this
piece of the code back to the previous version where it does malloc +
memcpy instead.

Regression added in e839446c2a, released in curl 7.32.0.

Reported-by: Felix Yan
Bug: http://curl.haxx.se/bug/view.cgi?id=1295
2013-11-05 09:59:19 +01:00
Steve Holme
f0831f7931 RELEASE-NOTES: Synced with 7fc3b2ce38 2013-11-05 07:17:24 +00:00
Steve Holme
7fc3b2ce38 connect.h: Updated copyright year for last edit 2013-11-05 07:15:01 +00:00
Björn Stenberg
02fbc26d59 connect: Add connection delay to Happy Eyeballs.
This patch adds a 200ms delay between the first and second address
family socket connection attempts.

It also iterates over IP addresses in the order returned by the
system, meaning most dual-stack systems will try IPv6 first.

Additionally, it refactors the connect code, removing most code that
handled synchronous connects. Since all sockets are now non-blocking,
the logic can be made simpler.
2013-11-04 22:38:19 +01:00
Steve Holme
0074c9f5d1 winbind: Fixed ntlm_auth expecting eol following commit e17c1b25bc 2013-11-04 20:12:22 +00:00
Steve Holme
90acbfd52e nss.c: Fixed compilation warnings (Take Two)
nss.c:702: warning: pointer targets in passing argument 3 of
'Curl_extract_certinfo' differ in signedness

nss.c:702: warning: pointer targets in passing argument 4 of
'Curl_extract_certinfo' differ in signedness

Made sure the cast was correctly "unsigned char *" to "char *" and not
"unsigned char *" to "unsigned char *".
2013-11-04 14:17:11 +00:00
Steve Holme
989b28fe97 nss.c: Fixed compilation warnings
nss.c:700: warning: pointer targets in passing argument 3 of
'Curl_extract_certinfo' differ in signedness

nss.c:700: warning: pointer targets in passing argument 4 of
'Curl_extract_certinfo' differ in signedness
2013-11-04 00:38:58 +00:00
Steve Holme
aa61e14dc1 tests: Added test for IMAP NOOP command 2013-11-03 21:36:46 +00:00
Steve Holme
a84a09ad0b tests: Added test for IMAP COPY command 2013-11-03 21:36:11 +00:00
Steve Holme
66b8557aff tests: Disable IMAP CLOSE and EXPUNGE command tests
This is temporary until curl supports either multiple custom commands
or post-quote commands in IMAP.
2013-11-03 20:39:21 +00:00
Steve Holme
63cac69c2a tests: Added tests for IMAP CLOSE and EXPUNGE commands 2013-11-03 20:37:34 +00:00
Steve Holme
f77d9b6584 connect.c: Code policing on commit 5094bb53f4
No need for a rhs condition on a bitwise compare.
2013-11-03 19:53:58 +00:00
Steve Holme
2736b27df7 nss.c: Fixed compilation warnings
warning: implicit declaration of function 'Curl_extract_certinfo'
2013-11-03 16:36:51 +00:00
Steve Holme
297644fa70 x509asn1.c: Fixed compilation warnings
warning: declaration of 'chsize' shadows a global declaration
2013-11-03 16:24:17 +00:00
Steve Holme
0177f28c51 DOCS: Expanded --request description to include POP3 and IMAP details 2013-11-03 14:39:10 +00:00
Steve Holme
732d10ed6c tool_help: Updated --list-only description to include POP3 2013-11-03 13:55:22 +00:00
Steve Holme
526a1c3b45 DOCS: Updated --list-only description to include POP3
Additionally corrected typos in --oauth2-bearer protocol list.
2013-11-03 13:54:49 +00:00
Steve Holme
5b315a273e base64: Fixed compilation warnings when using Curl_base64_decode()
curl_sasl.c:294: warning: dereferencing type-punned pointer will break
strict-aliasing rules

getpart.c:201: warning: dereferencing type-punned pointer will break
strict-aliasing rules
2013-11-03 12:25:07 +00:00
Steve Holme
5094bb53f4 connect: Fixed "Whut?" no server connection failures
Introduced in commit 7d7df83198 curl would loop displaying "Whut?"
if it was trying to connect to an address and port that didn't have
anything listening on it.
2013-11-03 11:27:12 +00:00
Steve Holme
052f24c9b7 http: Post base64 decoding tidy up
Renamed copy_header_value() to Curl_copy_header_value() as this
function is now non static.

Simplified proxy flag in Curl_http_input_auth() when calling
sub-functions.

Removed unnecessary white space removal when using negotiate as it had
been missed in commit cdccb42267.
2013-11-03 10:17:26 +00:00
Daniel Stenberg
bce03fe144 glob_range: pass the closing bracket for a-z ranges
Regression since commit 5ca96cb844 (release in 7.33.0)

Reported-by: Marcin Gryszkalis
2013-11-03 10:08:10 +01:00
Steve Holme
9a1755264f getpart: Fixed base64 encoded parts following commit e17c1b25bc 2013-11-02 17:00:00 +00:00
Steve Holme
3b59696a93 http: Added proxy tunnel authentication message header value extraction
...following recent changes to Curl_base64_decode() rather than trying
to parse a header line for the authentication mechanisms which is CRLF
terminated and inline zero terminate it.
2013-11-02 11:18:39 +00:00
Steve Holme
cdccb42267 http: Added authentication message header value extraction
...following recent changes to Curl_base64_decode() rather than trying
to parse a header line for the authentication mechanisms which is CRLF
terminated and inline zero terminate it.
2013-10-31 19:15:33 +00:00
Daniel Stenberg
753d44fa00 curl_multi_wait: accept 0 from multi_timeout() as valid timeout
The code rejected 0 as a valid timeout while in fact the function could
indeed legitimately return that and it should be respected.

Reported-by: Bjorn Stenberg
2013-10-30 23:48:08 +01:00
Steve Holme
cfdfdcdd9d email: Corrected a couple of typos from commit aa0eaef483 2013-10-30 21:25:15 +00:00
Steve Holme
e232f5f3f9 TODO: Removed the 'Graceful base64 decoding failure' sections
Updated following the recent changes to support graceful failures
during the authentication phrase.
2013-10-30 21:01:26 +00:00
Steve Holme
43400b4086 email: Post graceful SASL authentication cancellation tidy up 2013-10-30 20:58:24 +00:00
Kamil Dudka
8179354c2f tests: use proper padding in NTLM responses 2013-10-30 20:38:01 +00:00
Patrick Monnerat
f6c335d63f NSS: support for CERTINFO feature 2013-10-30 11:12:06 +01:00
Daniel Stenberg
2bd72fa61c base64: removed trailing white space
and updated copyright year
2013-10-30 09:11:10 +01:00
Steve Holme
e17c1b25bc base64: Added basic validation to base64 input string when decoding
A base64 string should be a multiple of 4 characters in length, not
contain any more than 2 padding characters and only contain padding
characters at the end of string. For example: Y3VybA==

Strings such as the following are considered invalid:

Y=   - Invalid length
Y==  - Invalid length
Y=== - More than two padding characters
Y=x= - Padding character contained within string
2013-10-30 07:31:22 +00:00
Daniel Stenberg
7d1eb66cd7 RELEASE-NOTES: synced with 255826c40f 2013-10-29 23:06:04 +01:00
Björn Stenberg
255826c40f bugfix: Don't block waiting for socket1 connect.
This patch fixes a bug in Happy Eyeballs where curl would wait for a
connect response from socket1 before checking socket2.

Also, it updates error messages for failed connections, showing the ip
addresses that failed rather than just the host name repeatedly.

Bug: http://curl.haxx.se/mail/lib-2013-10/0236.html
Reported-by: Paul Marks
2013-10-29 22:52:07 +01:00
Steve Holme
1d0eead969 sasl: Updated create_digest_md5_message() to use a dynamic buffer 2013-10-28 23:48:53 +00:00
Daniel Stenberg
8005e58983 SECURITY: "curl security for developers"
Describes our security process from a project and curl developer's
perspective.
2013-10-28 23:19:55 +01:00
Patrick Monnerat
5d415815df OS400: coding style standards 2013-10-28 12:00:22 +01:00
Steve Holme
f68559c086 email: Added support for cancelling NTLM authentication 2013-10-27 22:25:18 +00:00
Steve Holme
08f97f3b1d sasl: Removed unused variables from commit b87ba2c942 2013-10-27 17:04:56 +00:00
Steve Holme
b87ba2c942 email: Added support for cancelling DIGEST-MD5 authentication 2013-10-27 16:27:38 +00:00
Steve Holme
e7a2ba41e3 email: Corrected a couple of typos from 1e39b95682 2013-10-27 16:24:03 +00:00
Gisle Vanem
6fe619be7a docs/examples/httpput.c: fix build for MSVC
"Dan Fandrich" <dan@coneharvesters.com> wrote:

>> But I'm not sure <unistd.h> is needed at all.
>
> It's needed for close(2). But the only reason that's needed is because fstat
> is used instead of stat(2); if you fix that, then you could remove that
> include altogether.

Okay. I've tested the following with MSVC and MingW. htttput.c now
simply uses stat():
2013-10-27 15:48:57 +01:00
Steve Holme
1e39b95682 email: Added support for canceling CRAM-MD5 authentication 2013-10-27 12:42:30 +00:00
Björn Stenberg
8230af0b94 Typo fix in trynextip(). 2013-10-27 12:49:12 +01:00
Daniel Stenberg
1709e5e966 TODO: remove "Happy Eyeball dual stack connect"
... as it was just merged in commit 7d7df
2013-10-27 11:34:09 +01:00
Björn Stenberg
7d7df83198 Add "Happy Eyeballs" for IPv4/IPv6.
This patch invokes two socket connect()s nearly simultaneously, and
the socket that is first connected "wins" and is subsequently used for
the connection. The other is terminated.

There is a very slight IPv4 preference, in that if both sockets connect
simultaneously IPv4 is checked first and thus will win.
2013-10-27 11:19:53 +01:00
Steve Holme
7de4cc35f8 email: Added initial support for cancelling authentication
Should a client application fail to decode an authentication message
received from a server, or not support any of the parameters given by
the server in the message, then the authentication phrase should be
cancelled gracefully by the client rather than simply terminating the
connection.

The authentication phrase should be cancelled by simply sending a '*'
to the server, in response to erroneous data being received, as per
RFC-3501, RFC-4954 and RFC-5034.

This patch adds the necessary state machine constants and appropriate
response handlers in order to add this functionality for the CRAM-MD5,
DIGEST-MD5 and NTLM authentication mechanisms.
2013-10-27 09:17:03 +00:00
Steve Holme
aa0eaef483 email: Moved authentication message parsing into a separate function
...in preparation for upcoming modifications.
2013-10-27 09:04:59 +00:00
Steve Holme
9f503a254b ftp: Fixed compiler warning
warning: 'result' may be used uninitialized in this function
2013-10-27 00:00:01 +01:00
Daniel Stenberg
d44b014271 FTP: make the data connection work when going through proxy
This is a regression since the switch to always-multi internally
c43127414d.

Test 1316 was modified since we now clearly call the Curl_client_write()
function when doing the LIST transfer part and then the
handler->protocol says FTP and ftpc.transfertype is 'A' which implies
text converting even though that the response is initially a HTTP
CONNECT response in this case.
2013-10-26 23:33:06 +02:00
Steve Holme
469b423350 tool_help: Added login options to --user description 2013-10-26 20:11:48 +01:00
Steve Holme
0adad07690 email: Added references to SASL LOGIN authentication draft proposal 2013-10-26 14:35:27 +01:00
Steve Holme
e4670a1029 tests: Tidy up of SMTP and POP3 tests
Corrected line endings, RFC references and standardised on user names
and passwords used in the tests.
2013-10-26 13:50:08 +01:00
Steve Holme
1f0e50f2b9 tool_help: Added clarity to the --oauth2-bearer option
...as XOAUTH2 is the extended (or non-standard) SASL identifier and
OAuth 2 is the protocol name (and version).
2013-10-26 13:01:33 +01:00
Steve Holme
2766262a68 smtp: Fixed response code parsing for bad AUTH continuation responses
This workaround had been previously been implemented for IMAP and POP3
but not SMTP. Some of the recent test case additions implemented this
behaviour to emulate a bad server and the SMTP code didn't cope with it.
2013-10-26 11:09:31 +01:00
Steve Holme
bdb1f0e53d gskit.c: Code policing following commit 2cc9246477
Corrected 80 character line length error and pointer declarations (some
of which were previously incorrect)
2013-10-26 00:57:45 +01:00
Steve Holme
6e3613e6e6 test907: Corrected DIGEST-MD5 response given in commit 820ed48a00
As the URI, which is contained within the DIGEST-MD5 response, is
constructed from the service and realm, the encoded message differs
from that generated under POP3.
2013-10-26 00:24:45 +01:00
Steve Holme
1cb5150dba RELEASE-NOTES: Synced with d24b7953c2 2013-10-25 20:01:25 +01:00
Steve Holme
d24b7953c2 tests: Added SMTP OAUTH2 authentication with initial response test 2013-10-25 19:44:03 +01:00
Steve Holme
13db74ffc3 tests: Added SMTP NTLM authentication with initial response test 2013-10-25 19:40:23 +01:00
Steve Holme
98905aa2c5 tests: Added SMTP OAUTH2 authentication test 2013-10-25 19:34:05 +01:00
Steve Holme
820ed48a00 tests: Added SMTP DIGEST-MD5 authentication test 2013-10-25 19:31:51 +01:00
Steve Holme
973cc22529 tests: Regrouped SMTP authentication tests 2013-10-25 19:30:52 +01:00
Patrick Monnerat
2cc9246477 OS400: sync RPG wrapper, zlib support, fix header file names, ...
IFS compilation support, SSL GSKit backend by default, TLSv1.[12] support in
  GSKit for OS400 >= V7R1, no more tabs in make scripts.
2013-10-25 18:37:37 +02:00
Steve Holme
650036633f sasl: Fixed memory leak in OAUTH2 message creation 2013-10-24 00:16:59 +01:00
Steve Holme
78aee26be6 ftpserver.pl: Added support for empty pop3 authentication data 2013-10-23 22:19:42 +01:00
Daniel Stenberg
947d431d50 CURLOPT_RESOLVE: mention they don't time-out
Clarify in the documentation that DNS entries added with CURLOPT_RESOLVE
won't time-out.

Bug: http://curl.haxx.se/mail/lib-2013-10/0062.html
Reported-by: Romulo Ceccon
2013-10-23 23:15:36 +02:00
Steve Holme
58bd0148fb tests: Added POP3 OAUTH2 authentication test 2013-10-23 22:12:04 +01:00
Steve Holme
ca5c5be3e4 tests: Added empty response support to custom replies
...and fixed up test869 as DIGEST-MD transcript is as follows:

S: Challenge
C: Authentication String
S: Continue Response
C: Empty String
2013-10-23 22:05:22 +01:00
Daniel Stenberg
9bd37a6d27 sasl: fix compiler warning
error: unused variable 'table16'
2013-10-23 22:28:13 +02:00
Steve Holme
1be69159f3 tests: Added POP3 DIGEST-MD5 authentication test 2013-10-23 18:30:00 +01:00
Daniel Stenberg
a3da0a96e3 configure: check for long long when building with cyassl
cyassl/ctaocrypt/types.h needs SIZEOF_LONG_LONG

Reported-by: Chris Conlon
2013-10-22 22:55:48 +02:00
Daniel Stenberg
626f8a85f0 test1240: verify 867b52a7ac (glob ranges with text to the right) 2013-10-22 00:10:16 +02:00
Daniel Stenberg
867b52a7ac glob: fix regression from commit 5ca96cb844
Plain strings after glob ranges/lists weren't treated correctly but
caused broken URLs to get used.

Reported-by: Javier Barroso
2013-10-22 00:01:17 +02:00
Rémy Léone
be31924f8c Adding a .travis.yml file to use the travis-ci.org
From wikipedia:

Travis CI is a hosted, distributed continuous integration service used
to build and test projects hosted at GitHub.

Travis CI is configured by adding a file named .travis.yml, which is a
YAML format text file, to the root directory of the GitHub repository.

Travis CI automatically detects when a commit has been made and pushed
to a GitHub repository that is using Travis CI, and each time this
happens, it will try to build the project and run tests. This includes
commits to all branches, not just to the master branch. When that
process has completed, it will notify a developer in the way it has been
configured to do so — for example, by sending an email containing the
test results (showing success or failure), or by posting a message on an
IRC channel. It can be configured to run the tests on a range of
different machines, with different software installed (such as older
versions of a programming language, to test for compatibility).
2013-10-21 23:15:16 +02:00
Kamil Dudka
f70b2c77f4 ssh: initialize per-handle data in ssh_connect()
... if not already initialized.  This fixes a regression introduced by
commit 4ad8e142da, which caused test619
to intermittently fail on certain machines (namely Fedora build hosts).
2013-10-21 19:00:06 +02:00
Gisle Vanem
ae495ffcc3 curl.1: add missing exit-code
I noted a missing text for exit-code 89 in docs/curl.1
2013-10-20 23:57:24 +02:00
Daniel Stenberg
0fdfe82c6a cmake: unbreak for non-Windows platforms
Patch-by: Oliver Kuckertz
Bug: http://curl.haxx.se/bug/view.cgi?id=1292
2013-10-20 17:12:56 +02:00
Steve Holme
dead10b1b8 ftpserver.pl: Fixed syntax error from commit 5b31b38c27 2013-10-20 00:30:03 +01:00
Steve Holme
41d820d2c3 test866: Fixed user response from commit 7f7fbe7fbd 2013-10-19 21:43:20 +01:00
Steve Holme
5b31b38c27 ftpserver.pl: Fixed processing of POP3 authentication strings
...and corrected response when check fails from 500 to -ERR.
2013-10-19 20:39:18 +01:00
Steve Holme
39f4e4fafa tests: Added POP3 NTLM authentication test 2013-10-19 13:17:25 +01:00
Steve Holme
587811c0a6 tests: Added POP3 CRAM-MD5 authentication test 2013-10-19 12:57:25 +01:00
Steve Holme
7f7fbe7fbd tests: Added POP3 login authentication test 2013-10-19 12:42:25 +01:00
Steve Holme
9b1eb2b421 tests: Added POP3 plain authentication test 2013-10-19 12:31:55 +01:00
Steve Holme
1034aa6680 tests: Added POP3 APOP authentication test 2013-10-19 12:20:00 +01:00
Steve Holme
4be0af7f74 ftpserver.pl: Added support for APOP POP3 authentication 2013-10-19 10:38:19 +01:00
Steve Holme
72f850571d tests: Added POP3 RSET test 2013-10-19 00:10:29 +01:00
Steve Holme
e179d0eb12 RELEASE-NOTES: Synced with ce61510127 2013-10-18 19:54:30 +01:00
Steve Holme
ce61510127 email: Fixed QUIT / LOGOUT being sent when SSL connect fails 2013-10-18 19:28:20 +01:00
Kamil Dudka
86c64f3daf curl_sasl: initialize NSS before using crypto 2013-10-18 15:37:18 +02:00
Steve Holme
65e556d0ce SSL: Follow up work to commits 6a1363128f and 87861c9b0e
Changed the failure code when TLS v1.1 and v1.2 is requested but not
supported by older OpenSSL versions, following review from libcurl
peers, and reduced the number of required preprocessor if statements.
2013-10-17 19:57:26 +01:00
Steve Holme
6a1363128f SSL: Added unsupported cipher version check for OpenSSL
...with the use of CURL_SSLVERSION_TLSv1_1 and CURL_SSLVERSION_TLSv1_2
being conditional on OpenSSL v1.0.1 as the appropriate flags are not
supported under earlier versions.
2013-10-16 20:48:24 +01:00
Steve Holme
75b9b26465 DOCS: Added libcurl version number to CURLOPT_SSLVERSION 2013-10-16 20:18:18 +01:00
Steve Holme
2c84ffe154 SSL: Corrected version number for new symbols from commit ad34a2d5c8 2013-10-16 20:06:23 +01:00
Steve Holme
e7452415c5 SSL: Corrected typo from commit 87861c9b0e 2013-10-16 00:57:01 +01:00
Steve Holme
87861c9b0e SSL: Fixed OpenSSL builds prior to v1.0.1
Commit ad34a2d5c8 relies on definitions that are only present in
OpenSSL v1.0.1 and up. This quick fix allows the builds that use
older versions of OpenSSL to continue building.
2013-10-16 00:49:23 +01:00
Steve Holme
4d49ffe165 test906: Fixed failing test on some platforms
Bug: http://sourceforge.net/p/curl/bugs/1291
Reported-by: David Walser
2013-10-15 21:31:14 +01:00
Paul Donohue
f63603dec4 NSS: acknowledge the --no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option 2013-10-15 21:50:22 +02:00
Tyler Hall
0218a737fe ssh: Handle successful SSH_USERAUTH_NONE
According to the documentation for libssh2_userauth_list(), a NULL
return value is not necessarily an error. You must call
libssh2_userauth_authenticated() to determine if the SSH_USERAUTH_NONE
request was successful.

This fixes a segv when using sftp on a server that allows logins with an
empty password. When NULL was interpreted as an error, it would
free the session but not flag an error since the libssh2 errno would be
clear. This resulted in dereferencing a NULL session pointer.

Signed-off-by: Tyler Hall <tylerwhall@gmail.com>
2013-10-15 20:53:09 +02:00
Ishan SinghLevett
18ca0aa984 usercertinmem: fix memory leaks 2013-10-15 20:48:22 +02:00
Dave Reisner
c4e6c33b13 build: distribute and install libcurl.m4 by default 2013-10-15 20:43:39 +02:00
Dave Reisner
d774802eec tool: use XFERFUNCTION to save some casts 2013-10-15 20:42:05 +02:00
Alessandro Ghedini
69c0d3fbc8 curl.1: fix typo conjuction -> conjunction 2013-10-15 20:37:13 +02:00
Daniel Stenberg
076726f141 curl: document the new --tlsv1.[012] options 2013-10-15 20:31:04 +02:00
Gergely Nagy
ad34a2d5c8 SSL: protocol version can be specified more precisely
CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2 enum values are added to force exact TLS version
(CURL_SSLVERSION_TLSv1 means TLS 1.x).

axTLS:
axTLS only supports TLS 1.0 and 1.1 but it cannot be set that only one
of these should be used, so we don't allow the new enum values.

darwinssl:
Added support for the new enum values.

SChannel:
Added support for the new enum values.

CyaSSL:
Added support for the new enum values.
Bug: The original CURL_SSLVERSION_TLSv1 value enables only TLS 1.0 (it
did the same before this commit), because CyaSSL cannot be configured to
use TLS 1.0-1.2.

GSKit:
GSKit doesn't seem to support TLS 1.1 and TLS 1.2, so we do not allow
those values.
Bugfix: There was a typo that caused wrong SSL versions to be passed to
GSKit.

NSS:
TLS minor version cannot be set, so we don't allow the new enum values.

QsoSSL:
TLS minor version cannot be set, so we don't allow the new enum values.

OpenSSL:
Added support for the new enum values.
Bugfix: The original CURL_SSLVERSION_TLSv1 value enabled only TLS 1.0,
now it enables 1.0-1.2.

Command-line tool:
Added command line options for the new values.
2013-10-15 20:26:47 +02:00
Nick Zitzmann
31e106c01c darwinssl: un-break iOS build after PKCS#12 feature added
SecPKCS12Import() returns a few errors that are enumerated in OS X's
headers but not in iOS' headers for some reason.
2013-10-14 18:03:32 -05:00
Daniel Stenberg
1dcc433661 bump: start working on 7.33.1 2013-10-14 23:11:20 +02:00
Daniel Stenberg
a106abee62 THANKS: added contributors from the 7.33.0 announcement 2013-10-14 23:10:35 +02:00
175 changed files with 6496 additions and 2171 deletions

11
.travis.yml Normal file
View File

@@ -0,0 +1,11 @@
language: c
before_script:
- ./buildconf
compiler:
- clang
- gcc
notifications:
email: false

View File

@@ -108,7 +108,11 @@ if(NOT UNIX)
set(HAVE_IN_ADDR_T 0)
set(HAVE_INET_NTOA_R_DECL 0)
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
if(ENABLE_IPV6)
set(HAVE_GETADDRINFO 1)
else()
set(HAVE_GETADDRINFO 0)
endif()
set(STDC_HEADERS 1)
set(RETSIGTYPE_TEST 1)

View File

@@ -783,6 +783,17 @@ else()
set(CURL_SIZEOF_CURL_SOCKLEN_T ${SIZEOF_INT})
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)
add_definitions(-DHAVE_CONFIG_H)

View File

@@ -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
curl_easy_setopt() options: 205
curl_easy_setopt() options: 206
Public functions in libcurl: 58
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:
o test code for testing the event based API [3]
o CURLM_ADDED_ALREADY: new error code
o test TFTP server: support "writedelay" within <servercmd>
o krb4 support has been removed
o imap/pop3/smtp: added basic SASL XOAUTH2 support [9]
o darwinssl: add support for PKCS#12 files for client authentication
o darwinssl: enable BEAST workaround on iOS 7 & later
o Pass password to OpenSSL engine by user interface [15]
o c-ares: Add support for various DNS binding options
o cookies: add expiration
o curl: added --oauth2-bearer option
o SSL: protocol version can be specified more precisely [1]
o imap/pop3/smtp: Added graceful cancellation of SASL authentication
o Add "Happy Eyeballs" for IPv4/IPv6 dual connect attempts
o base64: Added validation of base64 input strings when decoding [8]
o curl_easy_setopt: Added the ability to set the login options separately
o smtp: Added support for additional SMTP commands
o curl_easy_getinfo: Added CURLINFO_TLS_SESSION for accessing TLS internals
o nss: allow to use TLS > 1.0 if built against recent NSS [18]
o SECURITY: added this document to describe our security processes [22]
o parseconfig: warn if unquoted white spaces are detected
This release includes the following bugfixes:
o nss: make sure that NSS is initialized
o curl: make --no-[option] work properly for several options
o FTP: with socket_action send better socket updates in active mode [1]
o curl: fix the --sasl-ir in the --help output
o tests 2032, 2033: Don't hardcode port in expected output
o urlglob: better detect unclosed braces, empty lists and overflows [7]
o urlglob: error out on range overflow [8]
o imap: Fixed response check for SEARCH, EXPUNGE, LSUB, UID and NOOP commands [10]
o handle arbitrary-length username and password [2]
o TFTP: make the CURLOPT_LOW_SPEED* options work [4]
o curl.h: name space pollution by "enum type" [5]
o multi: move on from STATE_DONE faster [6]
o FTP: 60 secs delay if aborted in the CURLOPT_HEADERFUNCTION callback [11]
o multi_socket: improved 100-continue timeout handling
o curl_multi_remove_handle: allow multiple removes
o FTP: fix getsock during DO_MORE state [12]
o -x: rephrased the --proxy section somewhat
o acinclude: fix --without-ca-path when cross-compiling [13]
o LDAP: fix bad free() when URL parsing failed [14]
o --data: mention CRLF treatment when reading from file
o curl_easy_pause: suggest one way to unpause
o imap: Fixed calculation of transfer when partial FETCH received [16]
o pingpong: Check SSL library buffers for already read data [16]
o imap/pop3/smtp: Speed up SSL connection initialization
o libcurl.3: for multi interface connections are held in the multi handle
o curl_easy_setopt.3: mention RTMP URL quirks [17]
o curl.1: detail how short/long options work [18]
o curl.1: Added information about optional login options to --user option
o curl: Added clarification to the --mail options in the --help output
o curl_easy_setopt.3: clarify that TIMEOUT and TIMEOUT_MS set the same value
o openssl: use correct port number in error message [19]
o darwinssl: block TLS_RSA_WITH_NULL_SHA256 cipher
o OpenSSL: acknowledge CURLOPT_SSL_VERIFYHOST without VERIFYPEER
o xattr: add support for FreeBSD xattr API
o win32: fix Visual Studio 2010 build with WINVER >= 0x600 [22]
o configure: use icc options without space [21]
o test1112: Increase the timeout from 7s to 16s [20]
o SCP: upload speed on a fast connection limited to 16384 B/s
o curl_setup_once: fix errno access for lwip on Windows [24]
o HTTP: Output http response 304 when modified time is too old [23]
o darwinssl: un-break iOS build after PKCS#12 feature added
o tool: use XFERFUNCTION to save some casts [2]
o usercertinmem: fix memory leaks
o ssh: Handle successful SSH_USERAUTH_NONE [3]
o NSS: acknowledge the --no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option [4]
o test906: Fixed failing test on some platforms [5]
o sasl: initialize NSS before using NTLM crypto
o sasl: Fixed memory leak in OAUTH2 message creation
o imap/pop3/smtp: Fixed QUIT / LOGOUT being sent when SSL connect fails
o cmake: unbreak for non-Windows platforms [6]
o ssh: initialize per-handle data in ssh_connect()
o glob: fix broken URLs
o configure: check for long long when building with cyassl
o CURLOPT_RESOLVE: mention they don't time-out [7]
o docs/examples/httpput.c: fix build for MSVC
o FTP: make the data connection work when going through proxy
o NSS: support for CERTINFO feature
o curl_multi_wait: accept 0 from multi_timeout() as valid timeout
o glob_range: pass the closing bracket for a-z ranges
o tool_help: Updated --list-only description to include POP3
o Curl_ssl_push_certinfo_len: don't %.*s non-zero-terminated string [9]
o cmake: fix Windows build with IPv6 support [10]
o ares: Fixed compilation under Visual Studio 2012 [11]
o curl_easy_setopt.3: clarify CURLOPT_SSL_VERIFYHOST documentation [12]
o curl.1: mention that -O does no URL decoding [13]
o darwinssl: PKCS#12 import feature now requires Lion or later [14]
o darwinssl: check for SSLSetSessionOption() presence when toggling BEAST
o configure: Fix test with -Werror=implicit-function-declaration [15]
o sigpipe: factor out sigpipe_reset from easy.c
o curl_multi_cleanup: ignore SIGPIPE
o globbing: curl glob counter mismatch with {} list use [16]
o parseconfig: dash options can't specified with colon or equals [17]
o digest: fix CURLAUTH_DIGEST_IE [19]
o curl.h: <sys/select.h> for OpenBSD [20]
o darwinssl: Fix #if 10.6.0 for SecKeychainSearch
o TFTP: fix return codes for connect timeout [21]
o login options: remove the ;[options] support from CURLOPT_USERPWD [23]
o imap: Fixed incorrect fallback to clear text authentication
o parsedate: avoid integer overflow
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:
@@ -71,41 +74,42 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Alex McLellan, Bill Doyle, Colby Ranger, Fabian Keil, Gisle Vanem,
John E. Malmberg, Jonathan Nieder, Kamil Dudka, Shawn Landden,
Tor Arntsen, Will Dietz, Yi Huang, Kyle L. Huff, Steve Holme, Mike Mio,
Stefan Neis, Nick Zitzmann, Geoff Beier, John Dunn, Jiri Hruska,
Tomas Mlcoch, Kim Vandry, Ben Greear, Gorilla Maguila, Jerry Krinock,
Yamada Yasuharu, Gordon Marler, Dave Thompson, D. Flinkmann,
Benoit Sigoure, Clemens Gruber, Guenter Knauf, Petr Pisar, Elmira A Semenova,
Francois Charlier, Ishan SinghLevett, Marcel Raad, Ulf Samuelsson,
Andrej E Baranov, Derek Higgins, Heinrich Schaefer
Alessandro Ghedini, Andreas Rieke, Björn Stenberg, Chris Conlon,
Christian Grothoff, Christian Weisgerber, Dave Reisner, David Walser,
Dima Tisnek, Fabian Keil, Felix Yan, Gergely Nagy, Gisle Vanem,
Ishan SinghLevett, James Dury, Javier Barroso, Jeff King, Kamil Dudka,
Kim Vandry, Marcin Gryszkalis, Melissa Mears, Michael Osipov, Nick Zitzmann,
Oliver Kuckertz, Patrick Monnerat, Paul Donohue, Paul Marks, Romulo A. Ceccon,
Rémy Léone, Sergey Tatarincev, Steve Holme, Tomas Hoger, Tyler Hall,
Yaakov Selkowitz, Eric Lubin, Petr Bahula, He Qin, Marc Deslauriers
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/mail/lib-2013-08/0043.html
[2] = http://bugs.debian.org/719856
[3] = http://daniel.haxx.se/blog/2013/08/20/testing-curl_multi_socket_action/
[4] = http://curl.haxx.se/bug/view.cgi?id=1269
[5] = https://github.com/bagder/curl/pull/76
[6] = http://curl.haxx.se/mail/lib-2013-08/0211.html
[7] = http://curl.haxx.se/bug/view.cgi?id=1264
[8] = http://curl.haxx.se/bug/view.cgi?id=1267
[9] = http://curl.haxx.se/mail/lib-2013-08/0234.html
[10] = http://curl.haxx.se/mail/lib-2013-08/0136.html
[11] = https://bugzilla.redhat.com/1005686
[12] = http://curl.haxx.se/mail/lib-2013-08/0109.html
[13] = http://curl.haxx.se/bug/view.cgi?id=1273
[14] = http://curl.haxx.se/mail/lib-2013-08/0209.html
[15] = http://curl.haxx.se/mail/lib-2013-08/0265.html
[16] = http://curl.haxx.se/mail/lib-2013-08/0170.html
[17] = http://curl.haxx.se/bug/view.cgi?id=1278
[18] = http://curl.haxx.se/bug/view.cgi?id=1279
[19] = http://curl.haxx.se/bug/view.cgi?id=1281
[20] = http://curl.haxx.se/mail/lib-2010-02/0200.html
[21] = http://curl.haxx.se/mail/lib-2013-09/0182.html
[22] = http://curl.haxx.se/bug/view.cgi?id=1282
[23] = http://curl.haxx.se/bug/view.cgi?id=1288
[24] = http://curl.haxx.se/mail/lib-2013-10/0048.html
[1] = https://github.com/bagder/curl/pull/79
[2] = http://curl.haxx.se/mail/lib-2013-10/0089.html
[3] = http://curl.haxx.se/mail/lib-2013-10/0096.html
[4] = http://curl.haxx.se/mail/lib-2013-10/0113.html
[5] = http://sourceforge.net/p/curl/bugs/1291
[6] = http://sourceforge.net/p/curl/bugs/1292
[7] = http://curl.haxx.se/mail/lib-2013-10/0062.html
[8] = http://curl.haxx.se/mail/lib-2013-10/0242.html
[9] = http://curl.haxx.se/bug/view.cgi?id=1295
[10] = http://sourceforge.net/p/curl/bugs/1064
[11] = http://curl.haxx.se/mail/lib-2013-11/0057.html
[12] = https://github.com/bagder/curl/pull/83
[13] = http://sourceforge.net/p/curl/bugs/1299
[14] = http://curl.haxx.se/mail/lib-2013-11/0076.html
[15] = http://curl.haxx.se/bug/view.cgi?id=1304
[16] = http://curl.haxx.se/bug/view.cgi?id=1305
[17] = http://curl.haxx.se/bug/view.cgi?id=1297
[18] = http://curl.haxx.se/mail/lib-2013-11/0162.html
[19] = http://curl.haxx.se/bug/view.cgi?id=1308
[20] = http://curl.haxx.se/mail/lib-2013-12/0017.html
[21] = http://curl.haxx.se/bug/view.cgi?id=1310
[22] = http://curl.haxx.se/dev/security.html
[23] = http://curl.haxx.se/bug/view.cgi?id=1311
[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

View File

@@ -1065,6 +1065,7 @@ AC_HELP_STRING([--disable-ipv6],[Disable ipv6 support]),
AC_TRY_RUN([ /* is AF_INET6 available? */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h> /* for exit() */
main()
{
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
AC_MSG_NOTICE([detected CyaSSL])
dnl cyassl/ctaocrypt/types.h needs SIZEOF_LONG_LONG defined!
AC_CHECK_SIZEOF(long long)
LIBS="-lcyassl -lm $LIBS"
if test -n "$cyassllib"; then
@@ -2067,8 +2071,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
CPPFLAGS="$CPPFLAGS $addcflags"
fi
dnl The function PK11_CreateGenericObject is needed to load libnsspem.so
AC_CHECK_LIB(nss3, PK11_CreateGenericObject,
dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
AC_CHECK_LIB(nss3, SSL_VersionRangeSet,
[
AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
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
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 linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail

View File

@@ -43,7 +43,7 @@ Portability
openldap 2.0
MIT krb5 lib 1.2.4
qsossl V5R3M0
NSS 3.12.x
NSS 3.14.x
axTLS 1.2.7
Heimdal ?

View File

@@ -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
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
backends, so relying on this information in a generic app is flaky.

View File

@@ -37,7 +37,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS SECURITY
MAN2HTML= roffit < $< >$@

91
docs/SECURITY Normal file
View 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

View File

@@ -27,6 +27,7 @@ Alessandro Vesely
Alex Bligh
Alex Fishman
Alex Gruz
Alex McLellan
Alex Neblett
Alex Suykov
Alex Vinnik
@@ -62,6 +63,7 @@ Andreas Schuldei
Andreas Wurf
Andrei Benea
Andrei Cipu
Andrej E Baranov
Andres Garcia
Andrew Benham
Andrew Biggs
@@ -109,9 +111,11 @@ Benbuck Nason
Benjamin Gerard
Benjamin Gilbert
Benjamin Johnson
Benoit Sigoure
Bernard Leak
Bernhard Reutner-Fischer
Bertrand Demiddelaer
Bill Doyle
Bill Egert
Bill Hoffman
Bill Middlecamp
@@ -154,6 +158,7 @@ Charles Kerr
Chih-Chung Chang
Chris "Bob Bob"
Chris Combes
Chris Conlon
Chris Conroy
Chris Deidun
Chris Flerackers
@@ -181,6 +186,7 @@ Clarence Gardner
Clemens Gruber
Clifford Wolf
Cody Jones
Colby Ranger
Colin Hogben
Colin Watson
Colm Buckley
@@ -194,6 +200,7 @@ Cristian Rodríguez
Curt Bogmine
Cyrill Osterwalder
Cédric Deltheil
D. Flinkmann
Dag Ekengren
Dagobert Michelsen
Damien Adant
@@ -221,6 +228,7 @@ Dave Halbakken
Dave Hamilton
Dave May
Dave Reisner
Dave Thompson
Dave Vasilevsky
David Bau
David Binderman
@@ -244,13 +252,16 @@ David Shaw
David Strauss
David Tarendash
David Thiel
David Walser
David Wright
David Yan
Dengminwen
Derek Higgins
Detlef Schmier
Didier Brisebourg
Diego Casorran
Dima Barsky
Dima Tisnek
Dimitre Dimitrov
Dimitris Sarris
Dinar
@@ -289,6 +300,7 @@ Eelco Dolstra
Eetu Ojanen
Eldar Zaitov
Ellis Pritchard
Elmira A Semenova
Emanuele Bovisio
Emil Romanus
Emiliano Ida
@@ -298,6 +310,7 @@ Eric Cooper
Eric Hu
Eric Landes
Eric Lavigne
Eric Lubin
Eric Melville
Eric Mertens
Eric Rautman
@@ -318,10 +331,12 @@ Fabian Hiernaux
Fabian Keil
Fabrizio Ammollo
Fedor Karpelevitch
Felix Yan
Felix von Leitner
Feng Tu
Florian Schoppmann
Forrest Cahoon
Francois Charlier
Frank Hempel
Frank Keeney
Frank McGeough
@@ -342,11 +357,13 @@ Gautam Kachroo
Gautam Mani
Gavrie Philipson
Gaz Iqbal
Geoff Beier
Georg Horn
Georg Huettenegger
Georg Lippitsch
Georg Wicherski
Gerd v. Egidy
Gergely Nagy
Gerhard Herre
Gerrit Bruchhäuser
Ghennadi Procopciuc
@@ -362,6 +379,8 @@ Giuseppe D'Ambrosio
Glen Nakamura
Glen Scott
Gokhan Sengun
Gordon Marler
Gorilla Maguila
Grant Erickson
Greg Hewgill
Greg Morse
@@ -384,8 +403,10 @@ Hans-Jurgen May
Hardeep Singh
Harshal Pradhan
Hauke Duden
He Qin
Heikki Korpela
Heinrich Ko
Heinrich Schaefer
Hendrik Visage
Henrik Storner
Henry Ludemann
@@ -422,6 +443,7 @@ James Bursa
James Cheng
James Clancy
James Cone
James Dury
James Gallagher
James Griffiths
James Housley
@@ -441,6 +463,7 @@ Jason Glasgow
Jason Liu
Jason McDonald
Jason S. Priebe
Javier Barroso
Jay Austin
Jayesh A Shah
Jaz Fresh
@@ -453,6 +476,7 @@ Jean-Noel Rouvignac
Jean-Philippe Barrette-LaPierre
Jeff Connelly
Jeff Johnson
Jeff King
Jeff Lawson
Jeff Phillips
Jeff Pohlmeyer
@@ -462,6 +486,7 @@ Jeremy Friesner
Jeremy Huddleston
Jerome Muffat-Meridol
Jerome Vouillon
Jerry Krinock
Jerry Wu
Jes Badwal
Jesper Jensen
@@ -486,6 +511,7 @@ Johannes Bauer
John Bradshaw
John Crow
John Dennis
John Dunn
John E. Malmberg
John Gardiner Myers
John Janssen
@@ -569,6 +595,7 @@ Krishnendu Majumdar
Krister Johansen
Kristian Gunstone
Kristian Köhntopp
Kyle L. Huff
Kyle Sallee
Lachlan O'Dea
Larry Campbell
@@ -611,6 +638,7 @@ Mandy Wu
Manfred Schwarb
Manuel Massing
Marc Boucher
Marc Deslauriers
Marc Doughty
Marc Hoersken
Marc Kleine-Budde
@@ -618,6 +646,7 @@ Marcel Raad
Marcel Roelofs
Marcelo Juchem
Marcin Adamski
Marcin Gryszkalis
Marcin Konicki
Marco G. Salvagno
Marco Maggi
@@ -672,6 +701,7 @@ Maxim Prohorov
Maxime Larocque
Mehmet Bozkurt
Mekonikum
Melissa Mears
Mettgut Jamalla
Michael Benedict
Michael Calmer
@@ -683,6 +713,7 @@ Michael Jahn
Michael Jerris
Michael Mealling
Michael Mueller
Michael Osipov
Michael Smith
Michael Stillwell
Michael Wallner
@@ -700,6 +731,7 @@ Mike Crowe
Mike Dobbs
Mike Giancola
Mike Hommey
Mike Mio
Mike Power
Mike Protts
Mike Revi
@@ -744,6 +776,7 @@ Olaf Flebbe
Olaf Stueben
Olaf Stüben
Oliver Gondža
Oliver Kuckertz
Olivier Berger
Oren Tirosh
Ori Avtalion
@@ -762,8 +795,10 @@ Patrick Scott
Patrick Smith
Patrik Thunstrom
Pau Garcia i Quiles
Paul Donohue
Paul Harrington
Paul Howarth
Paul Marks
Paul Marquis
Paul Moore
Paul Nolan
@@ -792,6 +827,8 @@ Peter Todd
Peter Verhas
Peter Wullinger
Peteris Krumins
Petr Bahula
Petr Pisar
Phil Blundell
Phil Karn
Phil Lisiecki
@@ -875,6 +912,7 @@ Roland Zimmermann
Rolland Dudemaine
Roman Koifman
Roman Mamedov
Romulo A. Ceccon
Ron Zapp
Rosimildo da Silva
Roy Shan
@@ -884,6 +922,7 @@ Rutger Hofman
Ryan Chan
Ryan Nelson
Ryan Schmidt
Rémy Léone
S. Moonesamy
Salvador Dávila
Salvatore Sorrentino
@@ -909,11 +948,13 @@ Sebastian Rasmussen
Sebastien Willemijns
Senthil Raja Velu
Sergei Nikulov
Sergey Tatarincev
Sergio Ballestrero
Seshubabu Pasam
Sh Diao
Sharad Gupta
Shard
Shawn Landden
Shawn Poulson
Shmulik Regev
Siddhartha Prakash Jain
@@ -997,6 +1038,7 @@ Tom Mueller
Tom Regner
Tom Wright
Tom Zerucha
Tomas Hoger
Tomas Mlcoch
Tomas Pospisek
Tomas Szepe
@@ -1014,7 +1056,9 @@ Traian Nicolescu
Troels Walsted Hansen
Troy Engel
Tupone Alfredo
Tyler Hall
Ulf Härnhammar
Ulf Samuelsson
Ulrich Doehner
Ulrich Zadow
Venkat Akella
@@ -1041,15 +1085,18 @@ Wesley Laxton
Wesley Miaw
Wez Furlong
Wilfredo Sanchez
Will Dietz
Willem Sparreboom
Wojciech Zwiefka
Wouter Van Rooy
Wu Yongzheng
Xavier Bouchoux
Yaakov Selkowitz
Yamada Yasuharu
Yang Tse
Yarram Sunil
Yehoshua Hershberg
Yi Huang
Yukihiro Kawada
Yuriy Sosov
Yves Arrouye

View File

@@ -16,8 +16,7 @@
1.3 struct lifreq
1.4 signal-based resolver timeouts
1.5 get rid of PATH_MAX
1.6 Happy Eyeball dual stack connect
1.7 Modified buffer size approach
1.6 Modified buffer size approach
2. libcurl - multi interface
2.1 More non-blocking
@@ -39,6 +38,7 @@
5.2 support FF3 sqlite cookie files
5.3 Rearrange request header order
5.4 HTTP2/SPDY
5.5 auth= in URLs
6. TELNET
6.1 ditch stdin
@@ -48,17 +48,14 @@
7. SMTP
7.1 Pipelining
7.2 Graceful base64 decoding failure
7.3 Enhanced capability support
7.2 Enhanced capability support
8. POP3
8.1 Pipelining
8.2 Graceful base64 decoding failure
8.3 Enhanced capability support
8.2 Enhanced capability support
9. IMAP
9.1 Graceful base64 decoding failure
9.2 Enhanced capability support
9.1 Enhanced capability support
10. LDAP
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
its current API (as of libssh2 1.2.7) doesn't.
1.6 Happy Eyeball dual stack connect
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
1.6 Modified buffer size approach
Current libcurl allocates a fixed 16K size buffer for download and an
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
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
@@ -331,14 +327,7 @@ to provide the data to send.
Add support for pipelining emails.
7.2 Graceful base64 decoding failure
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
7.2 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the EHLO command.
@@ -349,28 +338,14 @@ to provide the data to send.
Add support for pipelining commands.
8.2 Graceful base64 decoding failure
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
8.2 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPA command.
9. IMAP
9.1 Graceful base64 decoding failure
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
9.1 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPABILITY command.

View File

@@ -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
contents but they should be encoded according to the URI standard.
.IP "-G, --get"
When used, this option will make all data specified with \fI-d, --data\fP or
\fI--data-binary\fP to be used in an HTTP GET request instead of the POST
request that otherwise would be used. The data will be appended to the URL
with a '?' separator.
When used, this option will make all data specified with \fI-d, --data\fP,
\fI--data-binary\fP or \fI--data-urlencode\fP to be used in an HTTP GET
request instead of the POST request that otherwise would be used. The data
will be appended to the URL with a '?' separator.
If used in combination with -I, the POST data will instead be appended to the
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
server-specified Content-Disposition filename instead of extracting a filename
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"
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
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>"
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
used as if they were written on the actual command line. Options and their
parameters must be specified on the same config file line, separated by
whitespace, colon, the equals sign or any combination thereof (however,
the preferred separator is the equals sign). 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.
used as if they were written on the actual command line.
Options and their parameters must be specified on the same config file line,
separated by whitespace, colon, or the equals sign. Long option names can
optionally be given in the config file without the initial double dashes and
if so, the colon or equals characters can be used as separators. If the option
is specified with one or two dashes, there can be no colon or equals character
between the option and its parameter.
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
stdin.
@@ -742,9 +750,6 @@ line. So, it could look similar to this:
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
config file and uses it if found. The default config file is checked for in
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.
.IP "-l, --list-only"
(FTP)
When listing an FTP directory, this switch forces a name-only view.
Especially useful if you want to machine-parse the contents of an FTP
directory since the normal directory view doesn't use a standard look
or format.
When listing an FTP directory, this switch forces a name-only view. This is
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 or
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
list only files in their response to NLST; they do not include
subdirectories and symbolic links.
Note: Some FTP servers list only files in their response to NLST; they do not
include sub-directories 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"
(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),
@@ -894,10 +907,18 @@ return with exit code 63.
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.
.IP "--mail-rcpt <address>"
(SMTP) Specify a single address that the given mail should get sent to. This
option can be used multiple times to specify many recipients.
(SMTP) Specify a single address, user name or mailing list name.
(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>"
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
@@ -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
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.
.IP "--oauth2-bearer"
(IMAP/POP3/SMTP) Specify the Bearer Token for OAUTH 2.0 server authentication.
The Bearer Token is used in conjuction with the user name which can be
specified as part of the \fI--url\fP or \fI-u, --user\fP options.
(IMAP, POP3, SMTP)
Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token
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.
@@ -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
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
(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>"
Set password for use with the TLS authentication method specified with
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (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 "--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"
(HTTP) Request a compressed Transfer-Encoding response using one of the
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
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"
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
@@ -2055,6 +2101,8 @@ RTSP: mismatch of Session Identifiers
unable to parse FTP file list
.IP 88
FTP chunk callback reported error
.IP 89
No connection available, the session will be queued
.IP XX
More error codes will appear here in future releases. The existing ones
are meant to never change.

View File

@@ -13,4 +13,4 @@ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
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

View File

@@ -22,8 +22,6 @@
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <curl/curl.h>
/*
@@ -59,7 +57,6 @@ int main(int argc, char **argv)
CURL *curl;
CURLcode res;
FILE * hd_src ;
int hd ;
struct stat file_info;
char *file;
@@ -72,9 +69,7 @@ int main(int argc, char **argv)
url = argv[2];
/* get the file size of the local file */
hd = open(file, O_RDONLY) ;
fstat(hd, &file_info);
close(hd) ;
stat(file, &file_info);
/* get a FILE * of the same file, could also be made with
fdopen() from the previous descriptor, but hey this is just

105
docs/examples/sessioninfo.c Normal file
View 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;
}

View File

@@ -22,8 +22,9 @@
/* Example using an in memory PEM user certificate and RSA key to retrieve an
* https page.
* 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
* if you want a properly secure connection
* Note that to maintain simplicity this example does not use a CA certificate
* 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>
@@ -152,6 +153,18 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
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 */
return CURLE_OK ;

View File

@@ -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_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
m4macrodir = $(datadir)/aclocal
dist_m4macro_DATA = libcurl.m4
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
MAN2HTML= roffit --mandir=. < $< >$@

View File

@@ -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
.\" * 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
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
option is only available in libcurl built with OpenSSL support. (Added in
7.19.1)
option is only available in libcurl built with OpenSSL, NSS, GSKit or QsoSSL
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
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

View File

@@ -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)
.IP CURLOPT_USERPWD
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
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
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
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
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.
.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)
CURLOPT_USERPWD option.
In order to specify the password to be used in conjunction with the user name
use the \fICURLOPT_PASSWORD\fP option. (Added in 7.19.1)
To specify the password and login options, along with the user name, use the
\fICURLOPT_PASSWORD\fP and \fICURLOPT_LOGIN_OPTIONS\fP options. (Added in
7.19.1)
.IP CURLOPT_PASSWORD
Pass a char * as parameter, which should be pointing to the zero terminated
password to use for the transfer.
The CURLOPT_PASSWORD option should be used in conjunction with
the \fICURLOPT_USERNAME\fP option. (Added in 7.19.1)
The CURLOPT_PASSWORD option should be used in conjunction with the
\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
Pass a char * as parameter, which should be pointing to the zero terminated
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
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 (<>),
however, should you not use an angled bracket as the first character libcurl
will assume you provided a single email address and enclose that address
within brackets for you.
When performing a mail transfer, each recipient should be specified within a
pair of angled brackets (<>), however, should you not use an angled bracket as
the first character libcurl will assume you provided a single email address and
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
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
@@ -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
you want the transfer to start from. (Added in 7.11.0)
.IP CURLOPT_CUSTOMREQUEST
Pass a pointer to a zero terminated string as parameter. It can be used to
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.
Pass a pointer to a zero terminated string as parameter.
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
to the particular request method, it will only change the actual string sent
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:
With the HTTP protocol when you tell libcurl to do a HEAD request, but then
specify a GET though a custom request libcurl will still act as if it sent a
HEAD. To switch to a proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a
proper POST use \fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch
to a proper GET use CURLOPT_HTTPGET.
When you tell libcurl to do a HEAD request, but then specify a GET though a
custom request libcurl will still act as if it sent a HEAD. To switch to a
proper HEAD use \fICURLOPT_NOBODY\fP, to switch to a proper POST use
\fICURLOPT_POST\fP or \fICURLOPT_POSTFIELDS\fP and to switch to a proper GET
use CURLOPT_HTTPGET.
With the POP3 protocol 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.
Restore to the internal default by setting this to NULL.
Please don't perform this at will, on HTTP based requests, by making sure
your server supports the command you are sending first.
Many people have wrongly used this option to replace the entire request with
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
\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
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
@@ -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
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
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
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
(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)
.IP CURLOPT_SSLKEY
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.
.IP CURLOPT_SSLVERSION
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:
.RS
.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
by default with 7.18.1).
.IP CURL_SSLVERSION_TLSv1
Force TLSv1
Force TLSv1.x
.IP CURL_SSLVERSION_SSLv2
Force SSLv2
.IP CURL_SSLVERSION_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
.IP CURLOPT_SSL_VERIFYPEER
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
URL to which you told Curl to connect.
When the value is 1, libcurl will return a failure. It was previously (in
7.28.0 and earlier) a debug option of some sorts, but it is no longer
supported due to frequently leading to programmer mistakes.
When the value is 1, \fIcurl_easy_setopt\fP will return an error and the option
value will not be changed. It was previously (in 7.28.0 and earlier) a debug
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
certificate.
@@ -2534,14 +2591,14 @@ The default value for this option is 2.
This option controls checking the server's certificate's claimed identity.
The server could be lying. To control lying, see
\fICURLOPT_SSL_VERIFYPEER\fP. If libcurl is built against NSS and
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP
is ignored.
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_SSL_VERIFYHOST\fP is also set
to zero and cannot be overridden.
.IP CURLOPT_CERTINFO
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
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
7.19.1)
.IP CURLOPT_RANDOM_FILE

View File

@@ -250,6 +250,7 @@ CURLINFO_SSL_VERIFYRESULT 7.5
CURLINFO_STARTTRANSFER_TIME 7.9.2
CURLINFO_STRING 7.4.1
CURLINFO_TEXT 7.9.6
CURLINFO_TLS_SESSION 7.34.0
CURLINFO_TOTAL_TIME 7.4.1
CURLINFO_TYPEMASK 7.4.1
CURLIOCMD_NOP 7.12.3
@@ -394,6 +395,7 @@ CURLOPT_KRB4LEVEL 7.3 7.17.0
CURLOPT_KRBLEVEL 7.16.4
CURLOPT_LOCALPORT 7.15.2
CURLOPT_LOCALPORTRANGE 7.15.2
CURLOPT_LOGIN_OPTIONS 7.34.0
CURLOPT_LOW_SPEED_LIMIT 7.1
CURLOPT_LOW_SPEED_TIME 7.1
CURLOPT_MAIL_AUTH 7.25.0
@@ -593,6 +595,16 @@ CURLSSH_AUTH_KEYBOARD 7.16.1
CURLSSH_AUTH_NONE 7.16.1
CURLSSH_AUTH_PASSWORD 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
CURLUSESSL_ALL 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_SSLv3 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_IFUNMODSINCE 7.9.7
CURL_TIMECOND_LASTMOD 7.9.7

View File

@@ -69,7 +69,7 @@
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
defined(ANDROID) || defined(__ANDROID__) || \
defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
#include <sys/select.h>
#endif
@@ -827,10 +827,10 @@ typedef enum {
/* Name of proxy to use. */
CINIT(PROXY, OBJECTPOINT, 4),
/* "name:password" to use when fetching. */
/* "user:password;options" to use when fetching. */
CINIT(USERPWD, OBJECTPOINT, 5),
/* "name:password" to use with proxy. */
/* "user:password" to use with proxy. */
CINIT(PROXYUSERPWD, OBJECTPOINT, 6),
/* Range to get, specified as an ASCII string. */
@@ -1388,8 +1388,7 @@ typedef enum {
CINIT(ADDRESS_SCOPE, LONG, 171),
/* Collect certificate chain info and allow it to get retrievable with
CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only
working with OpenSSL-powered builds. */
CURLINFO_CERTINFO after the transfer is complete. */
CINIT(CERTINFO, LONG, 172),
/* "name" and "pwd" to use when fetching. */
@@ -1569,6 +1568,9 @@ typedef enum {
* Only supported by the c-ares DNS backend */
CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),
/* Set authentication options directly */
CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
@@ -1659,9 +1661,12 @@ enum CURL_NETRC_OPTION {
enum {
CURL_SSLVERSION_DEFAULT,
CURL_SSLVERSION_TLSv1,
CURL_SSLVERSION_TLSv1, /* TLS 1.x */
CURL_SSLVERSION_SSLv2,
CURL_SSLVERSION_SSLv3,
CURL_SSLVERSION_TLSv1_0,
CURL_SSLVERSION_TLSv1_1,
CURL_SSLVERSION_TLSv1_2,
CURL_SSLVERSION_LAST /* never use, keep last */
};
@@ -1980,6 +1985,28 @@ struct curl_certinfo {
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_LONG 0x200000
#define CURLINFO_DOUBLE 0x300000
@@ -2031,9 +2058,10 @@ typedef enum {
CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40,
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
/* Fill in new entries below here! */
CURLINFO_LASTONE = 42
CURLINFO_LASTONE = 43
} CURLINFO;
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as

View File

@@ -71,6 +71,7 @@
#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_OFF_T
#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
@@ -110,71 +111,87 @@
/* 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 */
/* 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
# include <sys/types.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* 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
# include <stdint.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* 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
# include <inttypes.h>
#endif
/* The size of `long', as computed by sizeof. */
#cmakedefine CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG}
/* Integral data type used for curl_socklen_t. */
#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
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/socket.h must be included by the external interface. */
#cmakedefine CURL_PULL_SYS_SOCKET_H
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#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. */
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. */
#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. */
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
/* 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. */
#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. */
#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. */
#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. */
#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. */
#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 */

View File

@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
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
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 33
#define LIBCURL_VERSION_MINOR 34
#define LIBCURL_VERSION_PATCH 0
/* 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
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

View File

@@ -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
* 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_LOCAL_IP4 || \
(option) == CURLOPT_DNS_LOCAL_IP6 || \
(option) == CURLOPT_LOGIN_OPTIONS || \
0)
/* evaluates to true if option takes a curl_write_callback argument */

View File

@@ -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_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 \
http2.h
http2.h sigpipe.h

View File

@@ -645,10 +645,10 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
const char *local_ip4)
{
#if (ARES_VERSION >= 0x010704)
uint32_t a4;
struct in_addr a4;
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 {
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;
#else /* c-ares version too old! */

View File

@@ -164,7 +164,8 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_TLSv1:
break;
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;
}

View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -40,29 +40,45 @@
static const char table64[]=
"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;
unsigned long i, v, x = 0;
for(i = 0, s = src; i < 4; i++, s++) {
v = 0;
if(*s == '=') {
x = (x << 6);
padding++;
}
else {
p = table64;
while(*p && (*p != *s)) {
v++;
p++;
}
if(*p == *s)
x = (x << 6) + v;
else if(*s == '=')
x = (x << 6);
else
return 0;
}
}
if(padding < 1)
dest[2] = curlx_ultouc(x & 0xFFUL);
x >>= 8;
if(padding < 2)
dest[1] = curlx_ultouc(x & 0xFFUL);
x >>= 8;
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,
unsigned char **outptr, size_t *outlen)
{
size_t srclen = 0;
size_t length = 0;
size_t equalsTerm = 0;
size_t padding = 0;
size_t i;
size_t result;
size_t numQuantums;
unsigned char lastQuantum[3];
size_t rawlen = 0;
unsigned char *pos;
unsigned char *newstr;
*outptr = NULL;
*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])
length++;
/* A maximum of two = padding characters is allowed */
if(src[length] == '=') {
equalsTerm++;
if(src[length+equalsTerm] == '=')
equalsTerm++;
padding++;
if(src[length + 1] == '=')
padding++;
}
numQuantums = (length + equalsTerm) / 4;
/* Don't allocate a buffer if the decoded length is 0 */
if(numQuantums == 0)
return CURLE_OK;
/* Check the = padding characters weren't part way through the input */
if(length + padding != srclen)
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
(which may be partially thrown out) and the zero terminator. */
newstr = malloc(rawlen+4);
/* Calculate the size of the decoded string */
rawlen = (numQuantums * 3) - padding;
/* Allocate our buffer including room for a zero terminator */
newstr = malloc(rawlen + 1);
if(!newstr)
return CURLE_OUT_OF_MEMORY;
*outptr = newstr;
pos = newstr;
/* Decode all but the last quantum (which may not decode to a
multiple of 3 bytes) */
for(i = 0; i < numQuantums - 1; i++) {
decodeQuantum(newstr, src);
newstr += 3; src += 4;
/* Decode the quantums */
for(i = 0; i < numQuantums; i++) {
result = decodeQuantum(pos, src);
if(!result) {
Curl_safefree(newstr);
return CURLE_BAD_CONTENT_ENCODING;
}
/* This final decode may actually read slightly past the end of the buffer
if the input string is missing pad bytes. This will almost always be
harmless. */
decodeQuantum(lastQuantum, src);
for(i = 0; i < 3 - equalsTerm; i++)
newstr[i] = lastQuantum[i];
pos += result;
src += 4;
}
newstr[i] = '\0'; /* zero terminate */
/* Zero terminate */
*pos = '\0';
*outlen = rawlen; /* return size of decoded data */
/* Return the decoded data */
*outptr = newstr;
*outlen = rawlen;
return CURLE_OK;
}

View File

@@ -529,10 +529,10 @@
#define SEND_TYPE_RETV int
/* Define to use the QsoSSL package. */
#define USE_QSOSSL
#undef USE_QSOSSL
/* Define to use the GSKit package. */
#undef USE_GSKIT
#define USE_GSKIT
/* Use the system keyring as the default CA bundle. */
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"

View File

@@ -164,8 +164,7 @@ tcpkeepalive(struct SessionHandle *data,
static CURLcode
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai, /* start connecting to this */
curl_socket_t *sock,
bool *connected);
curl_socket_t *sock);
/*
* Curl_timeleft() returns the amount of milliseconds left allowed for the
@@ -233,45 +232,6 @@ long Curl_timeleft(struct SessionHandle *data,
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,
curl_socket_t sockfd, int af)
{
@@ -573,42 +533,53 @@ static bool verifyconnect(curl_socket_t sockfd, int *error)
more address exists or error */
static CURLcode trynextip(struct connectdata *conn,
int sockindex,
bool *connected)
int tempindex)
{
curl_socket_t sockfd;
Curl_addrinfo *ai;
CURLcode rc = CURLE_COULDNT_CONNECT;
/* First clean up after the failed socket.
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
interface is used with certain select() replacements such as kqueue. */
curl_socket_t fd_to_close = conn->sock[sockindex];
conn->sock[sockindex] = CURL_SOCKET_BAD;
*connected = FALSE;
curl_socket_t fd_to_close = conn->tempsock[tempindex];
conn->tempsock[tempindex] = CURL_SOCKET_BAD;
if(sockindex != FIRSTSOCKET) {
Curl_closesocket(conn, fd_to_close);
return CURLE_COULDNT_CONNECT; /* no next */
if(sockindex == FIRSTSOCKET) {
Curl_addrinfo *ai;
int family;
if(conn->tempaddr[tempindex]) {
/* find next address in the same protocol family */
family = conn->tempaddr[tempindex]->ai_family;
ai = conn->tempaddr[tempindex]->ai_next;
}
else {
/* happy eyeballs - try the other protocol family */
int firstfamily = conn->tempaddr[0]->ai_family;
family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
ai = conn->tempaddr[0]->ai_next;
}
/* try the next address */
ai = conn->ip_addr->ai_next;
while(ai) {
CURLcode res = singleipconnect(conn, ai, &sockfd, connected);
if(res)
return res;
if(sockfd != CURL_SOCKET_BAD) {
/* store the new socket descriptor */
conn->sock[sockindex] = sockfd;
conn->ip_addr = ai;
Curl_closesocket(conn, fd_to_close);
return CURLE_OK;
}
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;
}
}
if(fd_to_close != CURL_SOCKET_BAD)
Curl_closesocket(conn, fd_to_close);
return CURLE_COULDNT_CONNECT;
return rc;
}
/* 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));
return;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
if(!getaddressinfo((struct sockaddr*)&ssloc,
conn->local_ip, &conn->local_port)) {
@@ -732,11 +704,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
{
struct SessionHandle *data = conn->data;
CURLcode code = CURLE_OK;
curl_socket_t sockfd = conn->sock[sockindex];
long allow = DEFAULT_CONNECT_TIMEOUT;
long allow;
int error = 0;
struct timeval now;
enum chkconn_t chk;
int result;
int i;
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
@@ -759,25 +731,51 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OPERATION_TIMEDOUT;
}
for(i=0; i<2; i++) {
if(conn->tempsock[i] == CURL_SOCKET_BAD)
continue;
#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(conn->tempsock[i], NULL);
#endif
/* check socket for connect */
chk = checkconnect(sockfd);
if(CHKCONN_IDLE == chk) {
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);
goto next;
error = ETIMEDOUT;
}
/* not an error, but also no connection yet */
return code;
/* 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);
}
if(CHKCONN_CONNECTED == chk) {
if(verifyconnect(sockfd, &error)) {
}
else if(result == CURL_CSELECT_OUT) {
if(verifyconnect(conn->tempsock[i], &error)) {
/* we are connected with TCP, awesome! */
int other = i ^ 1;
/* use this socket from now on */
conn->sock[sockindex] = conn->tempsock[i];
conn->ip_addr = conn->tempaddr[i];
conn->tempsock[i] = CURL_SOCKET_BAD;
/* close the other socket, if open */
if(conn->tempsock[other] != CURL_SOCKET_BAD) {
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 */
code = Curl_connected_proxy(conn);
code = Curl_connected_proxy(conn, sockindex);
if(code)
return code;
@@ -786,42 +784,51 @@ CURLcode Curl_is_connected(struct connectdata *conn,
*connected = TRUE;
if(sockindex == FIRSTSOCKET)
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
Curl_updateconninfo(conn, conn->sock[sockindex]);
Curl_verboseconnect(conn);
Curl_updateconninfo(conn, sockfd);
return CURLE_OK;
}
/* nope, not connected for real */
}
else {
/* nope, not connected */
if(CHKCONN_FDSET_ERROR == chk) {
(void)verifyconnect(sockfd, &error);
infof(data, "%s\n",Curl_strerror(conn, error));
}
else
infof(data, "Connection failed\n");
}
else if(result & CURL_CSELECT_ERR)
(void)verifyconnect(conn->tempsock[i], &error);
/*
* 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) {
char ipaddress[MAX_IPADR_LEN];
data->state.os_errno = error;
SET_SOCKERRNO(error);
}
next:
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->ip_addr->ai_next == NULL ?
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
allow : allow / 2;
code = trynextip(conn, sockindex, connected);
code = trynextip(conn, sockindex, i);
}
}
if(code) {
error = SOCKERRNO;
data->state.os_errno = error;
failf(data, "Failed connect to %s:%ld; %s",
conn->host.name, conn->port, Curl_strerror(conn, error));
/* no more addresses to try */
/* if the first address family runs out of addresses to try before
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;
@@ -938,8 +945,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
static CURLcode
singleipconnect(struct connectdata *conn,
const Curl_addrinfo *ai,
curl_socket_t *sockp,
bool *connected)
curl_socket_t *sockp)
{
struct Curl_sockaddr_ex addr;
int rc;
@@ -948,9 +954,10 @@ singleipconnect(struct connectdata *conn,
struct SessionHandle *data = conn->data;
curl_socket_t sockfd;
CURLcode res = CURLE_OK;
char ipaddress[MAX_IPADR_LEN];
long port;
*sockp = CURL_SOCKET_BAD;
*connected = FALSE; /* default is not connected */
res = Curl_socket(conn, ai, &addr, &sockfd);
if(res)
@@ -961,7 +968,7 @@ singleipconnect(struct connectdata *conn,
/* store remote address and port used in this connection attempt */
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 */
error = ERRNO;
failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
@@ -969,10 +976,7 @@ singleipconnect(struct connectdata *conn,
Curl_closesocket(conn, sockfd);
return CURLE_OK;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
infof(data, " Trying %s...\n", conn->ip_addr_str);
Curl_persistconninfo(conn);
infof(data, " Trying %s...\n", ipaddress);
if(data->set.tcp_nodelay)
tcpnodelay(conn, sockfd);
@@ -1045,25 +1049,25 @@ singleipconnect(struct connectdata *conn,
case EAGAIN:
#endif
#endif
*sockp = sockfd;
return CURLE_OK;
res = CURLE_OK;
break;
default:
/* unknown error, fallthrough and try another address! */
failf(data, "Failed to connect to %s: %s",
conn->ip_addr_str, Curl_strerror(conn,error));
infof(data, "Immediate connect fail for %s: %s\n",
ipaddress, Curl_strerror(conn,error));
data->state.os_errno = error;
/* connect failed */
Curl_closesocket(conn, sockfd);
res = CURLE_COULDNT_CONNECT;
}
}
break;
}
}
else
if(!res)
*sockp = sockfd;
return CURLE_OK;
return res;
}
/*
@@ -1073,29 +1077,13 @@ singleipconnect(struct connectdata *conn,
*/
CURLcode Curl_connecthost(struct connectdata *conn, /* context */
const struct Curl_dns_entry *remotehost,
curl_socket_t *sockconn, /* the connected socket */
Curl_addrinfo **addr, /* the one we used */
bool *connected) /* really connected? */
const struct Curl_dns_entry *remotehost)
{
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();
CURLcode res;
/*************************************************************
* 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);
long timeout_ms = Curl_timeleft(data, &before, TRUE);
if(timeout_ms < 0) {
/* a precaution, no need to continue if time already is up */
@@ -1104,58 +1092,28 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
}
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
* know for the given host. One by one until one IP succeeds.
*/
/* start connecting to first IP */
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);
/*
* Connecting with a Curl_addrinfo chain
*/
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)
if(conn->tempsock[0] == CURL_SOCKET_BAD)
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 */
return CURLE_OK;

View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -31,11 +31,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
bool *connected);
CURLcode Curl_connecthost(struct connectdata *conn,
const struct Curl_dns_entry *host, /* connect to
this */
curl_socket_t *sockconn, /* not set if error */
Curl_addrinfo **addr, /* the one we used */
bool *connected); /* truly connected? */
const struct Curl_dns_entry *host);
/* generic function that returns how much time there's left to run, according
to the timeouts set */
@@ -44,6 +40,8 @@ long Curl_timeleft(struct SessionHandle *data,
bool duringconnect);
#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

View File

@@ -834,7 +834,7 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
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
deprecation warnings, so let's not compile this unless it's necessary: */
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
@@ -874,7 +874,7 @@ static OSStatus CopyIdentityWithLabelOldSchool(char *label,
CFRelease(search);
return status;
}
#endif /* CURL_SUPPORT_MAC_10_7 */
#endif /* CURL_SUPPORT_MAC_10_6 */
static OSStatus CopyIdentityWithLabel(char *label,
SecIdentityRef *out_cert_and_key)
@@ -914,12 +914,12 @@ static OSStatus CopyIdentityWithLabel(char *label,
CFRelease(query_dict);
}
else {
#if CURL_SUPPORT_MAC_10_7
#if CURL_SUPPORT_MAC_10_6
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#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
to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
@@ -938,8 +938,10 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
cPassword, kCFStringEncodingUTF8) : NULL;
CFDataRef pkcs_data = NULL;
/* We can import P12 files on iOS or OS X 10.6 or later: */
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* We can import P12 files on iOS or OS X 10.7 or later: */
/* 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,
NULL, NULL, &status)) {
const void *cKeys[] = {kSecImportExportPassphrase};
@@ -963,7 +965,7 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
CFRelease(options);
CFRelease(pkcs_data);
}
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
if(password)
CFRelease(password);
CFRelease(pkcs_url);
@@ -1056,6 +1058,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
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:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
@@ -1100,6 +1114,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
kTLSProtocol12,
true);
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:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol3,
@@ -1130,10 +1159,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kTLSProtocol1,
true);
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:
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
@@ -1216,16 +1252,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
switch(err) {
case errSecPkcs12VerifyFailure: case errSecAuthFailed:
case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
failf(data, "SSL: Incorrect password for the certificate \"%s\" "
"and its private key.", data->set.str[STRING_CERT]);
break;
case errSecDecode: case errSecUnknownFormat:
case errSecDecode: case -25257: /* errSecUnknownFormat */
failf(data, "SSL: Couldn't make sense of the data in the "
"certificate \"%s\" and its private key.",
data->set.str[STRING_CERT]);
break;
case errSecPassphraseRequired:
case -25260: /* errSecPassphraseRequired */
failf(data, "SSL The certificate \"%s\" requires a password.",
data->set.str[STRING_CERT]);
break;
@@ -1403,6 +1439,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
#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
specifically doesn't want us doing that: */
if(SSLSetSessionOption != NULL)
SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!data->set.ssl_enable_beast);
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */

View File

@@ -77,10 +77,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
/* skip initial whitespaces */
while(*header && ISSPACE(*header))
header++;
if(checkprefix("NTLM", header)) {
header += strlen("NTLM");

View File

@@ -356,7 +356,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
conn->response_header = NULL;
break;
case NTLMSTATE_TYPE2:
input = aprintf("TT %s", conn->challenge_header);
input = aprintf("TT %s\n", conn->challenge_header);
if(!input)
return CURLE_OUT_OF_MEMORY;
res = ntlm_wb_response(conn, input, ntlm->state);

View File

@@ -23,6 +23,7 @@
* RFC4422 Simple Authentication and Security Layer (SASL)
* RFC4616 PLAIN authentication
* RFC6749 OAuth 2.0 Authorization Framework
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
*
***************************************************************************/
@@ -40,6 +41,10 @@
#include "warnless.h"
#include "curl_memory.h"
#ifdef USE_NSS
#include "nssg.h" /* for Curl_nss_force_init() */
#endif
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -50,7 +55,7 @@
/* 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
*/
static bool sasl_digest_get_key_value(const unsigned char *chlg,
static bool sasl_digest_get_key_value(const char *chlg,
const char *key,
char *value,
size_t max_val_len,
@@ -59,7 +64,7 @@ static bool sasl_digest_get_key_value(const unsigned char *chlg,
char *find_pos;
size_t i;
find_pos = strstr((const char *) chlg, key);
find_pos = strstr(chlg, key);
if(!find_pos)
return FALSE;
@@ -163,6 +168,36 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
}
#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()
*
@@ -172,7 +207,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
* Parameters:
*
* data [in] - The session handle.
* chlg64 [in] - Pointer to the base64 encoded challenge buffer.
* chlg [in] - The challenge.
* userp [in] - The user name.
* passdwp [in] - The user's password.
* 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.
*/
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *chlg,
const char *userp,
const char *passwdp,
char **outptr, size_t *outlen)
{
CURLcode result = CURLE_OK;
size_t chlg64len = strlen(chlg64);
unsigned char *chlg = (unsigned char *) NULL;
size_t chlglen = 0;
HMAC_context *ctxt;
unsigned char digest[MD5_DIGEST_LEN];
char *response;
/* Decode the challenge if necessary */
if(chlg64len && *chlg64 != '=') {
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
if(result)
return result;
}
if(chlg)
chlglen = strlen(chlg);
/* Compute the digest using the password as the key */
ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
(const unsigned char *) passwdp,
curlx_uztoui(strlen(passwdp)));
if(!ctxt) {
Curl_safefree(chlg);
if(!ctxt)
return CURLE_OUT_OF_MEMORY;
}
/* Update the digest with the given challenge */
if(chlglen > 0)
Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen));
Curl_safefree(chlg);
Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
curlx_uztoui(chlglen));
/* Finalise the digest */
Curl_HMAC_final(ctxt, digest);
/* Prepare the response */
/* Generate the response */
response = aprintf(
"%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],
@@ -231,13 +255,74 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
if(!response)
return CURLE_OUT_OF_MEMORY;
/* Base64 encode the reply */
/* Base64 encode the response */
result = Curl_base64_encode(data, response, 0, outptr, outlen);
Curl_safefree(response);
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()
*
@@ -247,10 +332,11 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
* Parameters:
*
* 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.
* 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
* holding the result will be stored upon completion.
* 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.
*/
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *nonce,
const char *realm,
const char *userp,
const char *passwdp,
const char *service,
char **outptr, size_t *outlen)
{
#ifndef DEBUGBUILD
static const char table16[] = "0123456789abcdef";
#endif
CURLcode result = CURLE_OK;
unsigned char *chlg = (unsigned char *) NULL;
size_t chlglen = 0;
size_t i;
MD5_context *ctxt;
char *response = NULL;
unsigned char digest[MD5_DIGEST_LEN];
char HA1_hex[2 * MD5_DIGEST_LEN + 1];
char HA2_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 cnonce[] = "12345678"; /* will be changed */
char method[] = "AUTHENTICATE";
char qop[] = "auth";
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 */
for(i = 0; i < 8; i++)
cnonce[i] = table16[Curl_rand(data)%16];
#endif
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
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++)
snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
snprintf(response, sizeof(response),
"username=\"%s\",realm=\"%s\",nonce=\"%s\","
/* Generate the response */
response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s",
userp, realm, nonce,
cnonce, nonceCount, uri, resp_hash_hex);
if(!response)
return CURLE_OUT_OF_MEMORY;
/* Base64 encode the reply */
return Curl_base64_encode(data, response, 0, outptr, outlen);
/* Base64 encode the response */
result = Curl_base64_encode(data, response, 0, outptr, outlen);
Curl_safefree(response);
return result;
}
#endif
@@ -438,8 +495,36 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
struct ntlmdata *ntlm,
char **outptr, size_t *outlen)
{
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr,
outlen);
return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr, 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:
*
* 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.
* passdwp [in] - The user's password.
* 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.
*/
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
const char *header,
const char *userp,
const char *passwdp,
struct ntlmdata *ntlm,
char **outptr, size_t *outlen)
{
CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm);
if(!result)
result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm,
outptr, outlen);
return result;
return Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, outptr,
outlen);
}
#endif /* USE_NTLM */
/*
* Curl_sasl_create_xoauth2_message()
*
* This is used to generate an already encoded XOAUTH2 message ready
* for sending to the recipient.
* This is used to generate an already encoded OAuth 2.0 message ready for
* sending to the recipient.
*
* Parameters:
*
* data [in] - The session handle.
* 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
* holding the result will be stored upon completion.
* outlen [out] - The length of the output message.
@@ -500,16 +578,20 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
const char *bearer,
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);
if(!xoauth)
return CURLE_OUT_OF_MEMORY;
/* Base64 encode the reply */
return Curl_base64_encode(data, xoauth, strlen(xoauth), outptr,
outlen);
result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
Curl_safefree(xoauth);
return result;
}
/*

View File

@@ -66,16 +66,27 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
size_t *outlen);
#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 */
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *chlg,
const char *user,
const char *passwdp,
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 */
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
const char *chlg64,
const char *nonce,
const char *realm,
const char *user,
const char *passwdp,
const char *service,
@@ -90,10 +101,13 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
char **outptr,
size_t *outlen);
/* This is used to decode an incoming NTLM type-2 message and generate a
base64 encoded type-3 response */
/* This is used to decode a base64 encoded NTLM type-2 message */
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,
const char *header,
const char *userp,
const char *passwdp,
struct ntlmdata *ntlm,

View File

@@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
SP_PROT_TLS1_1_CLIENT |
SP_PROT_TLS1_2_CLIENT;
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:
schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
break;

View File

@@ -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
* 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();
break;
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();
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:
req_method = SSLv3_client_method();
break;

View File

@@ -50,11 +50,6 @@
#include <sys/param.h>
#endif
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
#define SIGPIPE_IGNORE 1
#include <signal.h>
#endif
#include "strequal.h"
#include "urldata.h"
#include <curl/curl.h>
@@ -78,6 +73,7 @@
#include "warnless.h"
#include "conncache.h"
#include "multiif.h"
#include "sigpipe.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -85,56 +81,6 @@
/* The last #include file should be: */
#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
of win32_init() */
static void win32_cleanup(void)

188
lib/ftp.c
View File

@@ -1802,23 +1802,87 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
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,
int ftpcode)
{
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result;
struct SessionHandle *data=conn->data;
Curl_addrinfo *conninfo;
struct Curl_dns_entry *addr=NULL;
int rc;
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 */
if((ftpc->count1 == 0) &&
@@ -1851,7 +1915,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
return CURLE_FTP_WEIRD_PASV_REPLY;
}
if(ptr) {
newport = (unsigned short)(num & 0xffff);
ftpc->newport = (unsigned short)(num & 0xffff);
if(conn->bits.tunnel_proxy ||
conn->proxytype == CURLPROXY_SOCKS5 ||
@@ -1860,10 +1924,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
conn->proxytype == CURLPROXY_SOCKS4A)
/* proxy tunnel -> use other host info because ip_addr_str is the
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
/* 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
@@ -1916,14 +1981,15 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
conn->proxytype == CURLPROXY_SOCKS4A)
/* proxy tunnel -> use other host info because ip_addr_str is the
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
snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
conn->ip_addr_str);
}
else
snprintf(newhost, sizeof(newhost),
snprintf(ftpc->newhost, sizeof(ftpc->newhost),
"%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) {
/* EPSV failed, move on to PASV */
@@ -1957,24 +2023,21 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
else {
/* normal, direct, ftp connection */
rc = Curl_resolv(conn, newhost, newport, &addr);
rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
if(rc == CURLRESOLV_PENDING)
/* BLOCKING */
(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) {
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;
}
}
result = Curl_connecthost(conn,
addr,
&conn->sock[SECONDARYSOCKET],
&conninfo,
&connected);
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
result = Curl_connecthost(conn, addr);
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;
}
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
/*
* 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
* connect to connect and we should not be "hanging" here waiting.
* connect to connect.
*/
if(data->set.verbose)
/* 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;
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? */
if(connected) {
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 {
if(result && (ftpc->count1 == 0)) {

View File

@@ -147,6 +147,12 @@ struct ftp_conn {
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
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 */

View File

@@ -277,7 +277,57 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
ptr.to_certinfo = &data->info.certs;
*param_slistp = ptr.to_slist;
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:
return CURLE_BAD_FUNCTION_ARGUMENT;
}

View File

@@ -32,6 +32,35 @@
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
#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
# include <limits.h>
#endif
@@ -54,30 +83,65 @@
#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. */
typedef struct {
const char *name; /* Cipher name. */
const char *gsktoken; /* Corresponding token for GSKit String. */
int sslver; /* SSL version. */
unsigned int versions; /* SSL version flags. */
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
{ "null-md5", "01", CURL_SSLVERSION_SSLv3 },
{ "null-sha", "02", CURL_SSLVERSION_SSLv3 },
{ "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
{ "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
{ "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
{ "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
{ "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
{ "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
{ "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
{ "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
{ "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
{ "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
{ "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
{ "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
{ "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
{ "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
{ "null-md5", "01",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "null-sha", "02",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "exp-rc4-md5", "03",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
{ "rc4-md5", "04",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "rc4-sha", "05",
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
{ "exp-rc2-cbc-md5", "06",
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 }
};
@@ -142,8 +206,8 @@ static CURLcode gskit_status(struct SessionHandle * data, int rc,
}
static CURLcode set_enum(struct SessionHandle * data,
gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
static CURLcode set_enum(struct SessionHandle *data, gsk_handle h,
GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
{
int rc = gsk_attribute_set_enum(h, id, value);
@@ -153,6 +217,9 @@ static CURLcode set_enum(struct SessionHandle * data,
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
case GSK_ATTRIBUTE_INVALID_ID:
if(unsupported_ok)
return CURLE_UNSUPPORTED_PROTOCOL;
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
@@ -161,8 +228,8 @@ static CURLcode set_enum(struct SessionHandle * data,
}
static CURLcode set_buffer(struct SessionHandle * data,
gsk_handle h, GSK_BUF_ID id, const char * buffer)
static CURLcode set_buffer(struct SessionHandle *data, gsk_handle h,
GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
{
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:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
case GSK_ATTRIBUTE_INVALID_ID:
if(unsupported_ok)
return CURLE_UNSUPPORTED_PROTOCOL;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
@@ -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];
char * sslv2ciphers;
char * sslv3ciphers;
const char *clp;
const gskit_cipher *ctp;
char * v2p;
char * v3p;
int i;
int l;
bool unsupported;
CURLcode cc;
struct {
char *buf;
char *ptr;
} ciphers[CURL_GSKPROTO_LAST];
/* 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
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accomodate the result. */
i = strlen(cipherlist) + 1;
v2p = malloc(i);
if(!v2p)
return CURLE_OUT_OF_MEMORY;
v3p = malloc(i);
if(!v3p) {
free(v2p);
l = strlen(cipherlist) + 1;
memset((char *) ciphers, 0, sizeof ciphers);
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
ciphers[i].buf = malloc(l);
if(!ciphers[i].buf) {
while(i--)
free(ciphers[i].buf);
return CURLE_OUT_OF_MEMORY;
}
sslv2ciphers = v2p;
sslv3ciphers = v3p;
ciphers[i].ptr = ciphers[i].buf;
*ciphers[i].ptr = '\0';
}
/* Process each cipher in input string. */
unsupported = FALSE;
cc = CURLE_OK;
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
i = cipherlist - clp;
if(!i)
l = cipherlist - clp;
if(!l)
break;
/* Search the cipher in our table. */
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;
if(!ctp->name)
failf(data, "Unknown cipher %.*s: ignored", i, clp);
if(!ctp->name) {
failf(data, "Unknown cipher %.*s", l, clp);
cc = CURLE_SSL_CIPHER;
}
else {
switch (ctp->sslver) {
case CURL_SSLVERSION_SSLv2:
strcpy(v2p, ctp->gsktoken);
v2p += strlen(v2p);
break;
default:
/* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
strcpy(v3p, ctp->gsktoken);
v3p += strlen(v3p);
break;
unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
if(ctp->versions & (1 << i)) {
strcpy(ciphers[i].ptr, ctp->gsktoken);
ciphers[i].ptr += strlen(ctp->gsktoken);
}
}
}
@@ -286,13 +361,63 @@ static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
while(is_separator(*cipherlist))
cipherlist++;
}
*v2p = '\0';
*v3p = '\0';
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
if(cc == CURLE_OK)
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
free(sslv2ciphers);
free(sslv3ciphers);
/* Disable protocols with empty cipher lists. */
for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
*protoflags &= ~(1 << i);
ciphers[i].buf[0] = '\0';
}
}
/* 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;
}
@@ -333,15 +458,15 @@ static CURLcode init_environment(struct SessionHandle * data,
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)
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)
c = set_buffer(data, h, GSK_KEYRING_FILE, file);
c = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
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)
c = set_buffer(data, h, GSK_KEYRING_PW, password);
c = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
if(c == CURLE_OK) {
/* Locate CAs, Client certificate and key according to our settings.
@@ -438,10 +563,8 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
char *keyringfile;
char *keyringpwd;
char *keyringlabel;
char * v2ciphers;
char * v3ciphers;
char *sni;
bool sslv2enable, sslv3enable, tlsv1enable;
unsigned int protoflags;
long timeout;
Qso_OverlappedIO_t commarea;
@@ -491,43 +614,39 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
return cc;
/* 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;
switch (data->set.ssl.version) {
case CURL_SSLVERSION_SSLv2:
sslv2enable = true;
protoflags = CURL_GSKPROTO_SSLV2_MASK;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_SSLv3:
sslv3enable = true;
protoflags = CURL_GSKPROTO_SSLV2_MASK;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
tlsv1enable = true;
protoflags = CURL_GSKPROTO_TLSV10_MASK |
CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
break;
default: /* CURL_SSLVERSION_DEFAULT. */
sslv3enable = true;
tlsv1enable = true;
case CURL_SSLVERSION_TLSv1_0:
protoflags = CURL_GSKPROTO_TLSV10_MASK;
break;
case CURL_SSLVERSION_TLSv1_1:
protoflags = CURL_GSKPROTO_TLSV11_MASK;
break;
case CURL_SSLVERSION_TLSv1_2:
protoflags = CURL_GSKPROTO_TLSV12_MASK;
break;
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
rc = gsk_attribute_set_buffer(connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
switch (rc) {
case GSK_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;
}
cc = set_buffer(data, connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
if(cc == CURLE_UNSUPPORTED_PROTOCOL)
cc = CURLE_OK;
}
/* Set session parameters. */
@@ -544,23 +663,51 @@ static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
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)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
sslv2enable? GSK_PROTOCOL_SSLV2_ON:
GSK_PROTOCOL_SSLV2_OFF);
(protoflags & CURL_GSKPROTO_SSLV2_MASK)?
GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
sslv3enable? GSK_PROTOCOL_SSLV3_ON:
GSK_PROTOCOL_SSLV3_OFF);
(protoflags & CURL_GSKPROTO_SSLV3_MASK)?
GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
GSK_PROTOCOL_TLSV1_OFF);
(protoflags & CURL_GSKPROTO_TLSV10_MASK)?
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)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU);
GSK_SERVER_AUTH_PASSTHRU, FALSE);
if(cc == CURLE_OK) {
/* Start handshake. Try asynchronous first. */

View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -633,10 +633,8 @@ gtls_connect_step3(struct connectdata *conn,
else
infof(data, "\t server certificate verification OK\n");
}
else {
else
infof(data, "\t server certificate verification SKIPPED\n");
goto after_server_cert_verification;
}
/* initialize an X.509 certificate structure. */
gnutls_x509_crt_init(&x509_cert);
@@ -766,8 +764,6 @@ gtls_connect_step3(struct connectdata *conn,
gnutls_x509_crt_deinit(x509_cert);
after_server_cert_verification:
/* compression algorithm (if any) */
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */

View File

@@ -23,7 +23,7 @@
#include "curl_setup.h"
#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 */
#include "hostcheck.h"
@@ -94,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
return 0;
}
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT or NSS */

View File

@@ -291,9 +291,10 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
{
struct hostcache_prune_data user;
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
/* cache forever means never prune, and NULL hostcache means
we can't do it */
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache ||
dns->inuse)
/* 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;
time(&user.now);
@@ -428,9 +429,13 @@ int Curl_resolv(struct connectdata *conn,
/* free the allocated entry_id again */
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 */
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 */
}
if(dns) {
dns->inuse++; /* we use it! */

View File

@@ -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
* 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 *end;
char *value;
size_t len;
DEBUGASSERT(h);
DEBUGASSERT(header);
/* Find the end of the header name */
while(*h && (*h != ':'))
++h;
while(*header && (*header != ':'))
++header;
if(*h)
if(*header)
/* Skip over colon */
++h;
++header;
/* Find the first non-space letter */
start = h;
start = header;
while(*start && ISSPACE(*start))
start++;
@@ -699,9 +699,8 @@ Curl_http_output_auth(struct connectdata *conn,
* proxy CONNECT loop.
*/
CURLcode Curl_http_input_auth(struct connectdata *conn,
int httpcode,
const char *header) /* the first non-space */
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
const char *auth) /* the first non-space */
{
/*
* This resource requires authentication
@@ -709,24 +708,17 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
struct SessionHandle *data = conn->data;
unsigned long *availp;
const char *start;
struct auth *authp;
if(httpcode == 407) {
start = header+strlen("Proxy-authenticate:");
if(proxy) {
availp = &data->info.proxyauthavail;
authp = &data->state.authproxy;
}
else {
start = header+strlen("WWW-Authenticate:");
availp = &data->info.httpauthavail;
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
* 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
if(checkprefix("GSS-Negotiate", start) ||
checkprefix("Negotiate", start)) {
if(checkprefix("GSS-Negotiate", auth) ||
checkprefix("Negotiate", auth)) {
int neg;
*availp |= CURLAUTH_GSSNEGOTIATE;
authp->avail |= CURLAUTH_GSSNEGOTIATE;
@@ -760,7 +752,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
data->state.authproblem = TRUE;
}
else {
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
neg = Curl_input_negotiate(conn, proxy, auth);
if(neg == 0) {
DEBUGASSERT(!data->req.newurl);
data->req.newurl = strdup(data->change.url);
@@ -779,14 +771,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
#endif
#ifdef USE_NTLM
/* NTLM support requires the SSL crypto libs */
if(checkprefix("NTLM", start)) {
if(checkprefix("NTLM", auth)) {
*availp |= CURLAUTH_NTLM;
authp->avail |= CURLAUTH_NTLM;
if(authp->picked == CURLAUTH_NTLM ||
authp->picked == CURLAUTH_NTLM_WB) {
/* NTLM authentication is picked and activated */
CURLcode ntlm =
Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
Curl_input_ntlm(conn, proxy, auth);
if(CURLE_OK == ntlm) {
data->state.authproblem = FALSE;
#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
* ntlm_auth for generating the type 3 message later */
while(*start && ISSPACE(*start))
start++;
if(checkprefix("NTLM", start)) {
start += strlen("NTLM");
while(*start && ISSPACE(*start))
start++;
if(*start)
if((conn->challenge_header = strdup(start)) == NULL)
while(*auth && ISSPACE(*auth))
auth++;
if(checkprefix("NTLM", auth)) {
auth += strlen("NTLM");
while(*auth && ISSPACE(*auth))
auth++;
if(*auth)
if((conn->challenge_header = strdup(auth)) == NULL)
return CURLE_OUT_OF_MEMORY;
}
}
@@ -820,7 +812,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
else
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(checkprefix("Digest", start)) {
if(checkprefix("Digest", auth)) {
if((authp->avail & CURLAUTH_DIGEST) != 0) {
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
* incoming data from this header in case we are gonna use
* Digest. */
dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
dig = Curl_input_digest(conn, proxy, auth);
if(CURLDIGEST_FINE != dig) {
infof(data, "Authentication problem. Ignoring this.\n");
@@ -843,7 +835,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
}
else
#endif
if(checkprefix("Basic", start)) {
if(checkprefix("Basic", auth)) {
*availp |= CURLAUTH_BASIC;
authp->avail |= 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 */
while(*start && *start != ',') /* read up to the next comma */
start++;
if(*start == ',') /* if we're on a comma, skip it */
start++;
while(*start && ISSPACE(*start))
start++;
while(*auth && *auth != ',') /* read up to the next comma */
auth++;
if(*auth == ',') /* if we're on a comma, skip it */
auth++;
while(*auth && ISSPACE(*auth))
auth++;
}
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
redirected request is being out on thin ice. Except if the host name
is the same as the first one! */
char *cookiehost = copy_header_value(ptr);
char *cookiehost = Curl_copy_header_value(ptr);
if(!cookiehost)
return CURLE_OUT_OF_MEMORY;
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 */
else if(checkprefix("Content-Type:", k->p)) {
char *contenttype = copy_header_value(k->p);
char *contenttype = Curl_copy_header_value(k->p);
if(!contenttype)
return CURLE_OUT_OF_MEMORY;
if(!*contenttype)
@@ -3259,7 +3251,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
}
}
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 */
if(conn->bundle && conn->bundle->server_supports_pipelining) {
@@ -3455,7 +3447,16 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
(401 == k->httpcode)) ||
(checkprefix("Proxy-authenticate:", k->p) &&
(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)
return result;
}
@@ -3463,7 +3464,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
checkprefix("Location:", k->p) &&
!data->req.location) {
/* 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)
return CURLE_OUT_OF_MEMORY;
if(!*location)

View File

@@ -35,11 +35,12 @@ extern const struct Curl_handler Curl_handler_http;
extern const struct Curl_handler Curl_handler_https;
#endif
/* Header specific functions */
bool Curl_compareheader(const char *headerline, /* line to check */
const char *header, /* header keyword _with_ colon */
const char *content); /* content string to find */
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 */
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
CURLcode Curl_http_input_auth(struct connectdata *conn,
int httpcode, const char *header);
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
const char *auth);
CURLcode Curl_http_auth_act(struct connectdata *conn);
CURLcode Curl_http_perhapsrewind(struct connectdata *conn);

View File

@@ -141,10 +141,6 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
d = &data->state.digest;
}
/* skip initial whitespaces */
while(*header && ISSPACE(*header))
header++;
if(checkprefix("Digest", header)) {
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
this sorted out, I must urge you dear friend to read up on the RFC2617
section 3.2.2, */
size_t urilen;
unsigned char md5buf[16]; /* 16 bytes/128 bits */
unsigned char request_digest[33];
unsigned char *md5this;
@@ -440,13 +437,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
Further details on Digest implementation differences:
http://www.fngtps.com/2006/09/http-authentication
*/
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
md5this = (unsigned char *)aprintf("%s:%.*s", request,
curlx_sztosi(tmp - (char *)uripath),
uripath);
}
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL))
urilen = tmp - (char *)uripath;
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")) {
/* 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\", "
"realm=\"%s\", "
"nonce=\"%s\", "
"uri=\"%s\", "
"uri=\"%.*s\", "
"cnonce=\"%s\", "
"nc=%08x, "
"qop=%s, "
@@ -520,7 +517,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
urilen, uripath, /* this is the PATH part of the URL */
d->cnonce,
d->nc,
d->qop,
@@ -537,13 +534,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"username=\"%s\", "
"realm=\"%s\", "
"nonce=\"%s\", "
"uri=\"%s\", "
"uri=\"%.*s\", "
"response=\"%s\"",
proxy?"Proxy-":"",
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
urilen, uripath, /* this is the PATH part of the URL */
request_digest);
}
Curl_safefree(userp_quoted);

View File

@@ -145,8 +145,6 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
const char* protocol;
CURLcode error;
while(*header && ISSPACE(*header))
header++;
if(checkprefix("GSS-Negotiate", header)) {
protocol = "GSS-Negotiate";
gss = TRUE;

View File

@@ -98,9 +98,6 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
const char* protocol;
CURLcode error;
while(*header && ISSPACE(*header))
header++;
if(checkprefix("GSS-Negotiate", header)) {
protocol = "GSS-Negotiate";
gss = TRUE;

View File

@@ -452,8 +452,16 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
(401 == k->httpcode)) ||
(checkprefix("Proxy-authenticate:", line_start) &&
(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)
return result;
}

View File

@@ -27,6 +27,7 @@
* RFC4959 IMAP Extension for SASL Initial Client Response
* RFC5092 IMAP URL Scheme
* 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 */
}
/***********************************************************************
*
* 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()
@@ -396,6 +426,7 @@ static void state(struct connectdata *conn, imapstate newstate)
"AUTHENTICATE_NTLM",
"AUTHENTICATE_NTLM_TYPE2MSG",
"AUTHENTICATE_XOAUTH2",
"AUTHENTICATE_CANCEL",
"AUTHENTICATE_FINAL",
"LOGIN",
"LIST",
@@ -553,8 +584,8 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
return result;
}
/* Calculate the supported authentication mechanism by decreasing order of
security */
/* Calculate the supported authentication mechanism, by decreasing order of
security, as well as the initial response where appropriate */
#ifndef CURL_DISABLE_CRYPTO_AUTH
if((imapc->authmechs & 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(mech) {
if(mech && (imapc->preftype & IMAP_TYPE_SASL)) {
/* Perform SASL based authentication */
if(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);
}
else if(!imapc->login_disabled)
else if((!imapc->login_disabled) &&
(imapc->preftype & IMAP_TYPE_CLEARTEXT))
/* Perform clear text authentication */
result = imap_perform_login(conn);
else {
@@ -976,19 +1008,16 @@ static CURLcode imap_state_auth_plain_resp(struct connectdata *conn,
/* Create the authorisation message */
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
&plainauth, &len);
if(!result && plainauth) {
/* Send the message */
if(!result) {
if(plainauth) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", plainauth);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
}
Curl_safefree(plainauth);
}
}
return result;
}
@@ -1013,19 +1042,16 @@ static CURLcode imap_state_auth_login_resp(struct connectdata *conn,
/* Create the user message */
result = Curl_sasl_create_login_message(data, conn->user,
&authuser, &len);
if(!result && authuser) {
/* Send the user */
if(!result) {
if(authuser) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authuser);
if(!result)
state(conn, IMAP_AUTHENTICATE_LOGIN_PASSWD);
}
}
Curl_safefree(authuser);
}
}
return result;
}
@@ -1050,19 +1076,16 @@ static CURLcode imap_state_auth_login_password_resp(struct connectdata *conn,
/* Create the password message */
result = Curl_sasl_create_login_message(data, conn->passwd,
&authpasswd, &len);
if(!result && authpasswd) {
/* Send the password */
if(!result) {
if(authpasswd) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", authpasswd);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
}
Curl_safefree(authpasswd);
}
}
return result;
}
@@ -1075,9 +1098,10 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
(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;
}
/* Get the challenge */
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
imap_get_message(data->state.buffer, &chlg64);
/* Terminate the challenge */
if(*chlg64 != '=') {
for(len = strlen(chlg64); len--;)
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
chlg64[len] != '\t')
break;
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
if(++len) {
chlg64[len] = '\0';
if(!result)
state(conn, IMAP_AUTHENTICATE_CANCEL);
}
}
else {
/* 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);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}
@@ -1128,9 +1148,13 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
char nonce[64];
char realm[128];
char algorithm[64];
(void)instate; /* no use for this yet */
@@ -1139,26 +1163,35 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn,
return CURLE_LOGIN_DENIED;
}
/* Get the challenge */
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
imap_get_message(data->state.buffer, &chlg64);
/* Decode the challange message */
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
realm, sizeof(realm),
algorithm, sizeof(algorithm));
if(result || strcmp(algorithm, "md5-sess") != 0) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
if(!result)
state(conn, IMAP_AUTHENTICATE_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
conn->passwd, "imap",
&rplyb64, &len);
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
conn->user, conn->passwd,
"imap", &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
if(!result)
state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP);
}
}
Curl_safefree(rplyb64);
}
return result;
}
@@ -1211,19 +1244,16 @@ static CURLcode imap_state_auth_ntlm_resp(struct connectdata *conn,
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
&conn->ntlm,
&type1msg, &len);
if(!result && type1msg) {
/* Send the message */
if(!result) {
if(type1msg) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type1msg);
if(!result)
state(conn, IMAP_AUTHENTICATE_NTLM_TYPE2MSG);
}
}
Curl_safefree(type1msg);
}
}
return result;
}
@@ -1235,8 +1265,9 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
size_t len = 0;
char *type2msg = NULL;
char *type3msg = NULL;
size_t len = 0;
(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;
}
else {
/* Create the type-3 message */
result = Curl_sasl_create_ntlm_type3_message(data,
data->state.buffer + 2,
conn->user, conn->passwd,
&conn->ntlm,
&type3msg, &len);
/* Get the challenge message */
imap_get_message(data->state.buffer, &type2msg);
/* Decode the type-2 message */
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
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 */
if(!result) {
if(type3msg) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", type3msg);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
}
}
Curl_safefree(type3msg);
}
}
return result;
}
#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,
int imapcode,
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,
conn->xoauth2_bearer,
&xoauth, &len);
if(!result && xoauth) {
/* Send the message */
if(!result) {
if(xoauth) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", xoauth);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
}
Curl_safefree(xoauth);
}
}
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,
int imapcode,
imapstate instate)
@@ -1660,6 +1712,10 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
break;
case IMAP_AUTHENTICATE_CANCEL:
result = imap_state_auth_cancel_resp(conn, imapcode, imapc->state);
break;
case IMAP_AUTHENTICATE_FINAL:
result = imap_state_auth_final_resp(conn, imapcode, imapc->state);
break;
@@ -1782,7 +1838,8 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
pp->endofresp = imap_endofresp;
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;
/* 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
point! */
if(!dead_connection && imapc->pp.conn)
if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
if(!imap_perform_logout(conn))
(void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
@@ -2276,25 +2333,43 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
if(strnequal(key, "AUTH", 4)) {
const char *value = ptr + 1;
if(strequal(value, "*"))
if(strequal(value, "*")) {
imapc->preftype = IMAP_TYPE_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;
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;
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;
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;
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;
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;
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;
else
}
else {
imapc->preftype = IMAP_TYPE_NONE;
imapc->prefmech = SASL_AUTH_NONE;
}
}
else
result = CURLE_URL_MALFORMAT;
}

View File

@@ -44,6 +44,7 @@ typedef enum {
IMAP_AUTHENTICATE_NTLM,
IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
IMAP_AUTHENTICATE_XOAUTH2,
IMAP_AUTHENTICATE_CANCEL,
IMAP_AUTHENTICATE_FINAL,
IMAP_LOGIN,
IMAP_LIST,
@@ -77,6 +78,7 @@ struct imap_conn {
imapstate state; /* Always use imap.c:state() to change state! */
bool ssldone; /* Is connect() over SSL done? */
unsigned int authmechs; /* Accepted authentication mechanisms */
unsigned int preftype; /* Preferred authentication type */
unsigned int prefmech; /* Preferred authentication mechanism */
unsigned int authused; /* Auth mechanism used for the connection */
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_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 */

View File

@@ -41,6 +41,7 @@
#include "bundles.h"
#include "multihandle.h"
#include "pipeline.h"
#include "sigpipe.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -621,17 +622,28 @@ static int waitconnect_getsock(struct connectdata *conn,
curl_socket_t *sock,
int numsocks)
{
int i;
int s=0;
int rc=0;
if(!numsocks)
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
socket to become readable to be able to get the response headers */
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
return GETSOCK_READSOCK(0);
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) {
sock[0] = conn->sock[FIRSTSOCKET];
rc = GETSOCK_READSOCK(0);
}
return GETSOCK_WRITESOCK(0);
return rc;
}
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
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);
if((timeout_internal > 0) && (timeout_internal < (long)timeout_ms))
if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
timeout_ms = (int)timeout_internal;
/* Count up how many fds we have from the multi handle */
@@ -865,6 +877,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
if(nfds) {
/* wait... */
infof(data, "Curl_poll(%d ds, %d ms)\n", nfds, timeout_ms);
i = Curl_poll(ufds, nfds, timeout_ms);
if(i) {
@@ -1774,12 +1787,18 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
struct SessionHandle *nextdata;
if(GOOD_MULTI_HANDLE(multi)) {
bool restore_pipe = FALSE;
SIGPIPE_VARIABLE(pipe_st);
multi->type = 0; /* not good anymore */
/* Close all the connections in the connection cache */
close_all_connections(multi);
if(multi->closure_handle) {
sigpipe_ignore(multi->closure_handle, &pipe_st);
restore_pipe = TRUE;
multi->closure_handle->dns.hostcache = multi->hostcache;
Curl_hostcache_clean(multi->closure_handle,
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);
free(multi);
if(restore_pipe)
sigpipe_restore(&pipe_st);
return CURLM_OK;
}

View File

@@ -30,6 +30,8 @@
#define MULTI_TIMEOUT_INACCURACY 3000
#endif
#define MULTI_TIMEOUT_INACCURACY_MS (MULTI_TIMEOUT_INACCURACY / 1000)
/*
* Prototypes for library-wide functions provided by multi.c
*/

175
lib/nss.c
View File

@@ -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
* you should have received as part of this distribution. The terms
@@ -63,6 +63,7 @@
#include "curl_memory.h"
#include "rawstr.h"
#include "warnless.h"
#include "x509asn1.h"
/* The last #include file should be: */
#include "memdebug.h"
@@ -76,9 +77,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
PRLock * nss_initlock = NULL;
PRLock * nss_crllock = NULL;
#ifdef HAVE_NSS_INITCONTEXT
NSSInitContext * nss_context = NULL;
#endif
volatile int initialized = 0;
@@ -653,6 +652,10 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
SSLChannelInfo channel;
SSLCipherSuiteInfo suite;
CERTCertificate *cert;
CERTCertificate *cert2;
CERTCertificate *cert3;
PRTime now;
int i;
if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
SECSuccess && channel.length == sizeof channel &&
@@ -663,11 +666,45 @@ static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
}
}
cert = SSL_PeerCertificate(sock);
if(cert) {
infof(conn->data, "Server certificate:\n");
cert = SSL_PeerCertificate(sock);
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;
}
@@ -854,7 +891,6 @@ isTLSIntoleranceError(PRInt32 err)
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
{
#ifdef HAVE_NSS_INITCONTEXT
NSSInitParameters initparams;
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));
initparams.length = sizeof(initparams);
#else /* HAVE_NSS_INITCONTEXT */
SECStatus rv;
if(NSS_IsInitialized())
return CURLE_OK;
#endif
if(cert_dir) {
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;
infof(data, "Initializing NSS with certpath: %s\n", certpath);
#ifdef HAVE_NSS_INITCONTEXT
nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
free(certpath);
if(nss_context != NULL)
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, "Initializing NSS with certpath: none\n");
#ifdef HAVE_NSS_INITCONTEXT
nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
if(nss_context != NULL)
return CURLE_OK;
#else /* HAVE_NSS_INITCONTEXT */
if(NSS_NoDB_Init(NULL) == SECSuccess)
return CURLE_OK;
#endif
infof(data, "Unable to initialize NSS\n");
return CURLE_SSL_CACERT_BADFILE;
@@ -1000,12 +1017,8 @@ void Curl_nss_cleanup(void)
SECMOD_DestroyModule(mod);
mod = NULL;
}
#ifdef HAVE_NSS_INITCONTEXT
NSS_ShutdownContext(nss_context);
nss_context = NULL;
#else /* HAVE_NSS_INITCONTEXT */
NSS_Shutdown();
#endif
}
PR_Unlock(nss_initlock);
@@ -1172,13 +1185,69 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
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)
{
PRErrorCode err = 0;
PRFileDesc *model = NULL;
PRBool ssl2 = PR_FALSE;
PRBool ssl3 = PR_FALSE;
PRBool tlsv1 = PR_FALSE;
PRBool ssl_no_cache;
PRBool ssl_cbc_random_iv;
struct SessionHandle *data = conn->data;
@@ -1190,6 +1259,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
long time_left;
PRUint32 timeout;
SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_3_0, /* min */
SSL_LIBRARY_VERSION_TLS_1_0 /* max */
};
if(connssl->state == ssl_connection_complete)
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)
goto error;
/* do not use SSL cache if we are not going to verify peer */
ssl_no_cache = (data->set.ssl.verifypeer) ? PR_FALSE : PR_TRUE;
/* do not use SSL cache if disabled or we are not going to verify peer */
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)
goto error;
switch (data->set.ssl.version) {
default:
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)
/* enable/disable the requested SSL version(s) */
if(nss_init_sslver(&sslver, data) != CURLE_OK)
goto error;
if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
goto error;
ssl_cbc_random_iv = !data->set.ssl_enable_beast;
@@ -1466,7 +1517,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
Curl_llist_destroy(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() */
data->state.ssl_connect_retry = TRUE;
infof(data, "Error in TLS handshake, trying SSLv3...\n");

View File

@@ -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
* 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. */
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 */
t += delta;

View File

@@ -29,6 +29,7 @@
* RFC4616 PLAIN authentication
* RFC5034 POP3 SASL Authentication Mechanism
* 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 */
}
/***********************************************************************
*
* 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()
@@ -375,6 +405,7 @@ static void state(struct connectdata *conn, pop3state newstate)
"AUTH_NTLM",
"AUTH_NTLM_TYPE2MSG",
"AUTH_XOAUTH2",
"AUTH_CANCEL",
"AUTH_FINAL",
"APOP",
"USER",
@@ -570,8 +601,8 @@ static CURLcode pop3_perform_authenticate(struct connectdata *conn)
return result;
}
/* Calculate the supported authentication mechanism by decreasing order of
security */
/* Calculate the supported authentication mechanism, by decreasing order of
security, as well as the initial response where appropriate */
if(pop3c->authtypes & POP3_TYPE_SASL) {
#ifndef CURL_DISABLE_CRYPTO_AUTH
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
@@ -834,19 +865,16 @@ static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn,
/* Create the authorisation message */
result = Curl_sasl_create_plain_message(data, conn->user, conn->passwd,
&plainauth, &len);
if(!result && plainauth) {
/* Send the message */
if(!result) {
if(plainauth) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", plainauth);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
}
Curl_safefree(plainauth);
}
}
return result;
}
@@ -871,19 +899,16 @@ static CURLcode pop3_state_auth_login_resp(struct connectdata *conn,
/* Create the user message */
result = Curl_sasl_create_login_message(data, conn->user,
&authuser, &len);
if(!result && authuser) {
/* Send the user */
if(!result) {
if(authuser) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authuser);
if(!result)
state(conn, POP3_AUTH_LOGIN_PASSWD);
}
}
Curl_safefree(authuser);
}
}
return result;
}
@@ -908,19 +933,16 @@ static CURLcode pop3_state_auth_login_password_resp(struct connectdata *conn,
/* Create the password message */
result = Curl_sasl_create_login_message(data, conn->passwd,
&authpasswd, &len);
if(!result && authpasswd) {
/* Send the password */
if(!result) {
if(authpasswd) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", authpasswd);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
}
Curl_safefree(authpasswd);
}
}
return result;
}
@@ -933,9 +955,10 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
(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;
}
/* Get the challenge */
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlg64);
/* Terminate the challenge */
if(*chlg64 != '=') {
for(len = strlen(chlg64); len--;)
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
chlg64[len] != '\t')
break;
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
if(++len) {
chlg64[len] = '\0';
if(!result)
state(conn, POP3_AUTH_CANCEL);
}
}
else {
/* 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);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}
@@ -986,9 +1005,13 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
char nonce[64];
char realm[128];
char algorithm[64];
(void)instate; /* no use for this yet */
@@ -997,26 +1020,35 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn,
return CURLE_LOGIN_DENIED;
}
/* Get the challenge */
for(chlg64 += 2; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlg64);
/* Decode the challange message */
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
realm, sizeof(realm),
algorithm, sizeof(algorithm));
if(result || strcmp(algorithm, "md5-sess") != 0) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
if(!result)
state(conn, POP3_AUTH_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
conn->passwd, "pop",
&rplyb64, &len);
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
conn->user, conn->passwd,
"pop", &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
if(!result)
state(conn, POP3_AUTH_DIGESTMD5_RESP);
}
}
Curl_safefree(rplyb64);
}
return result;
}
@@ -1069,19 +1101,16 @@ static CURLcode pop3_state_auth_ntlm_resp(struct connectdata *conn,
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
&conn->ntlm,
&type1msg, &len);
if(!result && type1msg) {
/* Send the message */
if(!result) {
if(type1msg) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type1msg);
if(!result)
state(conn, POP3_AUTH_NTLM_TYPE2MSG);
}
}
Curl_safefree(type1msg);
}
}
return result;
}
@@ -1093,8 +1122,9 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
size_t len = 0;
char *type2msg = NULL;
char *type3msg = NULL;
size_t len = 0;
(void)instate; /* no use for this yet */
@@ -1103,25 +1133,34 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
result = CURLE_LOGIN_DENIED;
}
else {
/* Create the type-3 message */
result = Curl_sasl_create_ntlm_type3_message(data,
data->state.buffer + 2,
conn->user, conn->passwd,
&conn->ntlm,
&type3msg, &len);
/* Get the type-2 message */
pop3_get_message(data->state.buffer, &type2msg);
/* Decode the type-2 message */
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
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 */
if(!result) {
if(type3msg) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", type3msg);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
}
}
Curl_safefree(type3msg);
}
}
return result;
}
@@ -1147,24 +1186,36 @@ static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn,
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
conn->xoauth2_bearer,
&xoauth, &len);
if(!result && xoauth) {
/* Send the message */
if(!result) {
if(xoauth) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", xoauth);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
}
Curl_safefree(xoauth);
}
}
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,
int pop3code,
pop3state instate)
@@ -1386,6 +1437,10 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
break;
case POP3_AUTH_CANCEL:
result = pop3_state_auth_cancel_resp(conn, pop3code, pop3c->state);
break;
case POP3_AUTH_FINAL:
result = pop3_state_auth_final_resp(conn, pop3code, pop3c->state);
break;
@@ -1570,12 +1625,12 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
{
/* This is POP3 and no proxy */
CURLcode result = CURLE_OK;
struct POP3 *pop3 = conn->data->req.protop;
DEBUGF(infof(conn->data, "DO phase starts\n"));
if(conn->data->set.opt_no_body) {
/* Requested no body means no transfer */
struct POP3 *pop3 = conn->data->req.protop;
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
* resources. BLOCKING.
*/
static CURLcode pop3_disconnect(struct connectdata *conn,
bool dead_connection)
static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
{
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
point! */
if(!dead_connection && pop3c->pp.conn)
if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
if(!pop3_perform_quit(conn))
(void)pop3_block_statemach(conn); /* ignore errors on QUIT */

View File

@@ -44,6 +44,7 @@ typedef enum {
POP3_AUTH_NTLM,
POP3_AUTH_NTLM_TYPE2MSG,
POP3_AUTH_XOAUTH2,
POP3_AUTH_CANCEL,
POP3_AUTH_FINAL,
POP3_APOP,
POP3_USER,
@@ -92,7 +93,7 @@ extern const struct Curl_handler Curl_handler_pop3s;
/* Authentication type values */
#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 */
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"

View File

@@ -204,6 +204,12 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
case CURL_SSLVERSION_SSLv3:
h->protocol = SSL_VERSION_3;
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;

View File

@@ -33,7 +33,7 @@
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 <netdb.h>
@@ -42,7 +42,8 @@ typedef unsigned long u_int32_t;
#include <qsoasync.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,
struct addrinfo * * res);
#define getaddrinfo Curl_getaddrinfo_a
@@ -66,7 +67,8 @@ extern int Curl_SSL_Init_a(SSLInit * init);
#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
@@ -226,5 +228,12 @@ extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
#define sendto Curl_os400_sendto
#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 */

78
lib/sigpipe.h Normal file
View 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 */

View File

@@ -27,7 +27,8 @@
* RFC4954 SMTP Authentication
* RFC5321 SMTP protocol
* 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_parse_url_options(struct connectdata *conn);
static CURLcode smtp_parse_url_path(struct connectdata *conn);
static CURLcode smtp_parse_custom_request(struct connectdata *conn);
/*
* 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
* 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;
bool result = FALSE;
size_t wordlen;
/* Nothing for us */
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? */
result = (line[3] == ' ') ? TRUE : FALSE;
if(result)
/* Do we have a command response? This should be the response code followed
by a space and optionally some text as per RFC-5321 and as outlined in
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));
/* Are we processing EHLO command data? */
if(smtpc->state == SMTP_EHLO && (!result || (result && *resp/100 == 2))) {
line += 4;
len -= 4;
/* Does the server support the STARTTLS capability? */
if(len >= 8 && !memcmp(line, "STARTTLS", 8))
smtpc->tls_supported = TRUE;
/* 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;
}
/* Make sure real server never sends internal value */
if(*resp == 1)
*resp = 0;
}
/* Do we have a multiline (continuation) response? */
else if(line[3] == '-' &&
(smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) {
result = TRUE;
*resp = 1; /* Internal response code */
}
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()
@@ -330,7 +314,9 @@ static void state(struct connectdata *conn, smtpstate newstate)
"AUTH_NTLM",
"AUTH_NTLM_TYPE2MSG",
"AUTH_XOAUTH2",
"AUTH_CANCEL",
"AUTH_FINAL",
"COMMAND",
"MAIL",
"RCPT",
"DATA",
@@ -565,6 +551,35 @@ static CURLcode smtp_perform_authenticate(struct connectdata *conn)
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()
@@ -656,7 +671,6 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
struct SMTP *smtp = data->req.protop;
/* Send the RCPT TO command */
if(smtp->rcpt) {
if(smtp->rcpt->data[0] == '<')
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
smtp->rcpt->data);
@@ -665,7 +679,6 @@ static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
smtp->rcpt->data);
if(!result)
state(conn, SMTP_RCPT);
}
return result;
}
@@ -740,10 +753,13 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
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 */
if(smtpcode/100 != 2) {
if(smtpcode/100 != 2 && smtpcode != 1) {
if((data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) &&
!conn->bits.user_passwd)
result = smtp_perform_helo(conn);
@@ -752,7 +768,67 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
result = CURLE_REMOTE_ACCESS_DENIED;
}
}
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
else {
line += 4;
len -= 4;
/* Does the server support the STARTTLS capability? */
if(len >= 8 && !memcmp(line, "STARTTLS", 8))
smtpc->tls_supported = TRUE;
/* 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;
}
}
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 */
@@ -767,6 +843,8 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
}
else
result = smtp_perform_authenticate(conn);
}
}
return result;
}
@@ -811,19 +889,16 @@ static CURLcode smtp_state_auth_plain_resp(struct connectdata *conn,
/* Create the authorisation message */
result = Curl_sasl_create_plain_message(conn->data, conn->user,
conn->passwd, &plainauth, &len);
if(!result && plainauth) {
/* Send the message */
if(!result) {
if(plainauth) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", plainauth);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
}
Curl_safefree(plainauth);
}
}
return result;
}
@@ -848,19 +923,16 @@ static CURLcode smtp_state_auth_login_resp(struct connectdata *conn,
/* Create the user message */
result = Curl_sasl_create_login_message(conn->data, conn->user,
&authuser, &len);
if(!result && authuser) {
/* Send the user */
if(!result) {
if(authuser) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authuser);
if(!result)
state(conn, SMTP_AUTH_LOGIN_PASSWD);
}
}
Curl_safefree(authuser);
}
}
return result;
}
@@ -885,19 +957,16 @@ static CURLcode smtp_state_auth_login_password_resp(struct connectdata *conn,
/* Create the password message */
result = Curl_sasl_create_login_message(conn->data, conn->passwd,
&authpasswd, &len);
if(!result && authpasswd) {
/* Send the password */
if(!result) {
if(authpasswd) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", authpasswd);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
}
Curl_safefree(authpasswd);
}
}
return result;
}
@@ -910,9 +979,10 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg = NULL;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
(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;
}
/* Get the challenge */
for(chlg64 += 4; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
smtp_get_message(data->state.buffer, &chlg64);
/* Terminate the challenge */
if(*chlg64 != '=') {
for(len = strlen(chlg64); len--;)
if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' &&
chlg64[len] != '\t')
break;
/* Decode the challenge message */
result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
if(result) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
if(++len) {
chlg64[len] = '\0';
if(!result)
state(conn, SMTP_AUTH_CANCEL);
}
}
else {
/* 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);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
Curl_safefree(rplyb64);
}
Curl_safefree(chlg);
Curl_safefree(rplyb64);
return result;
}
@@ -963,9 +1029,13 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlg64 = data->state.buffer;
size_t len = 0;
char *chlg64 = NULL;
char *rplyb64 = NULL;
size_t len = 0;
char nonce[64];
char realm[128];
char algorithm[64];
(void)instate; /* no use for this yet */
@@ -974,26 +1044,35 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn,
return CURLE_LOGIN_DENIED;
}
/* Get the challenge */
for(chlg64 += 4; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)
;
/* Get the challenge message */
smtp_get_message(data->state.buffer, &chlg64);
/* Decode the challange message */
result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
realm, sizeof(realm),
algorithm, sizeof(algorithm));
if(result || strcmp(algorithm, "md5-sess") != 0) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
if(!result)
state(conn, SMTP_AUTH_CANCEL);
}
else {
/* Create the response message */
result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user,
conn->passwd, "smtp",
&rplyb64, &len);
result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
conn->user, conn->passwd,
"smtp", &rplyb64, &len);
if(!result && rplyb64) {
/* Send the response */
if(!result) {
if(rplyb64) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
if(!result)
state(conn, SMTP_AUTH_DIGESTMD5_RESP);
}
}
Curl_safefree(rplyb64);
}
return result;
}
@@ -1047,19 +1126,16 @@ static CURLcode smtp_state_auth_ntlm_resp(struct connectdata *conn,
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
&conn->ntlm,
&type1msg, &len);
if(!result && type1msg) {
/* Send the message */
if(!result) {
if(type1msg) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type1msg);
if(!result)
state(conn, SMTP_AUTH_NTLM_TYPE2MSG);
}
}
Curl_safefree(type1msg);
}
}
return result;
}
@@ -1071,6 +1147,7 @@ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *type2msg = NULL;
char *type3msg = NULL;
size_t len = 0;
@@ -1081,25 +1158,34 @@ static CURLcode smtp_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
result = CURLE_LOGIN_DENIED;
}
else {
/* Create the type-3 message */
result = Curl_sasl_create_ntlm_type3_message(data,
data->state.buffer + 4,
conn->user, conn->passwd,
&conn->ntlm,
&type3msg, &len);
/* Get the type-2 message */
smtp_get_message(data->state.buffer, &type2msg);
/* Decode the type-2 message */
result = Curl_sasl_decode_ntlm_type2_message(data, type2msg, &conn->ntlm);
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 */
if(!result) {
if(type3msg) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", type3msg);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
}
}
Curl_safefree(type3msg);
}
}
return result;
}
@@ -1125,24 +1211,36 @@ static CURLcode smtp_state_auth_xoauth2_resp(struct connectdata *conn,
result = Curl_sasl_create_xoauth2_message(conn->data, conn->user,
conn->xoauth2_bearer,
&xoauth, &len);
if(!result && xoauth) {
/* Send the message */
if(!result) {
if(xoauth) {
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", xoauth);
if(!result)
state(conn, SMTP_AUTH_FINAL);
}
}
Curl_safefree(xoauth);
}
}
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,
int smtpcode,
smtpstate instate)
@@ -1163,26 +1261,68 @@ static CURLcode smtp_state_auth_final_resp(struct connectdata *conn,
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 */
static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct SMTP *smtp = data->req.protop;
(void)instate; /* no use for this yet */
if(smtpcode/100 != 2) {
failf(data, "MAIL failed: %d", smtpcode);
result = CURLE_SEND_ERROR;
state(conn, SMTP_STOP);
}
else {
smtp->rcpt = data->set.mail_rcpt;
else
/* Start the RCPT TO command */
result = smtp_perform_rcpt_to(conn);
}
return result;
}
@@ -1200,24 +1340,21 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
if(smtpcode/100 != 2) {
failf(data, "RCPT failed: %d", smtpcode);
result = CURLE_SEND_ERROR;
state(conn, SMTP_STOP);
}
else {
if(smtp->rcpt) {
smtp->rcpt = smtp->rcpt->next;
if(smtp->rcpt)
/* Send the next RCPT TO command */
result = smtp_perform_rcpt_to(conn);
/* If we failed or still are sending RCPT data then return */
if(result || smtp->rcpt)
return result;
}
else {
/* Send the DATA command */
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
if(!result)
state(conn, SMTP_DATA);
}
}
return result;
}
@@ -1226,15 +1363,16 @@ static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
smtpstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
(void)instate; /* no use for this yet */
if(smtpcode != 354) {
state(conn, SMTP_STOP);
return CURLE_SEND_ERROR;
failf(data, "DATA failed: %d", smtpcode);
result = CURLE_SEND_ERROR;
}
else {
/* Set the progress upload size */
Curl_pgrsSetUploadSize(data, data->set.infilesize);
@@ -1243,8 +1381,9 @@ static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
/* End of DO phase */
state(conn, SMTP_STOP);
}
return CURLE_OK;
return result;
}
/* 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)
return Curl_pp_flushsend(pp);
do {
/* Read the response from the server */
result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
if(result)
return result;
/* Store the latest response for later retrieval */
if(smtpc->state != SMTP_QUIT)
/* Store the latest response for later retrieval if necessary */
if(smtpc->state != SMTP_QUIT && smtpcode != 1)
data->info.httpcode = smtpcode;
if(smtpcode) {
if(!smtpcode)
break;
/* We have now received a full SMTP server response */
switch(smtpc->state) {
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);
break;
case SMTP_AUTH_CANCEL:
result = smtp_state_auth_cancel_resp(conn, smtpcode, smtpc->state);
break;
case SMTP_AUTH_FINAL:
result = smtp_state_auth_final_resp(conn, smtpcode, smtpc->state);
break;
case SMTP_COMMAND:
result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
break;
case SMTP_MAIL:
result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
break;
@@ -1381,7 +1531,7 @@ static CURLcode smtp_statemach_act(struct connectdata *conn)
state(conn, SMTP_STOP);
break;
}
}
} while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
return result;
}
@@ -1521,7 +1671,7 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
conn->bits.close = TRUE; /* marked for closure */
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
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. */
@@ -1560,6 +1710,9 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
result = smtp_block_statemach(conn);
}
/* Cleanup our per-request based variables */
Curl_safefree(smtp->custom);
/* Clear the transfer mode for the next request */
smtp->transfer = FTPTRANSFER_BODY;
@@ -1570,31 +1723,41 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
*
* smtp_perform()
*
* This is the actual DO function for SMTP. Send a mail according to the
* options previously setup.
* This is the actual DO function for SMTP. Transfer a mail, send a command
* or get some data according to the options previously setup.
*/
static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
bool *dophase_done)
{
/* This is SMTP and no proxy */
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct SMTP *smtp = data->req.protop;
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 */
struct SMTP *smtp = conn->data->req.protop;
smtp->transfer = FTPTRANSFER_INFO;
}
*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 */
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)
return result;
/* run the state-machine */
/* Run the state-machine */
result = smtp_multi_statemach(conn, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
@@ -1620,6 +1783,11 @@ static CURLcode smtp_do(struct connectdata *conn, bool *done)
*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);
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
* resources. BLOCKING.
*/
static CURLcode smtp_disconnect(struct connectdata *conn,
bool dead_connection)
static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
{
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
point! */
if(!dead_connection && smtpc->pp.conn)
if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
if(!smtp_perform_quit(conn))
(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);
}
/***********************************************************************
*
* 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)
{
/* When sending a SMTP payload we must detect CRLF. sequences making sure

View File

@@ -45,7 +45,9 @@ typedef enum {
SMTP_AUTH_NTLM,
SMTP_AUTH_NTLM_TYPE2MSG,
SMTP_AUTH_XOAUTH2,
SMTP_AUTH_CANCEL,
SMTP_AUTH_FINAL,
SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */
SMTP_MAIL, /* MAIL FROM */
SMTP_RCPT, /* RCPT TO */
SMTP_DATA,
@@ -60,6 +62,7 @@ typedef enum {
used. */
struct SMTP {
curl_pp_transfer transfer;
char *custom; /* Custom Request */
struct curl_slist *rcpt; /* Recipient list */
size_t eob; /* Number of bytes of the EOB (End Of Body) that
have been received so far */

View File

@@ -129,6 +129,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
curlx_nonblock(sock, FALSE);
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
/*
* Compose socks4 request
*
@@ -182,6 +184,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
else
hp = NULL; /* fail! */
infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
}

View File

@@ -754,7 +754,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
curlx_uztoui(strlen(conn->user)));
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) {
rc = LIBSSH2_ERROR_EAGAIN;
break;
@@ -2719,6 +2725,10 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
CURLcode result;
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
function to make the re-use checks properly be able to check this bit. */
conn->bits.close = FALSE;

View File

@@ -611,6 +611,9 @@ int Curl_ssl_init_certinfo(struct SessionHandle * data,
return 0;
}
/*
* 'value' is NOT a zero terminated string
*/
CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
int certnum,
const char *label,
@@ -621,12 +624,22 @@ CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data,
char * output;
struct curl_slist * nl;
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 = curl_maprintf("%s:%.*s", label, valuelen, value);
output = malloc(outlen);
if(!output)
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);
if(!nl) {
free(output);

View File

@@ -1431,19 +1431,12 @@ ossl_connect_step1(struct connectdata *conn,
switch(data->set.ssl.version) {
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:
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);
break;
case CURL_SSLVERSION_SSLv2:
@@ -1556,9 +1549,51 @@ ossl_connect_step1(struct connectdata *conn,
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
/* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT:
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);

View File

@@ -1256,7 +1256,7 @@ static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
if(*dophase_done) {
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
provide it for TFTP since it may do the entire transfer in this
state. */

View File

@@ -1309,10 +1309,11 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
Curl_pgrsStartNow(data);
if(data->set.timeout)
Curl_expire(data, data->set.timeout);
Curl_expire(data, data->set.timeout + MULTI_TIMEOUT_INACCURACY_MS);
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 the session we need to make sure we only use the one(s) we now

132
lib/url.c
View File

@@ -299,13 +299,11 @@ static CURLcode setstropt(char **charp, char *s)
return CURLE_OK;
}
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
char **optionsp)
static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
{
CURLcode result = CURLE_OK;
char *user = NULL;
char *passwd = NULL;
char *options = NULL;
/* Parse the login details if specified. It not then we treat NULL as a hint
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),
(userp ? &user : NULL),
(passwdp ? &passwd : NULL),
(optionsp ? &options : NULL));
NULL);
}
if(!result) {
@@ -335,12 +333,6 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
Curl_safefree(*passwdp);
*passwdp = passwd;
}
/* Store the options part of option if required */
if(optionsp) {
Curl_safefree(*optionsp);
*optionsp = options;
}
}
return result;
@@ -1553,13 +1545,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
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 *),
&data->set.str[STRING_USERNAME],
&data->set.str[STRING_PASSWORD],
&data->set.str[STRING_OPTIONS]);
&data->set.str[STRING_PASSWORD]);
break;
case CURLOPT_USERNAME:
/*
* 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],
va_arg(param, char *));
break;
case CURLOPT_PASSWORD:
/*
* 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],
va_arg(param, char *));
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:
/*
* 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],
va_arg(param, char *));
break;
case CURLOPT_POSTQUOTE:
/*
* 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 *),
&data->set.str[STRING_PROXYUSERNAME],
&data->set.str[STRING_PROXYPASSWORD], NULL);
&data->set.str[STRING_PROXYPASSWORD]);
break;
case CURLOPT_PROXYUSERNAME:
/*
@@ -1926,7 +1929,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.ssl.fsslctxp = va_arg(param, void *);
break;
#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:
data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
break;
@@ -2502,6 +2506,10 @@ static void conn_free(struct connectdata *conn)
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
if(CURL_SOCKET_BAD != 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)
Curl_ntlm_wb_cleanup(conn);
@@ -3219,9 +3227,12 @@ static CURLcode ConnectionStore(struct SessionHandle *data,
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;
switch(conn->proxytype) {
@@ -3252,49 +3263,6 @@ CURLcode Curl_connected_proxy(struct connectdata *conn)
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
*/
@@ -3561,6 +3529,8 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
conn->sock[FIRSTSOCKET] = 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->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,
const char *user, const char *passwd,
@@ -5598,41 +5568,10 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
is later set again for the progress meter purpose */
conn->now = Curl_tvnow();
for(;;) {
/* loop for CURL_SERVER_CLOSED_CONNECTION */
if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
/* Try to connect only if not already connected */
bool connected = FALSE;
result = ConnectPlease(data, conn, &connected);
if(result && !conn->ip_addr) {
/* transport connection failure not related with authentication */
conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
return result;
}
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)
result = Curl_connecthost(conn, conn->dns_entry);
if(result)
return result;
}
else {
@@ -5640,11 +5579,8 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
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;
Curl_verboseconnect(conn);
}
conn->now = Curl_tvnow(); /* time this *after* the connect is done, we

View File

@@ -70,7 +70,7 @@ void Curl_close_connections(struct SessionHandle *data);
#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
service */
CURLcode Curl_connected_proxy(struct connectdata *conn);
CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
#ifdef CURL_DISABLE_VERBOSE_STRINGS
#define Curl_verboseconnect(x) Curl_nop_stmt

View File

@@ -838,6 +838,7 @@ struct connectdata {
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() */
Curl_addrinfo *ip_addr;
Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
/* '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
@@ -889,6 +890,7 @@ struct connectdata {
struct timeval created; /* creation time */
curl_socket_t sock[2]; /* two sockets, the second is used for the data
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
accept() */
Curl_recv *recv[2];
@@ -1635,6 +1637,8 @@ struct SessionHandle {
other dynamic purposes */
struct WildcardData wildcard; /* wildcard download state info */
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)
iconv_t outbound_cd; /* for translating to the network encoding */
iconv_t inbound_cd; /* for translating from the network encoding */

View File

@@ -22,7 +22,7 @@
#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 "urldata.h"
@@ -252,7 +252,7 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
size_t inlength = end - from;
int size = 1;
size_t outlength;
int chsize;
int charsize;
unsigned int wc;
char * buf;
@@ -305,7 +305,7 @@ utf8asn1str(char * * to, int type, const char * from, const char * end)
default: /* case 1: */
wc = (wc << 8) | *(const unsigned char *) from++;
}
chsize = 1;
charsize = 1;
if(wc >= 0x00000080) {
if(wc >= 0x00000800) {
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));
wc = (wc >> 6) | 0x00010000;
chsize++;
charsize++;
}
buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
wc = (wc >> 6) | 0x00000800;
chsize++;
charsize++;
}
buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
wc = (wc >> 6) | 0x000000C0;
chsize++;
charsize++;
}
buf[outlength] = (char) wc;
outlength += chsize;
outlength += charsize;
}
}
buf[outlength] = '\0';
@@ -812,7 +812,9 @@ static void do_pubkey_field(struct SessionHandle *data, int certnum,
output = Curl_ASN1tostr(elem, 0);
if(output) {
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, label, output);
if(!certnum)
infof(data, " %s: %s\n", label, output);
free((char *) output);
}
@@ -845,12 +847,15 @@ static void do_pubkey(struct SessionHandle * data, int certnum,
len--;
if(len > 32)
elem.beg = q; /* Strip leading zero bytes. */
if(!certnum)
infof(data, " RSA Public Key (%lu bits)\n", len);
if(data->set.ssl.certinfo) {
q = curl_maprintf("%lu", len);
if(q) {
Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
free((char *) q);
}
}
/* Generate coefficients. */
do_pubkey_field(data, certnum, "rsa(n)", &elem);
Curl_getASN1Element(&elem, p, pk.end);
@@ -896,6 +901,10 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
size_t i;
size_t j;
if(!data->set.ssl.certinfo)
if(certnum)
return CURLE_OK;
/* Prepare the certificate information for curl_easy_getinfo(). */
/* Extract the certificate ASN.1 elements. */
@@ -905,7 +914,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
ccp = Curl_DNtostr(&cert.subject);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
if(!certnum)
infof(data, "%2d Subject: %s\n", certnum, ccp);
free((char *) ccp);
@@ -913,7 +924,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
ccp = Curl_DNtostr(&cert.issuer);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
if(!certnum)
infof(data, " Issuer: %s\n", ccp);
free((char *) ccp);
@@ -921,18 +934,23 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
version = 0;
for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
version = (version << 8) | *(const unsigned char *) ccp;
if(data->set.ssl.certinfo) {
ccp = curl_maprintf("%lx", version);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
free((char *) ccp);
}
if(!certnum)
infof(data, " Version: %lu (0x%lx)\n", version + 1, version);
/* Serial number. */
ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
if(!certnum)
infof(data, " Serial Number: %s\n", ccp);
free((char *) ccp);
@@ -941,7 +959,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
cert.signatureAlgorithm.end);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
if(!certnum)
infof(data, " Signature Algorithm: %s\n", ccp);
free((char *) ccp);
@@ -949,7 +969,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
ccp = Curl_ASN1tostr(&cert.notBefore, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
if(!certnum)
infof(data, " Start Date: %s\n", ccp);
free((char *) ccp);
@@ -957,7 +979,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
ccp = Curl_ASN1tostr(&cert.notAfter, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
if(!certnum)
infof(data, " Expire Date: %s\n", ccp);
free((char *) ccp);
@@ -966,7 +990,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
cert.subjectPublicKeyAlgorithm.end);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
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, &param, &cert.subjectPublicKey);
free((char *) ccp);
@@ -977,7 +1003,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
ccp = Curl_ASN1tostr(&cert.signature, 0);
if(!ccp)
return CURLE_OUT_OF_MEMORY;
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
if(!certnum)
infof(data, " Signature: %s\n", ccp);
free((char *) ccp);
@@ -987,7 +1015,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
&cp1, &cl1);
if(cc != CURLE_OK)
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
<max 64 base64 characters>\n
.
@@ -1008,7 +1036,9 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
cp2[i] = '\0';
free(cp1);
if(data->set.ssl.certinfo)
Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
if(!certnum)
infof(data, "%s\n", cp2);
free(cp2);
return CURLE_OK;
@@ -1148,4 +1178,4 @@ CURLcode Curl_verifyhost(struct connectdata * conn,
return CURLE_PEER_FAILED_VERIFICATION;
}
#endif /* USE_QSOSSL or USE_GSKIT */
#endif /* USE_QSOSSL or USE_GSKIT or USE_NSS */

View File

@@ -25,7 +25,7 @@
#include "curl_setup.h"
#if defined(USE_QSOSSL) || defined(USE_GSKIT)
#if defined(USE_QSOSSL) || defined(USE_GSKIT) || defined(USE_NSS)
#include "urldata.h"
@@ -125,5 +125,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
CURLcode Curl_verifyhost(struct connectdata * conn,
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 */

View File

@@ -85,6 +85,7 @@ options:
CURLOPT_ISSUERCERT
CURLOPT_KEYPASSWD
CURLOPT_KRBLEVEL
CURLOPT_LOGIN_OPTIONS
CURLOPT_MAIL_FROM
CURLOPT_MAIL_AUTH
CURLOPT_NETRC_FILE
@@ -118,6 +119,7 @@ options:
CURLOPT_USERAGENT
CURLOPT_USERNAME
CURLOPT_USERPWD
CURLOPT_XOAUTH2_BEARER
Else it is the same as for curl_easy_setopt().
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.

View File

@@ -77,7 +77,8 @@ makeOS400IconvCode(char buf[ICONV_ID_SIZE], unsigned int ccsid)
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];
@@ -407,7 +408,7 @@ curl_version_info_ccsid(CURLversion stamp, unsigned int ccsid)
compiler seems to compare string values after substitution. */
#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
/* If caller has been compiled with a new version, error. */
@@ -647,13 +648,15 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
case CURLINFO_SLIST:
ccsid = va_arg(arg, unsigned int);
if(info == CURLINFO_CERTINFO) {
switch (info) {
case CURLINFO_CERTINFO:
cipf = *(struct curl_certinfo * *) paramp;
if(cipf) {
if(!(cipt = (struct curl_certinfo *) malloc(sizeof *cipt)))
ret = CURLE_OUT_OF_MEMORY;
else {
cipt->certinfo = (struct curl_slist * *) calloc(cipf->num_of_certs +
cipt->certinfo = (struct curl_slist * *)
calloc(cipf->num_of_certs +
1, sizeof(struct curl_slist *));
if(!cipt->certinfo)
ret = CURLE_OUT_OF_MEMORY;
@@ -677,12 +680,18 @@ curl_easy_getinfo_ccsid(CURL * curl, CURLINFO info, ...)
*(struct curl_certinfo * *) paramp = cipt;
}
}
else {
break;
case CURLINFO_TLS_SESSION:
break;
default:
slp = (struct curl_slist * *) paramp;
if(*slp)
if(!(*slp = slist_convert(ccsid, *slp, ASCII_CCSID)))
ret = CURLE_OUT_OF_MEMORY;
break;
}
}
@@ -763,7 +772,7 @@ Curl_formadd_convert(struct curl_forms * forms,
forms[formx].value = cp;
if(lengthx >= 0)
forms[lengthx].value = (char *) l; /* Update to length after conversion. */
forms[lengthx].value = (char *) l; /* Update length after conversion. */
return l;
}
@@ -1111,11 +1120,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
if(testwarn) {
testwarn = 0;
#ifdef USE_TLS_SRP
if((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
#else
if((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
#endif
if((int) STRING_LAST != (int) STRING_BEARER + 1)
curl_mfprintf(stderr,
"*** 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_KEYPASSWD:
case CURLOPT_KRBLEVEL:
case CURLOPT_LOGIN_OPTIONS:
case CURLOPT_MAIL_FROM:
case CURLOPT_MAIL_AUTH:
case CURLOPT_NETRC_FILE:
@@ -1176,6 +1182,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
case CURLOPT_USERAGENT:
case CURLOPT_USERNAME:
case CURLOPT_USERPWD:
case CURLOPT_XOAUTH2_BEARER:
s = va_arg(arg, char *);
ccsid = va_arg(arg, unsigned int);

View File

@@ -38,13 +38,13 @@ CURL_EXTERN char * curl_easy_unescape_ccsid(CURL * handle, const char * string,
int length, int * outlength,
unsigned int sccsid,
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,
unsigned int ccsid);
CURL_EXTERN time_t curl_getdate_ccsid(const char * p, const time_t * unused,
unsigned int ccsid);
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,
unsigned int ccsid);
CURL_EXTERN const char * curl_share_strerror_ccsid(CURLSHcode error,

View File

@@ -115,6 +115,8 @@
d c X'00004000'
d CURL_VERSION_NTLM_WB...
d c X'00008000'
d CURL_VERSION_HTTP2...
d c X'00010000'
*
d HTTPPOST_FILENAME...
d c X'00000001'
@@ -212,6 +214,8 @@
d c 1
d CURL_HTTP_VERSION_1_1...
d c 2
d CURL_HTTP_VERSION_2_0...
d c 3
*
d CURL_NETRC_IGNORED...
d c 0
@@ -228,6 +232,12 @@
d c 2
d CURL_SSLVERSION_SSLv3...
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 c 0
@@ -1162,6 +1172,16 @@
d c 00218
d CURLOPT_XFERINFOFUNCTION...
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)
d CURLOPT_SSLKEYPASSWD...
@@ -1329,10 +1349,35 @@
d c X'00100029'
d CURLINFO_LOCAL_PORT... CURLINFO_LONG + 42
d c X'0020002A'
d CURLINFO_TLS_SESSION... CURLINFO_SLIST + 43
d c X'0040002B'
*
d CURLINFO_HTTP_CODE... Old ...RESPONSE_CODE
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 s 10i 0 based(######ptr######) Enum
d CURLCLOSEPOLICY_OLDEST...
@@ -1451,7 +1496,9 @@
d c 5
d CURLM_UNKNOWN_OPTION...
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_NONE c 0
@@ -1560,12 +1607,7 @@
d addrlen 10u 0
d addr 16 struct sockaddr
*
d curl_khkey ds based(######ptr######)
d qualified
d key * const char *
d len 10u 0
d keytype 10i 0
*
d curl_khtype s 10i 0 based(######ptr######) enum
d CURLKHTYPE_UNKNOWN...
d c 0
d CURLKHTYPE_RSA1...
@@ -1575,6 +1617,12 @@
d CURLKHTYPE_DSS...
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 qualified
d option like(CURLformoption)
@@ -1622,6 +1670,12 @@
d group * 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 qualified
d filename * char *

View File

@@ -1,6 +1,16 @@
#!/bin/sh
setenv()
{
# Define and export.
eval ${1}="${2}"
export ${1}
}
case "${SCRIPTDIR}" in
/*) ;;
*) SCRIPTDIR="`pwd`/${SCRIPTDIR}"
@@ -32,18 +42,23 @@ export SONAME
#
################################################################################
TARGETLIB='CURL' # Target OS/400 program library
STATBNDDIR='CURL_A' # Static binding directory.
DYNBNDDIR='CURL' # Dynamic binding directory.
SRVPGM="CURL.${SONAME}" # Service program.
TGTCCSID='500' # Target CCSID of objects
DEBUG='*ALL' # Debug level
OPTIMIZE='10' # Optimisation level
OUTPUT='*NONE' # Compilation output option.
TGTRLS='V5R3M0' # Target OS release
setenv TARGETLIB 'CURL' # Target OS/400 program library.
setenv STATBNDDIR 'CURL_A' # Static binding directory.
setenv DYNBNDDIR 'CURL' # Dynamic binding directory.
setenv SRVPGM "CURL.${SONAME}" # Service program.
setenv TGTCCSID '500' # Target CCSID of objects.
setenv DEBUG '*ALL' # Debug level.
setenv OPTIMIZE '10' # Optimisation level
setenv OUTPUT '*NONE' # Compilation output option.
setenv TGTRLS 'V5R3M0' # Target OS release.
setenv IFSDIR '/curl' # Installation IFS directory.
export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM TGTCCSID DEBUG OPTIMIZE OUTPUT
export TGTRLS
# Define ZLIB availability and locations.
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} INCDIR('/qibm/proddata/qadrt/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} OUTPUT(${OUTPUT})"
CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
CMD="${CMD} DBGVIEW(${DEBUG})"
if [ "${3}" ]
then CMD="${CMD} DEFINE(${3})"
DEFINES="${3}"
if [ "${WITH_ZLIB}" != "0" ]
then DEFINES="${DEFINES} HAVE_LIBZ HAVE_ZLIB_H"
fi
if [ "${DEFINES}" ]
then CMD="${CMD} DEFINE(${DEFINES})"
fi
system "${CMD}"
@@ -154,11 +181,17 @@ make_module()
db2_name()
{
basename "${1}" |
if [ "${2}" = 'nomangle' ]
then basename "${1}" |
tr 'a-z-' 'A-Z_' |
sed -e 's/\..*//' \
-e 's/^\(.\).*\(.........\)$/\1\2/'
else basename "${1}" |
tr 'a-z-' 'A-Z_' |
sed -e 's/\..*//' \
-e 's/^CURL_*/C/' \
-e 's/^\(.\).*\(.........\)$/\1\2/'
fi
}

View File

@@ -1,6 +1,6 @@
#!/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}"`
@@ -8,7 +8,7 @@ SCRIPTDIR=`dirname "${0}"`
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
then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
@@ -17,7 +17,7 @@ then if action_needed curl/curlbuild.h curl/curlbuild.h.dist
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"
@@ -28,6 +28,15 @@ then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)"
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
# integers.
@@ -48,16 +57,27 @@ copy_hfile()
# Copy the header files.
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}"
then copy_hfile "${DEST}" "${HFILE}"
IFSDEST="${IFSINCLUDE}/`basename \"${HFILE}\"`"
rm -f "${IFSDEST}"
ln -s "${DEST}" "${IFSDEST}"
fi
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"
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.

View File

@@ -83,12 +83,12 @@ fi
# Gather the list of symbols to export.
EXPORTS=`grep '^CURL_EXTERN[ ]' \
EXPORTS=`grep '^CURL_EXTERN[[:space:]]' \
"${TOPDIR}"/include/curl/*.h \
"${SCRIPTDIR}/ccsidcurl.h" |
sed -e 's/^.*CURL_EXTERN[ ]\(.*\)(.*$/\1/' \
-e 's/[ ]*$//' \
-e 's/^.*[ ][ ]*//' \
sed -e 's/^.*CURL_EXTERN[[:space:]]\(.*\)(.*$/\1/' \
-e 's/[[:space:]]*$//' \
-e 's/^.*[[:space:]][[:space:]]*//' \
-e 's/^\*//' \
-e 's/(\(.*\))/\1/'`
@@ -121,7 +121,11 @@ if [ "${LINK}" ]
then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})"
CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)"
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} TEXT('curl API library')"
CMD="${CMD} TGTRLS(${TGTRLS})"

View File

@@ -28,11 +28,11 @@ eval "`sed -e ': begin' \
-e 's/\\\\\\n/ /' \
-e 'b begin' \
-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 ': keep' \
-e 's/[ ]*=[ ]*/=/' \
-e 's/=\\(.*[^ ]\\)[ ]*$/=\\"\\1\\"/' \
-e 's/[[:space:]]*=[[:space:]]*/=/' \
-e 's/=\\(.*[^[:space:]]\\)[[:space:]]*$/=\\"\\1\\"/' \
-e 's/\\$(\\([^)]*\\))/${\\1}/g' \
< Makefile.inc`"

View File

@@ -38,6 +38,10 @@
#include <qadrt.h>
#include <errno.h>
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#ifdef USE_QSOSSL
#include <qsossl.h>
#endif
@@ -225,8 +229,7 @@ buffer_undef(localkey_t key, long size)
if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
if(!pthread_key_create(&thdkey, thdbufdestroy))
Curl_thread_buffer = buffer_threaded;
else if (!(locbufs = calloc((size_t) LK_LAST,
sizeof *locbufs))) {
else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
pthread_mutex_unlock(&mutex);
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
Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
char * nodename, curl_socklen_t nodenamelen,
@@ -434,23 +459,8 @@ char *
Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp)
{
int i;
char * cp;
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;
return set_thread_string(LK_SSL_ERROR,
SSL_Strerror(sslreturnvalue, serrmsgp));
}
#endif /* USE_QSOSSL */
@@ -825,23 +835,7 @@ const char *
Curl_gsk_strerror_a(int gsk_return_value)
{
int i;
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;
return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
}
int
@@ -954,7 +948,8 @@ Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
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_name_t target_name, gss_OID mech_type,
gss_flags_t req_flags, OM_uint32 time_req,
@@ -1224,8 +1219,8 @@ Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
if(cp)
free(cp);
/* Result data are binary in nature, so they haven't been converted to EBCDIC.
Therefore do not convert. */
/* Result data are binary in nature, so they haven't been
converted to EBCDIC. Therefore do not convert. */
return result;
}
@@ -1235,23 +1230,7 @@ char *
Curl_ldap_err2string_a(int error)
{
int i;
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;
return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
}
@@ -1492,3 +1471,79 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
*addrlen = laddrlen;
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

View File

@@ -39,6 +39,8 @@ typedef enum {
LK_EASY_STRERROR,
LK_SHARE_STRERROR,
LK_MULTI_STRERROR,
LK_ZLIB_VERSION,
LK_ZLIB_MSG,
LK_LAST
} localkey_t;

View File

@@ -32,14 +32,14 @@
#include "memdebug.h" /* keep this as LAST include */
/*
** callback for CURLOPT_PROGRESSFUNCTION
** callback for CURLOPT_XFERINFOFUNCTION
*/
#define MAX_BARLENGTH 256
int tool_progress_cb(void *clientp,
double dltotal, double dlnow,
double ultotal, double ulnow)
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
/* The original progress-bar source code was written for curl by Lars Aas,
and this new edition inherits some of his concepts. */
@@ -60,10 +60,10 @@ int tool_progress_cb(void *clientp,
return 0;
/* 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 */
point = (curl_off_t)dlnow + (curl_off_t)ulnow + bar->initial_size;
point = dlnow + ulnow + bar->initial_size;
if(point > total)
/* we have got more than the expected total! */

View File

@@ -43,8 +43,8 @@ void progressbarinit(struct ProgressData *bar,
*/
int tool_progress_cb(void *clientp,
double dltotal, double dlnow,
double ultotal, double ulnow);
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);
#endif /* HEADER_CURL_TOOL_CB_PRG_H */

View File

@@ -74,6 +74,7 @@ struct Configurable {
0 => -s is used to NOT show errors
1 => -S has been used to show errors */
char *userpwd;
char *login_options;
char *tls_username;
char *tls_password;
char *tls_authtype;

View File

@@ -184,6 +184,9 @@ static const struct LongShort aliases[]= {
{"01", "http1.1", FALSE},
{"02", "http2.0", FALSE},
{"1", "tlsv1", FALSE},
{"10", "tlsv1.0", FALSE},
{"11", "tlsv1.1", FALSE},
{"12", "tlsv1.2", FALSE},
{"2", "sslv2", FALSE},
{"3", "sslv3", FALSE},
{"4", "ipv4", FALSE},
@@ -215,6 +218,7 @@ static const struct LongShort aliases[]= {
{"El", "tlspassword", TRUE},
{"Em", "tlsauthtype", TRUE},
{"En", "ssl-allow-beast", FALSE},
{"Eo", "login-options", TRUE},
{"f", "fail", FALSE},
{"F", "form", TRUE},
{"Fs", "form-string", TRUE},
@@ -1023,10 +1027,26 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
break;
}
break;
case '1':
/* TLS version 1 */
case '1': /* --tlsv1* options */
switch(subletter) {
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;
case '2':
/* SSL version 2 */
config->ssl_version = CURL_SSLVERSION_SSLv2;
@@ -1347,10 +1367,15 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
else
return PARAM_LIBCURL_DOESNT_SUPPORT;
break;
case 'n': /* no empty SSL fragments */
case 'n': /* no empty SSL fragments, --ssl-allow-beast */
if(curlinfo->features & CURL_VERSION_SSL)
config->ssl_allow_beast = toggle;
break;
case 'o': /* --login-options */
GetStr(&config->login_options, nextarg);
break;
default: /* certificate file */
{
char *certname, *passphrase;
@@ -1668,7 +1693,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
}
break;
case 'u':
/* user:password;options */
/* user:password */
GetStr(&config->userpwd, nextarg);
cleanarg(nextarg);
break;

View File

@@ -120,7 +120,7 @@ static const char *const helptext[] = {
" --libcurl FILE Dump libcurl equivalent code of this command line",
#endif
" --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",
" -L, --location Follow redirects (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)",
" --noproxy List of hosts which do not use proxy",
" --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",
" --pass PASS Pass phrase for the private key (SSL/SSH)",
" --post301 "
@@ -215,7 +215,8 @@ static const char *const helptext[] = {
" -T, --upload-file FILE Transfer FILE to destination",
" --url URL URL to work with",
" -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",
" --tlspassword STRING TLS password",
" --tlsauthtype STRING TLS authentication type (default SRP)",

View File

@@ -54,9 +54,7 @@
# define MD5_CTX void *
# define SHA_CTX void *
# define SHA256_CTX void *
# ifdef HAVE_NSS_INITCONTEXT
static NSSInitContext *nss_context;
# endif
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
@@ -240,7 +238,6 @@ static int nss_hash_init(void **pctx, SECOidTag hash_alg)
PK11Context *ctx;
/* we have to initialize NSS if not initialized alraedy */
#ifdef HAVE_NSS_INITCONTEXT
if(!NSS_IsInitialized() && !nss_context) {
static NSSInitParameters 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_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
}
#endif
ctx = PK11_CreateDigestContext(hash_alg);
if(!ctx)
@@ -894,7 +890,7 @@ void clean_metalink(struct Configurable *config)
void metalink_cleanup(void)
{
#if defined(USE_NSS) && defined(HAVE_NSS_INITCONTEXT)
#ifdef USE_NSS
if(nss_context) {
NSS_ShutdownContext(nss_context);
nss_context = NULL;

View File

@@ -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_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_RANGE, config->range);
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) {
/* we want the alternative style, then we have to implement it
ourselves! */
my_setopt(curl, CURLOPT_PROGRESSFUNCTION, tool_progress_cb);
my_setopt(curl, CURLOPT_PROGRESSDATA, &progressbar);
my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
my_setopt(curl, CURLOPT_XFERINFODATA, &progressbar);
}
/* new in libcurl 7.24.0: */

View File

@@ -35,7 +35,10 @@
#include "memdebug.h" /* keep this as LAST include */
#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 char *my_get_line(FILE *fp);
@@ -123,6 +126,7 @@ int parseconfig(const char *filename,
char *param;
int lineno = 0;
bool alloced_param;
bool dashed_option;
while(NULL != (aline = my_get_line(file))) {
lineno++;
@@ -146,7 +150,11 @@ int parseconfig(const char *filename,
/* the option keywords starts here */
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++;
/* ... and has ended here */
@@ -158,7 +166,7 @@ int parseconfig(const char *filename,
#endif
/* pass spaces and separator(s) */
while(*line && (ISSPACE(*line) || ISSEP(*line)))
while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option)))
line++;
/* the parameter starts here (unless quoted) */
@@ -180,6 +188,24 @@ int parseconfig(const char *filename,
while(*line && !ISSPACE(*line))
line++;
*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) {

View File

@@ -78,6 +78,9 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = {
NV(CURL_SSLVERSION_TLSv1),
NV(CURL_SSLVERSION_SSLv2),
NV(CURL_SSLVERSION_SSLv3),
NV(CURL_SSLVERSION_TLSv1_0),
NV(CURL_SSLVERSION_TLSv1_1),
NV(CURL_SSLVERSION_TLSv1_2),
NVEND,
};

View File

@@ -40,7 +40,7 @@ typedef enum {
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];
pat->type = UPTSet;
@@ -48,17 +48,18 @@ static GlobCode glob_fixed(URLGlob *glob, unsigned long *amount)
pat->content.Set.ptr_s = 0;
pat->globindex = -1;
(*amount)++;
pat->content.Set.elements = malloc(sizeof(char*));
if(!pat->content.Set.elements)
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])
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;
}
@@ -211,7 +212,7 @@ static GlobCode glob_range(URLGlob *glob, char **patternp,
}
}
else
pattern+=3;
pattern += 4;
*posp += (pattern - *patternp);
@@ -307,11 +308,13 @@ static GlobCode glob_parse(URLGlob *glob, char *pattern,
/* processes a literal string component of a URL
special characters '{' and '[' branch to set/range processing functions
*/
char* buf = glob->glob_buffer;
GlobCode res = GLOB_OK;
int globindex = 0; /* count "actual" globs */
*amount = 1;
while(*pattern && !res) {
char *buf = glob->glob_buffer;
int sublen = 0;
while(*pattern && *pattern != '{' && *pattern != '[') {
if(*pattern == '}' || *pattern == ']')
@@ -333,12 +336,9 @@ static GlobCode glob_parse(URLGlob *glob, char *pattern,
if(sublen) {
/* we got a literal string, add it as a single-item list */
*buf = '\0';
res = glob_fixed(glob, amount);
res = glob_fixed(glob, glob->glob_buffer, sublen);
}
else {
if(!*amount)
*amount = 1;
switch (*pattern) {
case '\0': /* done */
break;

View File

@@ -3,6 +3,8 @@
# per line.
# Lines starting with '#' letters are treated as comments.
594
815
816
1209
1211
1512

View File

@@ -64,14 +64,19 @@ test700 test701 test702 test703 test704 test705 test706 test707 test708 \
test709 test710 test711 test712 \
\
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 \
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 \
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 \
test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \
@@ -96,12 +101,12 @@ test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
test1216 test1217 test1218 test1219 \
test1220 test1221 test1222 test1223 test1224 test1225 test1226 test1227 \
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 \
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
test1316 test1317 test1318 test1319 test1320 test1321 test1322 test1323 \
test1324 test1325 test1326 test1327 test1328 test1329 test1330 test1331 \
test1316 test1317 test1318 test1319 test1320 test1321 \
test1325 test1326 test1327 test1328 test1329 test1330 test1331 \
test1332 test1333 test1334 test1335 test1336 test1337 test1338 test1339 \
test1340 test1341 test1342 test1343 test1344 test1345 test1346 test1347 \
test1348 test1349 test1350 test1351 test1352 test1353 test1354 test1355 \

48
tests/data/test1240 Normal file
View 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>

View File

@@ -27,7 +27,7 @@ imap
IMAP doesn't perform SELECT if re-using the same mailbox
</name>
<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>
</client>

Some files were not shown because too many files have changed in this diff Show More