Compare commits

..

219 Commits

Author SHA1 Message Date
Daniel Stenberg
202aa9f775 dist: two cmake files are no more
CMake/FindOpenSSL.cmake and FindZLIB.cmake are gone since 14aa8f0c11
2014-09-10 08:07:58 +02:00
Daniel Stenberg
9636fc2588 RELEASE-NOTES: final update for 7.38.0 2014-09-10 07:34:36 +02:00
Daniel Stenberg
a76825a5ef cookies: reject incoming cookies set for TLDs
Test 61 was modified to verify this.

CVE-2014-3620

Reported-by: Tim Ruehsen
URL: http://curl.haxx.se/docs/adv_20140910B.html
2014-09-10 07:32:36 +02:00
Tim Ruehsen
8a75dbeb23 cookies: only use full host matches for hosts used as IP address
By not detecting and rejecting domain names for partial literal IP
addresses properly when parsing received HTTP cookies, libcurl can be
fooled to both send cookies to wrong sites and to allow arbitrary sites
to set cookies for others.

CVE-2014-3613

Bug: http://curl.haxx.se/docs/adv_20140910A.html
2014-09-10 07:32:36 +02:00
Daniel Stenberg
1ccfabb66d HISTORY: fix the 1998 title position 2014-09-10 00:40:11 +02:00
Daniel Stenberg
40bcd5447c HISTORY: extended and now markdown 2014-09-10 00:34:32 +02:00
Daniel Stenberg
4455f1f599 SSLCERTS: converted to markdown
Only minor edits to make it generate nice HTML output using markdown, as
this document serves both in source release tarballs as on the web site.

URL: http://curl.haxx.se/docs/sslcerts.html
2014-09-09 23:46:58 +02:00
Daniel Stenberg
9e6c3638e6 ftp-wildcard.c: spell fix
Reported-By: Frank Gevaerts
2014-09-09 11:10:18 +02:00
Daniel Stenberg
fa50d9d96d RELEASE-NOTES: synced with 921a0c22a6 2014-09-08 10:26:43 +02:00
Daniel Stenberg
38ced24ad1 THANKS: synced with RELEASE-NOTES for 921a0c22a6 2014-09-08 10:26:32 +02:00
Daniel Stenberg
921a0c22a6 polarassl: avoid memset() when clearing the first byte is enough 2014-09-08 10:11:34 +02:00
Catalin Patulea
af45542cfe polarssl: support CURLOPT_CAPATH / --capath
Signed-off-by: Catalin Patulea <cat@vv.carleton.ca>
2014-09-08 10:09:54 +02:00
Daniel Stenberg
55f8b03948 SECURITY: eh, make more sense! 2014-09-08 10:00:18 +02:00
Daniel Stenberg
55d6cba5e1 SECURITY: how to join the curl-security list 2014-09-08 09:39:14 +02:00
Daniel Stenberg
3963adca3d RELEASE-NOTES: fix the required nghttp2 version typo 2014-09-08 00:12:18 +02:00
Brandon Casey
6beb0eeea1 Ensure progress.size_dl/progress.size_ul are always >= 0
Historically the default "unknown" value for progress.size_dl and
progress.size_ul has been zero, since these values are initialized
implicitly by the calloc that allocates the curl handle that these
variables are a part of.  Users of curl that install progress
callbacks may expect these values to always be >= 0.

Currently it is possible for progress.size_dl and progress.size_ul
to by set to a value of -1, if Curl_pgrsSetDownloadSize() or
Curl_pgrsSetUploadSize() are passed a "size" of -1 (which a few
places currently do, and a following patch will add more).  So
lets update Curl_pgrsSetDownloadSize() and Curl_pgrsSetUploadSize()
so they make sure that these variables always contain a value that
is >= 0.

Updates test579 and test599.

Signed-off-by: Brandon Casey <drafnel@gmail.com>
2014-09-07 23:23:12 +02:00
Steve Holme
8acbb074f8 tests: Added test1420 to the makefile 2014-09-07 12:13:34 +01:00
Steve Holme
be83356e5e test1420: Removed unnecessary CURLOPT setting 2014-09-07 12:09:29 +01:00
Steve Holme
797d56cbd8 tests: Added more "Clear Text" authentication keywords 2014-09-07 11:37:10 +01:00
Steve Holme
9ee502ac6b tests: Updated "based on" text due to email test renumbering 2014-09-07 11:19:10 +01:00
Steve Holme
ed285ae5c9 tests: For consistency added --libcurl to test name 2014-09-07 11:19:08 +01:00
Steve Holme
436a841354 tests: Added --libcurl for IMAP test case 2014-09-07 11:19:05 +01:00
Steve Holme
4a6fa4c204 multi.c: Avoid invalid memory read after free() from commit 3c8c873252
As the current element in the list is free()d by Curl_llist_remove(),
when the associated connection is pending, reworked the loop to avoid
accessing the next element through e->next afterward.
2014-09-07 07:11:14 +01:00
Steve Holme
c25cd9094b multi.c: Fixed compilation warning from commit 3c8c873252
warning: implicit conversion from enumeration type 'CURLMcode' to
different enumeration type 'CURLcode'
2014-09-07 00:21:36 +01:00
Steve Holme
21db158722 url.c: Use CURLAUTH_NONE constant rather than 0
Small follow up to commit 898808fa8c to use auth constants rather than
hard code value when clearing picked authentication mechanism.
2014-09-06 22:23:54 +01:00
Steve Holme
e40197315d RELEASE-NOTES: Synced with fd1ce3856a 2014-09-06 21:48:40 +01:00
Vilmos Nebehaj
fd1ce3856a darwinssl: Use CopyCertSubject() to check CA cert.
SecCertificateCopyPublicKey() is not available on iPhone. Use
CopyCertSubject() instead to see if the certificate returned by
SecCertificateCreateWithData() is valid.

Reported-by: Toby Peterson
2014-09-04 19:00:02 -05:00
Steve Holme
c6ee182bd4 RELEASE-NOTES: Clarify email Kerberos support is currently via Windows SSPI 2014-09-04 22:04:50 +01:00
Daniel Stenberg
4989695ec3 MAIL-ETIQUETTE: "1.8 I posted, now what?" 2014-09-04 08:57:28 +02:00
Daniel Stenberg
0b48d1c821 CURLOPT_CA*: better refering between *CAINFO and *CAPATH
... and a minor wording edit
2014-09-03 23:04:52 +02:00
Daniel Stenberg
9e50d8f8bc THANKS: added Dennis Clarke
Dennis Clarke from Blastwave.org for ensuring that nightly builds run
smooth on Solaris!
2014-09-03 22:08:25 +02:00
Daniel Stenberg
a6c48c8be7 curl_multi_cleanup: remove superfluous NULL assigns
... as the struct is free()d in the end anyway. It was first pointed out
to me that one of the ->msglist assignments were supposed to have been
->pending but was a copy and paste mistake when I realized none of the
clearing of pointers had to be there.
2014-09-02 23:44:42 +02:00
Daniel Stenberg
3c8c873252 multi: convert CURLM_STATE_CONNECT_PEND handling to a list
... instead of scanning through all handles, stash only the actual
handles that are in that state in the new ->pending list and scan that
list only. It should be mostly empty or very short. And only used for
pipelining.

This avoids a rather hefty slow-down especially notable if you add many
handles to the same multi handle. Regression introduced in commit
0f147887 (version 7.30.0).

Bug: http://curl.haxx.se/mail/lib-2014-07/0206.html
Reported-by: David Meyer
2014-09-02 10:17:47 +02:00
Daniel Stenberg
4901ec2324 RELEASE-NOTES: synced with e608324f9f 2014-09-01 22:54:52 +02:00
Andre Heinecke
e608324f9f polarssl: implement CURLOPT_SSLVERSION
Forwards the setting as minimum ssl version (if set) to polarssl.  If
the server does not support the requested version the SSL Handshake will
fail.

Bug: http://curl.haxx.se/bug/view.cgi?id=1419
2014-09-01 22:42:58 +02:00
nickzman
0c14b31df4 Merge pull request #115 from ldx/darwinsslfixpr
darwinssl: now accepts cacert bundles in PEM format in addition to single certs
2014-09-01 15:33:43 -05:00
Vilmos Nebehaj
0426670f0a Check CA certificate in curl_darwinssl.c.
SecCertificateCreateWithData() returns a non-NULL SecCertificateRef even
if the buffer holds an invalid or corrupt certificate. Call
SecCertificateCopyPublicKey() to make sure cacert is a valid
certificate.
2014-09-01 00:34:37 +02:00
Daniel Stenberg
cacdc27f52 low-speed-limit: avoid timeout flood
Introducing Curl_expire_latest(). To be used when we the code flow only
wants to get called at a later time that is "no later than X" so that
something can be checked (and another timeout be added).

The low-speed logic for example could easily be made to set very many
expire timeouts if it would be called faster or sooner than what it had
set its own timer and this goes for a few other timers too that aren't
explictiy checked for timer expiration in the code.

If there's no condition the code that says if(time-passed >= TIME), then
Curl_expire_latest() is preferred to Curl_expire().

If there exists such a condition, it is on the other hand important that
Curl_expire() is used and not the other.

Bug: http://curl.haxx.se/mail/lib-2014-06/0235.html
Reported-by: Florian Weimer
2014-08-31 23:50:01 +02:00
Michael Wallner
09b5a99816 resolve: cache lookup for async resolvers
While waiting for a host resolve, check if the host cache may have
gotten the name already (by someone else), for when the same name is
resolved by several simultanoues requests.

The resolver thread occasionally gets stuck in getaddrinfo() when the
DNS or anything else is crappy or slow, so when a host is found in the
DNS cache, leave the thread alone and let itself cleanup the mess.
2014-08-31 10:49:40 +02:00
Vilmos Nebehaj
4c134bcfce Fix CA certificate bundle handling in darwinssl.
If the --cacert option is used with a CA certificate bundle that
contains multiple CA certificates, iterate through it, adding each
certificate as a trusted root CA.
2014-08-30 20:10:07 +02:00
Askar Safin
2434a4e88d getinfo-times: Typo fixed 2014-08-29 16:41:17 +02:00
Askar Safin
c9a981778d libcurl.3: Typo fixed 2014-08-29 16:41:11 +02:00
Daniel Stenberg
367b784738 curl_formadd.3: setting CURLFORM_CONTENTSLENGTH 0 zero means strlen 2014-08-29 08:10:38 +02:00
Daniel Stenberg
7bff23b166 curl.1: add an example for -H 2014-08-29 08:07:47 +02:00
Daniel Stenberg
accbbd7dc3 FAQ: mention -w in the 4.20 answer as well 2014-08-28 11:42:00 +02:00
Daniel Stenberg
889de6b285 FAQ: 4.20 curl doesn't return error for HTTP non-200 responses 2014-08-28 11:39:39 +02:00
Daniel Stenberg
1d30f40950 CURLOPT_NOBODY.3: clarify this option is for downloads
When enabling CURLOPT_NOBODY, libcurl effectively switches off upload
mode and will do a download (without a body). This is now better
explained in this man page.

Bug: http://curl.haxx.se/mail/lib-2014-08/0236.html
Reported-by: John Coffey
2014-08-28 00:11:09 +02:00
Daniel Stenberg
1cd5008bba INTERNALS: nghttp2 must be 0.6.0 or later 2014-08-26 23:05:26 +02:00
Tatsuhiro Tsujikawa
da933ee29d Compile with latest nghttp2 2014-08-26 23:02:50 +02:00
Dan Fandrich
d4a4a42cb3 THANKS: removed a few more duplicates 2014-08-26 00:38:17 +02:00
Daniel Stenberg
11bb05ba48 RELEASE-NOTES: synced with 0072422576
... and bumped the contributor amount after recount
2014-08-26 00:02:52 +02:00
Daniel Stenberg
0072422576 THANKS: added 52 missing contributors
I re-ran contributors.sh on all changes since 7.10 and I found these
contributors who are mentioned in the commits but never were added to
THANKS before!

I also removed a couple of duplicates (mostly due to different
spellings).
2014-08-25 23:22:40 +02:00
Daniel Stenberg
dfd821c738 contributors: grep and sort case insensitively 2014-08-25 23:09:23 +02:00
Michael Osipov
ee40b6882d configure.ac: Add support for recent GSS-API implementations for HP-UX
By default, configure script assumes that libcurl will use the
HP-supplied GSS-API implementation which does not have krb5-config.
If a dev needs a more recent version which has that config script,
the change will allow to pass an appropriate GSSAPI_ROOT.
2014-08-25 15:09:26 +02:00
Daniel Stenberg
36a7638073 CONNECT: close proxy connections that fail to CONNECT
This is usually due to failed auth. There's no point in us keeping such
a connection alive since it shouldn't be re-used anyway.

Bug: http://curl.haxx.se/bug/view.cgi?id=1381
Reported-by: Marcel Raad
2014-08-25 13:33:34 +02:00
Daniel Stenberg
2603618831 RELEASE-NOTES: added two missing HTTP/2 bug fixes
And renamed all http2 references to HTTP/2 in this file
2014-08-25 12:59:28 +02:00
Daniel Stenberg
b17b4b4a4a RELEASE-NOTES: synced with f646e9075f 2014-08-25 12:53:08 +02:00
Jakub Zakrzewski
f646e9075f Cmake: Possibility to use OpenLDAP, OpenSSL, LibSSH2 on windows
At this point I can build libcurl on windows. It provides at least the same
list of protocols as for linux build and works with our software.
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
ba8795083f Cmake: Removed repeated content from ending blocks
They are unnecesary in modern CMake and removing them improves readability.
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
06de7d6936 Cmake: Removed some useless empty SET statements.
Undefined variables resolve to empty strings and we do not ever test if
the variable is defined thus those SETs are superfluous.
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
febcfab23d Cmake: Removed useless comments from CMakeLists.txt
They look like some relics after changes.
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
1269df2e3b Cmake: Don't check for all headers each time
One header at a time is the right way. Apart from that the output on
windows goes from:
...
-- Looking for include files I:/src/libssh2-1.4.3/include/libssh2.h, ws2tcpip.h
-- Looking for include files I:/src/libssh2-1.4.3/include/libssh2.h, ws2tcpip.h
- found
-- Looking for 3 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wins
ock2.h
-- Looking for 3 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wins
ock2.h - found
-- Looking for 4 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., stdi
o.h
-- Looking for 4 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., stdi
o.h - found
-- Looking for 5 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wind
ows.h
-- Looking for 5 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wind
ows.h - found
-- Looking for 6 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wins
ock.h
-- Looking for 6 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., wins
ock.h - found
-- Looking for 7 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., sys/
filio.h
-- Looking for 7 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., sys/
filio.h - not found
-- Looking for 7 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., sys/
ioctl.h
-- Looking for 7 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., sys/
ioctl.h - not found
-- Looking for 7 include files I:/src/libssh2-1.4.3/include/libssh2.h, ..., sys/
resource.h
...

To much nicer:
...
-- Looking for ws2tcpip.h
-- Looking for ws2tcpip.h - found
-- Looking for winsock2.h
-- Looking for winsock2.h - found
-- Looking for stdio.h
-- Looking for stdio.h - found
-- Looking for windows.h
-- Looking for windows.h - found
-- Looking for winsock.h
-- Looking for winsock.h - found
-- Looking for sys/filio.h
-- Looking for sys/filio.h - not found
-- Looking for sys/ioctl.h
-- Looking for sys/ioctl.h - not found
-- Looking for sys/resource.h
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
dda86f386d Cmake: Append OpenSSL include directory to search path
At this point I can build libcurl with OpenSSL, OpenLDAP and LibSSH2.
Supported protocols are at least:
HTTP, HTTPS, FTP, SFTP, TFTP, LDAP, LDAPS, POP3, SMTP
(those are the ones we have regression tests for
in our product's testsuite)
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
7320e53d9e Cmake: Search for liblber, LDAP SSL headers, swith for using OpenLDAP code. 2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
118977f19d Cmake: LibSSH2 detection and use. 2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
88c17d5587 Cmake: Moved macros out of the main CMakeLists.txt 2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
73a1a639a7 Cmake: Added missing protocol-disable switches
They already have their defines in config.h. This makes it possible to
disable the protocols from command line during configure step.
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
8f4da2965e Cmake: Made boolean defines be defined to "1" instead of "ON"
It's by convention, for compatibility and because the comments say so.
Just mabe someone have written a test like "#if HAVE_XX==1"
2014-08-25 12:44:24 +02:00
Jakub Zakrzewski
14aa8f0c11 Cmake: Require at least CMake 2.8.
CMake 2.6 is already a bit old. Many bugs have been fixed since
its release. We use 2.8 in our company and we have no intention
of polluting our environment with old software, so 2.6 would
not be tested. This shouldn't be a problem since all one need
to build CMake from source is C and C++ compiler.
2014-08-25 12:44:24 +02:00
Daniel Stenberg
898808fa8c disconnect: don't touch easy-related state on disconnects
This was done to make sure NTLM state that is bound to a connection
doesn't survive and gets used for the subsequent request - but
disconnects can also be done to for example make room in the connection
cache and thus that connection is not strictly related to the easy
handle's current operation.

The http authentication state is still kept in the easy handle since all
http auth _except_ NTLM is connection independent and thus survive over
multiple connections.

Bug: http://curl.haxx.se/mail/lib-2014-08/0148.html
Reported-by: Paras S
2014-08-25 09:17:57 +02:00
Daniel Stenberg
a20da5523e curl.1: clarify --limit-rate's effect on both directions
Bug: http://curl.haxx.se/bug/view.cgi?id=1414
Reported-by: teo8976
2014-08-23 00:40:52 +02:00
Daniel Stenberg
5be48639b1 curl.1: mention the --post30x options within the --location desc 2014-08-23 00:00:00 +02:00
Dan Fandrich
1a073a20db sasl: Fixed a memory leak on OOM 2014-08-22 21:40:05 +02:00
Frank Meier
63a0bd4270 NTLM: ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth
Problem: if CURLOPT_FORBID_REUSE is set, requests using NTLM failed
since NTLM requires multiple requests that re-use the same connection
for the authentication to work

Solution: Ignore the forbid reuse flag in case the NTLM authentication
handshake is in progress, according to the NTLM state flag.

Fixed known bug #77.
2014-08-22 16:05:31 +02:00
Steve Holme
98633c2a19 openssl.c: Fixed longer than 79 columns 2014-08-22 07:44:03 +01:00
Steve Holme
bdfc75e751 openssl.c: Fixed compilation warning
warning: declaration of 'minor' shadows a global declaration
2014-08-21 20:37:29 +01:00
Haris Okanovic
da23624b57 win32: Fixed WinSock 2 #if
A conditionally compiled block in connect.c references WinSock 2
symbols, but used `#ifdef HAVE_WINSOCK_H` instead of `#ifdef
HAVE_WINSOCK2_H`.

Bug: http://curl.haxx.se/mail/lib-2014-08/0155.html
2014-08-21 00:22:33 +02:00
Daniel Stenberg
30f2d0c0b3 Curl_disconnect: don't free the URL
The URL is not a property of the connection so it should not be freed in
the connection disconnect but in the Curl_close() that frees the easy
handle.

Bug: http://curl.haxx.se/mail/lib-2014-08/0148.html
Reported-by: Paras S
2014-08-20 16:37:01 +02:00
Daniel Stenberg
f854130b7b help output: minor whitespace edits
Should've been amended in the previous commit but wasn't due to a
mistake.
2014-08-19 23:45:34 +02:00
Zearin
2f2d84033b help output: use ≥2 spaces between option and description
... and some other cleanups
2014-08-19 23:38:02 +02:00
Daniel Stenberg
b1341b3068 FAQ: some actually sometimes get paid... 2014-08-18 08:38:34 +02:00
Steve Holme
23d52ca4a7 sasl_sspi: Fixed a memory leak with the GSSAPI base-64 decoded challenge 2014-08-17 23:08:55 +01:00
Steve Holme
437b9ba46f sasl_sspi: Renamed GSSAPI mutual authentication parameter
...From "mutual" to "mutual_auth" which better describes what it is.
2014-08-17 23:08:53 +01:00
Steve Holme
f6e15d25a3 sasl_sspi: Corrected some of the GSSAPI security message error codes
Corrected a number of the error codes that can be returned from the
Curl_sasl_create_gssapi_security_message() function when things go
wrong.

It makes more sense to return CURLE_BAD_CONTENT_ENCODING when the
inbound security challenge can't be decoded correctly or doesn't
contain the KERB_WRAP_NO_ENCRYPT flag and CURLE_OUT_OF_MEMORY when
EncryptMessage() fails. Unfortunately the previous error code of
CURLE_RECV_ERROR was a copy and paste mistakes on my part and should
have been correct in commit 4b491c675f :(
2014-08-17 22:38:25 +01:00
Steve Holme
75be5a6681 docs: Escaped single backslash 2014-08-16 11:52:11 +01:00
Steve Holme
c4410c85ab TODO: Updated following GSSAPI (Kerberos V5) additions
Updated "FTP 4.6 GSSAPI via Windows SSPI" and "SASL 14.1 Other
authentication mechanisms" following recent additions.

Added SASL 14.2 GSSAPI via GSS-API libraries.
2014-08-16 11:42:04 +01:00
Steve Holme
97f6049bc2 CURLOPT_USERNAME.3: Added Kerberos V5 and NTLM domain information
This repeats what has already been documented in both the curl manpage
and CURLOPT_USERPWD documentation but is provided here for completeness
as someone may not especially read the latter when using libcurl.
2014-08-16 10:46:57 +01:00
Steve Holme
29240cb5c1 CURLOPT_USERPWD.3: Updated following Kerberos V5 SSPI changes
Added information about Kerberos V5 requiring the domain part in the
user name.

Mentioned that the user name can be specified in UPN format, and not
just in Down-Level Logon Name format, following the information
added in commit 7679cb3fa8 reworking the exisitng information in the
process.
2014-08-16 10:42:31 +01:00
Steve Holme
7679cb3fa8 docs: Added Kerberos V5 and NTLM domain information to --user 2014-08-16 10:37:16 +01:00
Steve Holme
0574196acb docs: Added Kerberos V5 to the --user SSPI current credentials usage 2014-08-16 10:16:05 +01:00
Steve Holme
14b3a2e4c3 sasl_sspi: Tell the server we don't support a GSSAPI receive buffer 2014-08-16 09:18:38 +01:00
Steve Holme
5663272435 smtp: Added support for GSSAPI (Kerberos V5) authentication via Windows SSPI 2014-08-15 21:39:36 +01:00
Steve Holme
03f368d94c pop3: Added support for GSSAPI (Kerberos V5) authentication via Windows SSPI 2014-08-15 21:39:33 +01:00
Steve Holme
96034c4a51 imap: Added support for GSSAPI (Kerberos V5) authentication via Windows SSPI 2014-08-15 21:39:31 +01:00
Steve Holme
078d1fbf2b email: Added mutual authentication flag 2014-08-15 21:32:21 +01:00
Daniel Stenberg
9eba83c156 RELEASE-NOTES: synced with 0187c9e11d 2014-08-15 12:19:20 +02:00
Daniel Stenberg
0187c9e11d http: fix the Content-Range: parser
... to handle "*/[total]". Also, removed the strange hack that made
CURLOPT_FAILONERROR on a 416 response after a *RESUME_FROM return
CURLE_OK.

Reported-by: Dimitrios Siganos
Bug: http://curl.haxx.se/mail/lib-2014-06/0221.html
2014-08-15 10:02:47 +02:00
Steve Holme
472d1d8e05 email: Introduced the GSSAPI states 2014-08-14 20:20:13 +01:00
Steve Holme
629f52843f curl_sasl_sspi.c: Fixed more compilation warnings from commit 4b491c675f
warning: unused variable 'resp'

warning: no previous prototype for 'Curl_sasl_gssapi_cleanup'
2014-08-14 16:03:16 +01:00
Steve Holme
c126bac153 SHA-1: 61c93383b7f6cf79d12ff99e9dced1d1cc2a7064
* curl_sasl_sspi.c: Fixed compilation warning from commit 4b491c675f

warning: declaration of 'result' shadows a previous local
2014-08-14 15:56:13 +01:00
Steve Holme
cff0757c31 curl_sasl.h: Fixed compilation error from commit 4b491c675f
warning: 'struct kerberos5data' declared inside parameter list

Due to missing forward declaration.
2014-08-14 15:53:33 +01:00
Steve Holme
b5c56190b2 urldata.h: Fixed compilation warnings from commit 3ec253532e
warning: extra tokens at end of #endif directive
2014-08-14 12:07:28 +01:00
Steve Holme
4b491c675f sasl_sspi: Added GSSAPI message functions 2014-08-14 10:37:01 +01:00
Steve Holme
3ec253532e urldata: Introduced a GSSAPI (Kerberos V5) data structure
Added a kerberos5data structure which is similar in nature to the
ntlmdata and negotiatedata structures.
2014-08-14 01:29:12 +01:00
Steve Holme
215f932e49 sspi: Moved KERB_WRAP_NO_ENCRYPT from socks_sspi module
In preparation for the upcoming SSPI implementation of GSSAPI
authentication, moved the definition of KERB_WRAP_NO_ENCRYPT from
socks_sspi.c to curl_sspi.h allowing it to be shared amongst other
SSPI based code.
2014-08-14 01:05:52 +01:00
Daniel Stenberg
076c0ab683 mk-ca-bundle.pl: add missing $ 2014-08-13 23:49:01 +02:00
Daniel Stenberg
57b53918d1 mk-ca-bundle.pl: switched to using hg.mozilla.org
... as mxr.mozilla.org is due to be retired.

The new host doesn't support If-Modified-Since nor ETags, meaning that
the script will now defer to download and do a post-transfer checksum
check to see if a new output is to be generated. The new output format
will hold the SHA1 checksum of the source file for that purpose.

We call this version 1.22

Reported-by: Ed Morley
Bug: http://curl.haxx.se/bug/view.cgi?id=1409
2014-08-13 23:42:53 +02:00
Jose Alf
fc5a5a4f07 openssl: fix version report for the 0.9.8 branch
Fixed libcurl to correctly output the newer versions of OpenSSL 0.9.8,
starting from openssl-0.9.8za.
2014-08-13 08:49:19 +02:00
Frank Meier
01368d395c create_conn: prune dead connections
Bringing back the old functionality that was mistakenly removed when the
connection cache was remade. When creating a new connection, all the
existing ones are checked and those that are known to be dead get
disconnected for real and removed from the connection cache. It helps
the cache from holding on to very many stale connections and aids in
keeping down the number of system sockets in wait states.

Help-by: Jonatan Vela <jonatan.vela@ergon.ch>

Bug: http://curl.haxx.se/mail/lib-2014-06/0189.html
2014-08-12 23:33:56 +02:00
Kamil Dudka
cb1f18661a docs/SSLCERTS: update the section about NSS database
Bug: http://curl.haxx.se/mail/lib-2014-07/0335.html
Reported-by: David Shaw
2014-08-11 16:49:54 +02:00
Peter Wang
97d2e4bd75 Curl_poll + Curl_wait_ms: fix timeout return value
Curl_poll and Curl_wait_ms require the fix applied to Curl_socket_check
in commits b61e8b8 and c771968:

When poll or select are interrupted and coincides with the timeout
elapsing, the functions return -1 indicating an error instead of 0 for
the timeout.
2014-08-11 15:10:13 +02:00
Steve Holme
33a95659e2 config-tpf.h: Fixed up line lengths > 79 characters 2014-08-10 20:38:09 +01:00
Steve Holme
35b078b29a config-symbian.h: Fixed up line lengths > 79 characters 2014-08-10 20:38:08 +01:00
Steve Holme
2384c11ff1 tool_hugehelp.c.cvs: Added copyright
Added copyright due to warning from checksrc.pl.
2014-08-10 20:38:06 +01:00
Steve Holme
4c4a188a22 RELEASE-NOTES: Synced with cd6ecf6a89 2014-08-10 17:00:57 +01:00
Steve Holme
cd6ecf6a89 sasl_sspi: Fixed hard coded buffer for response generation
Given the SSPI package info query indicates a token size of 4096 bytes,
updated to use a dynamic buffer for the response message generation
rather than a fixed buffer of 1024 bytes.
2014-08-10 11:11:20 +01:00
Steve Holme
d804ff0d6b sasl_sspi: Fixed missing free of challenge buffer on SPN failure 2014-08-10 10:35:57 +01:00
Steve Holme
343befa44b http_negotiate_sspi: Tidy up to remove the get_gss_name() function
Due to the reduction of code in commit 3b924b29 of get_gss_name() the
function isn't necessary anymore.
2014-08-09 20:43:46 +01:00
Steve Holme
72945b856e http_negotiate_sspi: Use a dynamic buffer for SPN generation
Updated to use a dynamic buffer for the SPN generation via the recently
introduced Curl_sasl_build_spn() function rather than a fixed buffer of
1024 characters, which should have been more than enough, but by using
the new function removes the need for another variable sname to do the
wide character conversion in Unicode builds.
2014-08-09 20:25:08 +01:00
Steve Holme
d01e30431c sasl: Tidy up to rename SPN variable from URI 2014-08-09 18:55:20 +01:00
Steve Holme
ff5dcb8df2 sasl: Use a dynamic buffer for SPN generation
Updated Curl_sasl_create_digest_md5_message() to use a dynamic buffer
for the SPN generation via the recently introduced Curl_sasl_build_spn()
function rather than a fixed buffer of 128 characters.
2014-08-09 18:40:10 +01:00
Steve Holme
f187372f0a sasl_sspi: Fixed SPN not being converted to wchar under Unicode builds
Curl_sasl_create_digest_md5_message() would simply cast the SPN variable
to a TCHAR when calling InitializeSecurityContext(). This meant that,
under Unicode builds, it would not be valid wide character string.

Updated to use the recently introduced Curl_sasl_build_spn() function
which performs the correct conversion for us.
2014-08-09 17:05:42 +01:00
Steve Holme
1b69122810 sasl: Introduced Curl_sasl_build_spn() for building a SPN
Various parts of the libcurl source code build a SPN for inclusion in
authentication data. This information is either used by our own native
generation routines or passed to authentication functions in third-party
libraries such as SSPI. However, some of these instances use fixed
buffers rather than dynamically allocated ones and not all of those that
should, convert to wide character strings in Unicode builds.

Implemented a common function that generates a SPN and performs the
wide character conversion where necessary.
2014-08-09 16:40:24 +01:00
Steve Holme
e9b4a96975 sasl_sspi: Fixed memory leak with not releasing Package Info struct
Curl_sasl_create_digest_md5_message() wouldn't free the Package Info
structure after QuerySecurityPackageInfo() had allocated it.
2014-08-09 12:34:22 +01:00
Michael Osipov
37f0e8a32c docs: Update SPNEGO and GSS-API related doc sections
Reflect recent changes in SPNEGO and GSS-API code in the docs.
Update them with appropriate namings and remove visible spots for
GSS-Negotiate.
2014-08-09 00:08:51 +01:00
Steve Holme
b91e97eabd sspi: Minor code tidy up to standardise coding style
Following the recent changes and in attempt to align the SSPI based
authentication code performed the following:

* Use NULL and SECBUFFVERSION rather than hard coded constants.
* Avoid comparison of zero in if statements.
* Standardised the buf and desc setup code.
2014-08-08 22:43:18 +01:00
Steve Holme
cda4aaba4d schannel: Fixed compilation warning in vtls.c
vtls.c:688:43: warning: unused parameter 'data'
2014-08-08 21:34:05 +01:00
Steve Holme
ea864fb24d tool_getparam.c: Fixed compilation warning
warning: `orig_opt' might be used uninitialized in this function
2014-08-08 11:24:43 +01:00
Steve Holme
5908ce5115 RELEASE-NOTES: Synced with 159c3aafd8 2014-08-08 07:39:09 +01:00
Daniel Stenberg
159c3aafd8 curl_ntlm_msgs: make < 80 columns wide 2014-08-08 08:34:51 +02:00
Steve Holme
df739784e5 ntlm: Fixed hard coded buffer for SSPI based auth packet generation
Given the SSPI package info query indicates a token size of 2888 bytes,
and as with the Winbind code and commit 9008f3d56, use a dynamic buffer
for the Type-1 and Type-3 message generation rather than a fixed buffer
of 1024 bytes.
2014-08-08 07:31:03 +01:00
Steve Holme
03d34b683d ntlm: Added support for SSPI package info query
Just as with the SSPI implementations of Digest and Negotiate added a
package info query so that libcurl can a) return a more appropriate
error code when the NTLM package is not supported and b) it can be of
use later to allocate a dynamic buffer for the Type-1 and Type-3
output tokens rather than use a fixed buffer of 1024 bytes.
2014-08-07 20:15:17 +01:00
Daniel Stenberg
dc61480c54 http2: added some more logging for debugging stream problems 2014-08-07 17:41:14 +02:00
Tatsuhiro Tsujikawa
f05e1a991a HTTP/2: Reset promised stream, not its associated stream. 2014-08-07 16:54:45 +02:00
Tatsuhiro Tsujikawa
7ceada43af HTTP/2: Move :authority before non-pseudo header fields 2014-08-07 16:54:17 +02:00
Daniel Stenberg
26393a97b2 http2: show the received header for better debugging 2014-08-07 13:26:15 +02:00
Daniel Stenberg
7d2f61f66a openssl: replace call to OPENSSL_config
OPENSSL_config() is "strongly recommended" to use but unfortunately that
function makes an exit() call on wrongly formatted config files which
makes it hard to use in some situations. OPENSSL_config() itself calls
CONF_modules_load_file() and we use that instead and we ignore its
return code!

Reported-by: Jan Ehrhardt
Bug: http://curl.haxx.se/bug/view.cgi?id=1401
2014-08-07 12:40:31 +02:00
Fabian Keil
40e13829af runtests.pl: Pad test case numbers with up to three zeroes
Test case numbers with four digits have been available for a
while now.
2014-08-07 10:17:25 +02:00
Steve Holme
f719a97e12 docs: Added Negotiate to the SSPI current credentials usage description 2014-08-07 08:04:40 +01:00
Steve Holme
6c6983f477 TODO: HTTP Digest via Windows SSPI 2014-08-06 22:58:42 +01:00
Steve Holme
c399f6eeb2 TODO: FTP GSSAPI via Windows SSPI 2014-08-06 21:54:27 +01:00
Steve Holme
f8a8ed73fe http_negotiate_sspi: Fixed specific username and password not working
Bug: http://curl.haxx.se/mail/lib-2014-06/0224.html
Reported-by: Leonardo Rosati
2014-08-06 20:31:19 +01:00
Steve Holme
f8af8606a5 http_negotiate_sspi: Fixed endless unauthorized loop in commit 6bc76194e8
If the server rejects our authentication attempt and curl hasn't
called CompleteAuthToken() then the status variable will be
SEC_I_CONTINUE_NEEDED and not SEC_E_OK.

As such the existing detection mechanism for determining whether or not
the authentication process has finished is not sufficient.

However, the WWW-Authenticate: Negotiate header line will not contain
any data when the server has exhausted the negotiation, so we can use
that coupled with the already allocated context pointer.
2014-08-06 07:17:13 +01:00
Daniel Stenberg
524833e155 RELEASE-NOTES: synced with 5b37db44a3 2014-08-05 09:38:04 +02:00
Dan Fandrich
5b37db44a3 parsedate.c: fix the return code for an overflow edge condition 2014-08-05 09:25:47 +02:00
Toby Peterson
0e452a02f1 darwinssl: don't use strtok()
The GetDarwinVersionNumber() function uses strtok, which is not
thread-safe.
2014-08-05 08:58:49 +02:00
Daniel Stenberg
ea6d371e7c Curl_ossl_version: adapted to detect BoringSSL
This seems to be the way it should work. Right now we can't build with
BoringSSL and try this out properly due to a minor API breakage.
2014-08-05 00:29:37 +02:00
Daniel Stenberg
7efff86639 Curl_ossl_version: detect and show libressl
LibreSSL is otherwise OpenSSL API compliant (so far)
2014-08-04 23:54:44 +02:00
Tatsuhiro Tsujikawa
67920e1516 HTTP/2: Fix infinite loop in readwrite_data()
To prevent infinite loop in readwrite_data() function when stream is
reset before any response body comes, reset closed flag to false once
it is evaluated to true.
2014-08-03 22:49:56 +02:00
Dan Fandrich
4d4dd7aea0 gtls: only define Curl_gtls_seed if Nettle is not being used 2014-08-03 11:18:08 +02:00
Dan Fandrich
cac1dd58a8 ssl: provide Curl_ssl_backend even if no SSL library is available 2014-08-03 10:43:31 +02:00
Tatsuhiro Tsujikawa
595f5f0e43 HTTP2: Support expect: 100-continue
"Expect: 100-continue", which was once deprecated in HTTP/2, is now
resurrected in HTTP/2 draft 14.  This change adds its support to
HTTP/2 code.  This change also includes stricter header field
checking.
2014-08-02 23:15:46 +02:00
Daniel Stenberg
e4f6adb023 CURLOPT_SSL_VERIFYPEER.3. add a warning about disabling it 2014-08-02 23:09:22 +02:00
Daniel Stenberg
8da2124060 FEATURES: minor update 2014-08-01 09:00:06 +02:00
Daniel Stenberg
b9f6ca1d32 openssl: make ossl_send return CURLE_OK better
Previously it only returned a CURLcode for errors, which is when it
returns a different size than what was passed in to it.

The http2 code only checked the curlcode and thus failed.
2014-08-01 00:01:02 +02:00
Daniel Stenberg
05e81222d4 RELEASE-NOTES: synced with 7bb4c8cadb 2014-07-31 23:24:17 +02:00
Michael Wallner
7bb4c8cadb CURLOPT_HEADEROPT.3: typo: do -> to 2014-07-31 17:52:08 +02:00
Marcel Raad
f8f2188888 schannel: use CryptGenRandom for random numbers
This function is available for every Windows version since Windows 95/NT.

reference:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa379942.aspx
2014-07-31 13:10:54 +02:00
Daniel Stenberg
0c23ec232b curl_version_info.3: 'ssl_version_num' is always 0
... and has been so since 2005
2014-07-31 12:27:15 +02:00
Daniel Stenberg
a439e438f3 ssl: generalize how the ssl backend identifier is set
Each backend now defines CURL_SSL_BACKEND accordingly. Added the *AXTLS
one which was missing previously.
2014-07-31 12:19:51 +02:00
Dan Fandrich
028a408d57 axtls: define curlssl_random using axTLS's PRNG 2014-07-31 01:12:38 +02:00
Dan Fandrich
3d5be801b9 cyassl: fix the test for ASN_NO_SIGNER_E
It's an enum so a macro test won't work. The CyaSSL changelog doesn't
say exactly when this error code was introduced, but it's likely
to be 2.7.0.
2014-07-31 00:31:36 +02:00
Dan Fandrich
1aa6418af9 cyassl: use RNG_GenerateBlock to generate a good random number 2014-07-31 00:09:13 +02:00
Dan Fandrich
524bb823c9 opts: fixed some typos 2014-07-30 23:37:24 +02:00
Dan Fandrich
2c1db913f7 smtp: fixed a segfault during test 1320 torture test
Under these circumstances, the connection hasn't been fully established
and smtp_connect hasn't been called, yet smtp_done still calls the state
machine which dereferences the NULL conn pointer in struct pingpong.
2014-07-30 23:37:24 +02:00
Daniel Stenberg
01a0168806 vtls: repair build without TLS support
... by defining Curl_ssl_random() properly
2014-07-30 23:17:41 +02:00
Daniel Stenberg
0e811d8c59 polarssl: provide a (weak) random function
This now provides a weak random function since PolarSSL doesn't have a
quick and easy way to provide a good one. It does however provide the
framework to make one so it _can_ and _should_ be done...
2014-07-30 20:59:16 +02:00
Michael Wallner
df52f3500c curl_tlsinfo -> curl_tlssessioninfo 2014-07-30 11:11:29 +02:00
Daniel Stenberg
f0369223cd cyassl: use the default (weeker) random
I couldn't find any dedicated function in its API to get a "good" random
with.
2014-07-30 10:08:27 +02:00
Daniel Stenberg
16cb818a74 cyassl: made it compile with version 2.0.6 again
ASN_NO_SIGNER_E didn't exist back then!
2014-07-30 10:07:42 +02:00
Daniel Stenberg
8dfd22089c vtls: make the random function mandatory in the TLS backend
To force each backend implementation to really attempt to provide proper
random. If a proper random function is missing, then we can explicitly
make use of the default one we use when TLS support is missing.

This commit makes sure it works for darwinssl, gnutls, nss and openssl.
2014-07-30 00:05:47 +02:00
Daniel Stenberg
37faf55e17 libcurl.m4: include the standard source header
... with permission from David Shaw
2014-07-29 00:06:36 +02:00
Kamil Dudka
30b093f6fc nss: do not check the version of NSS at run time
The minimal required version of NSS is 3.14.x so it does not make sense
to check for NSS 3.12.0+ at run time.
2014-07-28 16:27:04 +02:00
Anthon Pang
f3bd3deddd curl.h: bring back CURLE_OBSOLETE16
Removing defines, even obsolete ones that haven't been used for a very
long time, still break a lot of applications.

Bug: https://github.com/bagder/curl/pull/106
2014-07-28 10:51:50 +02:00
Fabian Keil
6543f6e36c tests: Fix a couple of incomplete response lines 2014-07-26 23:12:53 +02:00
Fabian Keil
2fab0d45a9 runtests.pl: Remove filteroff() which hasn't been used since 2001 2014-07-26 23:02:50 +02:00
Fabian Keil
dc7a598126 runtests.pl: Don't expect $TESTDIR/DISABLED to exist
If a non-standard $TESTDIR is used the file may not be necessary.

Previously a "missing" file resulted in the warning:
readline() on closed filehandle D at ./runtests.pl line 4940.
2014-07-26 23:01:31 +02:00
Fabian Keil
5828e886e6 getpart.pm: Fix a comment typo 2014-07-26 23:01:22 +02:00
Daniel Stenberg
c56aa6f121 c-ares: fix build without IPv6 support
Bug: http://curl.haxx.se/mail/lib-2014-07/0337.html
Reported-by: Spork Schivago
2014-07-25 09:26:13 +02:00
Daniel Stenberg
e1b13eba75 Curl_base64url_encode: unit-tested in 1302 2014-07-25 08:38:16 +02:00
Daniel Stenberg
aae4e4bf70 base64: added Curl_base64url_encode()
This is now used by the http2 code. It has two different symbols at the
end of the base64 table to make the output "url safe".

Bug: https://github.com/tatsuhiro-t/nghttp2/issues/62
2014-07-25 08:24:03 +02:00
Marcel Raad
9c1cf96664 SSPI Negotiate: Fix 3 memory leaks
Curl_base64_decode allocates the output string by itself and two other
strings were not freed either.
2014-07-24 23:50:53 +02:00
Daniel Stenberg
821d4a1e55 symbols: CURL_VERSION_GSSNEGOTIATE is deprecated 2014-07-24 23:47:32 +02:00
Daniel Stenberg
4e11bd156e test1013.pl: GSS-Negotiate doesn't exist as a feature anymore 2014-07-24 23:46:11 +02:00
Sergey Nikulov
64010d603c libtest: fixed duplicated line in Makefile
Bug: https://github.com/bagder/curl/pull/105
2014-07-24 15:19:46 +02:00
Patrick Monnerat
c31dec7f98 GSSAPI: remove useless *_MECHANISM defines. 2014-07-23 18:56:19 +02:00
Daniel Stenberg
5b22c47ca9 findprotocol: show unsupported protocol within quotes
... to aid when for example prefixed with a space or other weird
character.
2014-07-23 18:17:16 +02:00
Patrick Monnerat
8efc11a0c1 GSSAPI: private export mechanisms OIDs. OS400: Make RPG binding up to date. 2014-07-23 16:15:01 +02:00
Marcel Raad
2cd0c2d244 conncache: fix compiler warning
warning C4267: '=' : conversion from 'size_t' to 'long', possible loss
of data

The member connection_id of struct connectdata is a long (always a
32-bit signed integer on Visual C++) and the member next_connection_id
of struct conncache is a size_t, so one of them should be changed to
match the other.

This patch the size_t in struct conncache to long (the less invasive
change as that variable is only ever used in a single code line).

Bug: http://curl.haxx.se/bug/view.cgi?id=1399
2014-07-23 12:06:57 +02:00
Daniel Stenberg
05a887ebfa RELEASE-NOTES: synced with 81cd24adb8 2014-07-23 09:52:06 +02:00
Daniel Stenberg
81cd24adb8 http2: more and better error checking
1 - fixes the warnings when built without http2 support

2 - adds CURLE_HTTP2, a new error code for errors detected by nghttp2
basically when they are about http2 specific things.
2014-07-23 09:23:56 +02:00
Dan Fandrich
713f96ee0c cyassl.c: return the correct error code on no CA cert
CyaSSL 3.0.0 returns a unique error code if no CA cert is available,
so translate that into CURLE_SSL_CACERT_BADFILE when peer verification
is requested.
2014-07-23 00:52:56 +02:00
Daniel Stenberg
cc52d776dd symbols-in-versions: new SPNEGO/GSS-API symbols in 7.38.0 2014-07-23 00:01:39 +02:00
Daniel Stenberg
a8206adcad test1013.pl: remove SPNEGO/GSS-API tweaks
No longer necessary after Michael Osipov's rework
2014-07-23 00:01:39 +02:00
Daniel Stenberg
3cad5ab77a http_negotiate: remove unused variable 2014-07-23 00:01:39 +02:00
Michael Osipov
eed1c63c70 docs: Improve inline GSS-API naming in code documentation 2014-07-23 00:01:39 +02:00
Michael Osipov
e38ba43014 curl.h/features: Deprecate GSS-Negotiate macros due to bad naming
- Replace CURLAUTH_GSSNEGOTIATE with CURLAUTH_NEGOTIATE
- CURL_VERSION_GSSNEGOTIATE is deprecated which
  is served by CURL_VERSION_SSPI, CURL_VERSION_GSSAPI and
  CURUL_VERSION_SPNEGO now.
- Remove display of feature 'GSS-Negotiate'
2014-07-23 00:01:39 +02:00
Michael Osipov
46750c39bd configure/features: Add feature and version info for GSS-API and SPNEGO 2014-07-23 00:01:39 +02:00
Michael Osipov
5128672731 HTTP: Remove checkprefix("GSS-Negotiate")
That auth mech has never existed neither on MS nor on Unix side.
There is only Negotiate over SPNEGO.
2014-07-23 00:01:39 +02:00
Michael Osipov
eda12bcff8 curl_gssapi: Add macros for common mechs and pass them appropriately
Macros defined: KRB5_MECHANISM and SPNEGO_MECHANISM called from
HTTP, FTP and SOCKS on Unix
2014-07-23 00:01:39 +02:00
Daniel Stenberg
a4cece3d47 CONNECT: Revert Curl_proxyCONNECT back to 7.29.0 design
This reverts commit cb3e6dfa35 and instead fixes the problem
differently.

The reverted commit addressed a test failure in test 1021 by simplifying
and generalizing the code flow in a way that damaged the
performance. Now we modify the flow so that Curl_proxyCONNECT() again
does as much as possible in one go, yet still do test 1021 with and
without valgrind. It failed due to mistakes in the multi state machine.

Bug: http://curl.haxx.se/bug/view.cgi?id=1397
Reported-by: Paul Saab
2014-07-22 23:00:19 +02:00
Marcel Raad
d242839af8 url.c: use the preferred symbol name: *READDATA
with CURL_NO_OLDIES defined, it doesn't compile because this deprecated
symbol (*INFILE) is used

Bug: http://curl.haxx.se/bug/view.cgi?id=1398
2014-07-22 11:27:51 +02:00
Alessandro Ghedini
6f8046f7a4 CURLOPT_CHUNK_BGN_FUNCTION: fix typo 2014-07-19 21:27:38 +02:00
Alessandro Ghedini
c6e7cbb94e build: link curl to NSS libraries when NSS support is enabled
This fixes a build failure on Debian caused by commit
24c3cdce88.

Bug: http://curl.haxx.se/mail/lib-2014-07/0209.html
2014-07-18 14:20:42 +02:00
Steve Holme
12bf451ca4 build: Removed unnecessary XML Documentation file directive from VC8 to VC12
The curl tool project files for VC8 to VC12 would set this setting to
$(IntDir) which is the Visual Studio default value. To avoid confusion
when viewing settings from within Visual Studio and for consistency
with the libcurl project files removed this setting.

Conflicts:
	projects/Windows/VC10/src/curlsrc.tmpl
	projects/Windows/VC11/src/curlsrc.tmpl
	projects/Windows/VC12/src/curlsrc.tmpl
	projects/Windows/VC8/src/curlsrc.tmpl
	projects/Windows/VC9/src/curlsrc.tmpl
2014-07-17 20:40:18 +01:00
Steve Holme
af46c96d65 build: Removed unnecessary Precompiled Header file directive in VC7 to VC12
The curl tool project files for VC7 to VC12 would set this settings to
$(IntDir)$(TargetName).pch which is the Visual Studio default value. To
avoid confusion when viewing settings from within Visual Studio and for
consistency with the libcurl project files removed this setting.

Conflicts:
	projects/Windows/VC10/src/curlsrc.tmpl
	projects/Windows/VC11/src/curlsrc.tmpl
	projects/Windows/VC12/src/curlsrc.tmpl
	projects/Windows/VC8/src/curlsrc.tmpl
	projects/Windows/VC9/src/curlsrc.tmpl
2014-07-17 20:39:16 +01:00
Steve Holme
2856027e59 build: Removed unnecessary ASM and Object file directives in VC7 to VC12
The curl tool project files for VC7 to VC12 would set these settings to
$(IntDir) which is the Visual Studio default value. To avoid confusion
when viewing settings from within Visual Studio and for consistency
with the libcurl project files removed these two settings.
2014-07-17 20:39:04 +01:00
Dave Reisner
fb93fa9216 src/Makefile.am: add .DELETE_ON_ERROR
This prevents targets like tool_hugehelp.c from leaving around
half-constructed files if the rule fails with GNU make.

Reported-by: Rafaël Carré <funman@videolan.org>
2014-07-17 15:11:47 +02:00
Daniel Stenberg
da172b0dde THANKS: added new contributors from 7.37.1 announcement 2014-07-17 13:18:46 +02:00
Dan Fandrich
6ffc113ceb testcurl.pl: log the value of --runtestopts in the test header 2014-07-17 00:00:23 +02:00
Daniel Stenberg
1abc42b26c RELEASE-NOTES: cleared, working towards next release 2014-07-16 17:26:08 +02:00
Daniel Stenberg
d19dfa974c curl_gssapi.c: make line shorter than 80 columns 2014-07-16 17:26:08 +02:00
David Woodhouse
3de576efda Fix negotiate auth to proxies to track correct state 2014-07-16 17:26:08 +02:00
David Woodhouse
6bc76194e8 Don't abort Negotiate auth when the server has a response for us
It's wrong to assume that we can send a single SPNEGO packet which will
complete the authentication. It's a *negotiation* — the clue is in the
name. So make sure we handle responses from the server.

Curl_input_negotiate() will already handle bailing out if it thinks the
state is GSS_S_COMPLETE (or SEC_E_OK on Windows) and the server keeps
talking to us, so we should avoid endless loops that way.
2014-07-16 17:26:08 +02:00
David Woodhouse
f78ae415d2 Don't clear GSSAPI state between each exchange in the negotiation
GSSAPI doesn't work very well if we forget everything ever time.

XX: Is Curl_http_done() the right place to do the final cleanup?
2014-07-16 17:26:08 +02:00
David Woodhouse
59431c242b Use SPNEGO for HTTP Negotiate
This is the correct way to do SPNEGO. Just ask for it

Now I correctly see it trying NTLMSSP authentication when a Kerberos ticket
isn't available. Of course, we bail out when the server responds with the
challenge packet, since we don't expect that. But I'll fix that bug next...
2014-07-16 17:26:08 +02:00
David Woodhouse
9ad282b1ae Remove all traces of FBOpenSSL SPNEGO support
This is just fundamentally broken. SPNEGO (RFC4178) is a protocol which
allows client and server to negotiate the underlying mechanism which will
actually be used to authenticate. This is *often* Kerberos, and can also
be NTLM and other things. And to complicate matters, there are various
different OIDs which can be used to specify the Kerberos mechanism too.

A SPNEGO exchange will identify *which* GSSAPI mechanism is being used,
and will exchange GSSAPI tokens which are appropriate for that mechanism.

But this SPNEGO implementation just strips the incoming SPNEGO packet
and extracts the token, if any. And completely discards the information
about *which* mechanism is being used. Then we *assume* it was Kerberos,
and feed the token into gss_init_sec_context() with the default
mechanism (GSS_S_NO_OID for the mech_type argument).

Furthermore... broken as this code is, it was never even *used* for input
tokens anyway, because higher layers of curl would just bail out if the
server actually said anything *back* to us in the negotiation. We assume
that we send a single token to the server, and it accepts it. If the server
wants to continue the exchange (as is required for NTLM and for SPNEGO
to do anything useful), then curl was broken anyway.

So the only bit which actually did anything was the bit in
Curl_output_negotiate(), which always generates an *initial* SPNEGO
token saying "Hey, I support only the Kerberos mechanism and this is its
token".

You could have done that by manually just prefixing the Kerberos token
with the appropriate bytes, if you weren't going to do any proper SPNEGO
handling. There's no need for the FBOpenSSL library at all.

The sane way to do SPNEGO is just to *ask* the GSSAPI library to do
SPNEGO. That's what the 'mech_type' argument to gss_init_sec_context()
is for. And then it should all Just Work™.

That 'sane way' will be added in a subsequent patch, as will bug fixes
for our failure to handle any exchange other than a single outbound
token to the server which results in immediate success.
2014-07-16 17:26:08 +02:00
David Woodhouse
223612afa2 ntlm_wb: Avoid invoking ntlm_auth helper with empty username 2014-07-16 17:26:08 +02:00
David Woodhouse
9008f3d564 ntlm_wb: Fix hard-coded limit on NTLM auth packet size
Bumping it to 1KiB in commit aaaf9e50ec is all very well, but having hit
a hard limit once let's just make it cope by reallocating as necessary.
2014-07-16 17:26:08 +02:00
175 changed files with 4393 additions and 2898 deletions

View File

@@ -19,21 +19,17 @@ macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
if(${ARGC} GREATER 2) if(${ARGC} GREATER 2)
# then add the third argument as a message # then add the third argument as a message
set(message "${ARGV2} (${VAR})") set(message "${ARGV2} (${VAR})")
endif(${ARGC} GREATER 2) endif()
set(MACRO_CHECK_FUNCTION_DEFINITIONS set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}") "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES) if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
else(CMAKE_REQUIRED_LIBRARIES) endif()
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
endif(CMAKE_REQUIRED_LIBRARIES)
if(CMAKE_REQUIRED_INCLUDES) if(CMAKE_REQUIRED_INCLUDES)
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else(CMAKE_REQUIRED_INCLUDES) endif()
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
endif(CMAKE_REQUIRED_INCLUDES)
set(src "") set(src "")
foreach(def ${EXTRA_DEFINES}) foreach(def ${EXTRA_DEFINES})
set(src "${src}#define ${def} 1\n") set(src "${src}#define ${def} 1\n")
@@ -63,13 +59,13 @@ macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
"Performing C SOURCE FILE Test ${message} succeded with the following output:\n" "Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
"${OUTPUT}\n" "${OUTPUT}\n"
"Source file was:\n${src}\n") "Source file was:\n${src}\n")
else(${VAR}) else()
message(STATUS "Performing Test ${message} - Failed") message(STATUS "Performing Test ${message} - Failed")
set(${VAR} "" CACHE INTERNAL "Test ${message}") set(${VAR} "" CACHE INTERNAL "Test ${message}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${message} failed with the following output:\n" "Performing C SOURCE FILE Test ${message} failed with the following output:\n"
"${OUTPUT}\n" "${OUTPUT}\n"
"Source file was:\n${src}\n") "Source file was:\n${src}\n")
endif(${VAR}) endif()
endif("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN") endif()
endmacro(CURL_CHECK_C_SOURCE_COMPILES) endmacro()

35
CMake/FindLibSSH2.cmake Normal file
View File

@@ -0,0 +1,35 @@
# - Try to find the libssh2 library
# Once done this will define
#
# LIBSSH2_FOUND - system has the libssh2 library
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
# LIBSSH2_LIBRARY - the libssh2 library name
if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
set(LibSSH2_FIND_QUIETLY TRUE)
endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
)
FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
)
if(LIBSSH2_INCLUDE_DIR)
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
endif(LIBSSH2_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)

View File

@@ -1,21 +0,0 @@
# Extension of the standard FindOpenSSL.cmake
# Adds OPENSSL_INCLUDE_DIRS and libeay32
include("${CMAKE_ROOT}/Modules/FindOpenSSL.cmake")
# starting 2.8 it is better to use standard modules
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
# Bill Hoffman told that libeay32 is necessary for him:
find_library(SSL_LIBEAY NAMES libeay32)
if(OPENSSL_FOUND)
if(SSL_LIBEAY)
list(APPEND OPENSSL_LIBRARIES ${SSL_LIBEAY})
else()
set(OPENSSL_FOUND FALSE)
endif()
endif()
endif() # if (CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
if(OPENSSL_FOUND)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
endif()

View File

@@ -1,10 +0,0 @@
# Locate zlib
include("${CMAKE_ROOT}/Modules/FindZLIB.cmake")
# starting 2.8 it is better to use standard modules
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
find_library(ZLIB_LIBRARY_DEBUG NAMES zd zlibd zdlld zlib1d )
if(ZLIB_FOUND AND ZLIB_LIBRARY_DEBUG)
set( ZLIB_LIBRARIES optimized "${ZLIB_LIBRARY}" debug ${ZLIB_LIBRARY_DEBUG})
endif()
endif()

89
CMake/Macros.cmake Normal file
View File

@@ -0,0 +1,89 @@
#File defines convenience macros for available feature testing
# This macro checks if the symbol exists in the library and if it
# does, it prepends library to the list.
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
${VARIABLE})
if(${VARIABLE})
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
endif(${VARIABLE})
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
# Check if header file exists and add it to the list.
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
check_include_file("${FILE}" ${VARIABLE})
if(${VARIABLE})
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
endif(${VARIABLE})
endmacro(CHECK_INCLUDE_FILE_CONCAT)
# For other curl specific tests, use this macro.
macro(CURL_INTERNAL_TEST CURL_TEST)
if("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_compile(${CURL_TEST}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
"${OUTPUT}\n")
else(${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}\n")
endif(${CURL_TEST})
endif("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
endmacro(CURL_INTERNAL_TEST)
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
if("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}")
if(${CURL_TEST}_COMPILE)
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"There was a problem running this test\n")
endif(${CURL_TEST}_COMPILE)
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"\n\n")
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
endmacro(CURL_INTERNAL_TEST_RUN)

View File

@@ -21,6 +21,9 @@ if(HAVE_WINDOWS_H)
set(EXTRA_DEFINES ${EXTRA_DEFINES} set(EXTRA_DEFINES ${EXTRA_DEFINES}
"__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3") "__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
set(signature_call_conv "PASCAL") set(signature_call_conv "PASCAL")
if(HAVE_LIBWS2_32)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
endif()
else(HAVE_WINDOWS_H) else(HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TYPES_H "sys/types.h") add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h") add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")

View File

@@ -38,9 +38,10 @@
# To check: # To check:
# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not. # (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options. # (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR) cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
include(Utilities) include(Utilities)
include(Macros)
project( CURL C ) project( CURL C )
@@ -133,6 +134,19 @@ mark_as_advanced(CURL_DISABLE_HTTP)
option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF) option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF)
mark_as_advanced(CURL_DISABLE_LDAPS) mark_as_advanced(CURL_DISABLE_LDAPS)
option(CURL_DISABLE_RTSP "to disable RTSP" OFF)
mark_as_advanced(CURL_DISABLE_RTSP)
option(CURL_DISABLE_PROXY "to disable proxy" OFF)
mark_as_advanced(CURL_DISABLE_PROXY)
option(CURL_DISABLE_POP3 "to disable POP3" OFF)
mark_as_advanced(CURL_DISABLE_POP3)
option(CURL_DISABLE_IMAP "to disable IMAP" OFF)
mark_as_advanced(CURL_DISABLE_IMAP)
option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
mark_as_advanced(CURL_DISABLE_SMTP)
option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
mark_as_advanced(CURL_DISABLE_GOPHER)
if(HTTP_ONLY) if(HTTP_ONLY)
set(CURL_DISABLE_FTP ON) set(CURL_DISABLE_FTP ON)
set(CURL_DISABLE_LDAP ON) set(CURL_DISABLE_LDAP ON)
@@ -141,6 +155,11 @@ if(HTTP_ONLY)
set(CURL_DISABLE_DICT ON) set(CURL_DISABLE_DICT ON)
set(CURL_DISABLE_FILE ON) set(CURL_DISABLE_FILE ON)
set(CURL_DISABLE_TFTP ON) set(CURL_DISABLE_TFTP ON)
set(CURL_DISABLE_RTSP ON)
set(CURL_DISABLE_POP3 ON)
set(CURL_DISABLE_IMAP ON)
set(CURL_DISABLE_SMTP ON)
set(CURL_DISABLE_GOPHER ON)
endif() endif()
option(CURL_DISABLE_COOKIES "to disable cookies support" OFF) option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
@@ -177,22 +196,13 @@ include (CheckIncludeFiles)
include (CheckLibraryExists) include (CheckLibraryExists)
include (CheckSymbolExists) include (CheckSymbolExists)
include (CheckTypeSize) include (CheckTypeSize)
include (CheckCSourceCompiles)
# On windows preload settings # On windows preload settings
if(WIN32) if(WIN32)
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
endif(WIN32) endif(WIN32)
# This macro checks if the symbol exists in the library and if it
# does, it prepends library to the list.
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
${VARIABLE})
if(${VARIABLE})
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
endif(${VARIABLE})
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
# Check for all needed libraries # Check for all needed libraries
check_library_exists_concat("dl" dlopen HAVE_LIBDL) check_library_exists_concat("dl" dlopen HAVE_LIBDL)
check_library_exists_concat("socket" connect HAVE_LIBSOCKET) check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
@@ -209,37 +219,120 @@ if(NOT NOT_NEED_LIBNSL)
check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL) check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
endif(NOT NOT_NEED_LIBNSL) endif(NOT NOT_NEED_LIBNSL)
check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32)
check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
if(WIN32) if(WIN32)
set(CURL_DEFAULT_DISABLE_LDAP OFF) check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32)
# some windows compilers do not have wldap32 check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
if(NOT HAVE_WLDAP32)
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
message(STATUS "wldap32 not found CURL_DISABLE_LDAP set ON")
option(CURL_LDAP_WIN "Use Windows LDAP implementation" OFF)
else()
option(CURL_LDAP_WIN "Use Windows LDAP implementation" ON)
endif()
mark_as_advanced(CURL_LDAP_WIN)
endif() endif()
if(NOT CURL_DISABLE_LDAP)
# IF(NOT CURL_SPECIAL_LIBZ) if(WIN32)
# CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ) option(CURL_LDAP_WIN "Use Windows LDAP implementation" ON)
# ENDIF(NOT CURL_SPECIAL_LIBZ) if(CURL_LDAP_WIN)
check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
if(NOT HAVE_WLDAP32)
set(CURL_LDAP_WIN OFF)
endif()
endif()
endif()
option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF)
mark_as_advanced(CMAKE_USE_OPENLDAP)
set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
if(CMAKE_USE_OPENLDAP AND CURL_LDAP_WIN)
message(FATAL_ERROR "Cannot use CURL_LDAP_WIN and CMAKE_USE_OPENLDAP at the same time")
endif()
# Now that we know, we're not using windows LDAP...
if(NOT CURL_LDAP_WIN)
# Check for LDAP
check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
else()
check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
check_include_file_concat("winber.h" HAVE_WINBER_H)
endif()
set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
if(CMAKE_LDAP_INCLUDE_DIR)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
endif()
check_include_file_concat("ldap.h" HAVE_LDAP_H)
check_include_file_concat("lber.h" HAVE_LBER_H)
if(NOT HAVE_LDAP_H)
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
elseif(NOT HAVE_LIBLDAP)
message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
else()
if(CMAKE_USE_OPENLDAP)
set(USE_OPENLDAP ON)
endif()
if(CMAKE_LDAP_INCLUDE_DIR)
include_directories(${CMAKE_LDAP_INCLUDE_DIR})
endif()
set(NEED_LBER_H ON)
set(_HEADER_LIST)
if(HAVE_WINDOWS_H)
list(APPEND _HEADER_LIST "windows.h")
endif()
if(HAVE_SYS_TYPES_H)
list(APPEND _HEADER_LIST "sys/types.h")
endif()
list(APPEND _HEADER_LIST "ldap.h")
set(_SRC_STRING "")
foreach(_HEADER ${_HEADER_LIST})
set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
endforeach()
set(_SRC_STRING
"
${_INCLUDE_STRING}
int main(int argc, char ** argv)
{
BerValue *bvp = NULL;
BerElement *bep = ber_init(bvp);
ber_free(bep, 1);
return 0;
}"
)
set(CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1" "-DWIN32_LEAN_AND_MEAN")
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
if(HAVE_LIBLBER)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
endif()
check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
if(NOT_NEED_LBER_H)
set(NEED_LBER_H OFF)
else()
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
endif()
endif()
endif()
# No ldap, no ldaps.
if(CURL_DISABLE_LDAP)
if(NOT CURL_DISABLE_LDAPS)
message(STATUS "LDAP needs to be enabled to support LDAPS")
set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
endif()
endif()
if(NOT CURL_DISABLE_LDAPS)
check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H)
endif()
# Check for idn # Check for idn
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN) check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
# Check for LDAP
check_library_exists_concat("ldap" ldap_init HAVE_LIBLDAP)
# if(NOT HAVE_LIBLDAP)
# SET(CURL_DISABLE_LDAP ON)
# endif(NOT HAVE_LIBLDAP)
# Check for symbol dlopen (same as HAVE_LIBDL) # Check for symbol dlopen (same as HAVE_LIBDL)
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN) check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
@@ -250,7 +343,7 @@ option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
set(HAVE_LIBZ OFF) set(HAVE_LIBZ OFF)
set(HAVE_ZLIB_H OFF) set(HAVE_ZLIB_H OFF)
set(HAVE_ZLIB OFF) set(HAVE_ZLIB OFF)
if(CURL_ZLIB) # AND CURL_CONFIG_HAS_BEEN_RUN_BEFORE if(CURL_ZLIB)
find_package(ZLIB QUIET) find_package(ZLIB QUIET)
if(ZLIB_FOUND) if(ZLIB_FOUND)
set(HAVE_ZLIB_H ON) set(HAVE_ZLIB_H ON)
@@ -262,37 +355,70 @@ endif()
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON) option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON)
mark_as_advanced(CMAKE_USE_OPENSSL) mark_as_advanced(CMAKE_USE_OPENSSL)
set(USE_SSLEAY OFF)
set(USE_OPENSSL OFF)
set(HAVE_LIBCRYPTO OFF)
set(HAVE_LIBSSL OFF)
if(CMAKE_USE_OPENSSL) if(CMAKE_USE_OPENSSL)
set(USE_SSLEAY OFF)
set(USE_OPENSSL OFF)
set(HAVE_LIBCRYPTO OFF)
set(HAVE_LIBSSL OFF)
find_package(OpenSSL) find_package(OpenSSL)
if(OPENSSL_FOUND) if(OPENSSL_FOUND)
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES}) list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
set(USE_SSLEAY ON) set(USE_SSLEAY ON)
set(USE_OPENSSL ON) set(USE_OPENSSL ON)
set(HAVE_LIBCRYPTO ON) set(HAVE_LIBCRYPTO ON)
set(HAVE_LIBSSL ON) set(HAVE_LIBSSL ON)
include_directories(${OPENSSL_INCLUDE_DIR})
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
check_include_file_concat("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
check_include_file_concat("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
check_include_file_concat("openssl/err.h" HAVE_OPENSSL_ERR_H)
check_include_file_concat("openssl/pem.h" HAVE_OPENSSL_PEM_H)
check_include_file_concat("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
check_include_file_concat("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
check_include_file_concat("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
check_include_file_concat("openssl/x509.h" HAVE_OPENSSL_X509_H)
check_include_file_concat("openssl/rand.h" HAVE_OPENSSL_RAND_H)
endif(OPENSSL_FOUND) endif(OPENSSL_FOUND)
endif(CMAKE_USE_OPENSSL) endif(CMAKE_USE_OPENSSL)
#libSSH2
option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
mark_as_advanced(CMAKE_USE_LIBSSH2)
set(USE_LIBSSH2 OFF)
set(HAVE_LIBSSH2 OFF)
set(HAVE_LIBSSH2_H OFF)
if(CMAKE_USE_LIBSSH2)
find_package(LibSSH2)
if(LIBSSH2_FOUND)
list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
set(CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
set(HAVE_LIBSSH2 ON)
set(USE_LIBSSH2 ON)
# find_package has already found the headers
set(HAVE_LIBSSH2_H ON)
set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
# now check for specific libssh2 symbols as they were added in different versions
set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h")
check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION)
check_function_exists(libssh2_init HAVE_LIBSSH2_INIT)
check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT)
check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
set(CMAKE_EXTRA_INCLUDE_FILES "")
endif(LIBSSH2_FOUND)
endif(CMAKE_USE_LIBSSH2)
# If we have features.h, then do the _BSD_SOURCE magic # If we have features.h, then do the _BSD_SOURCE magic
check_include_file("features.h" HAVE_FEATURES_H) check_include_file("features.h" HAVE_FEATURES_H)
# Check if header file exists and add it to the list.
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
if(${VARIABLE})
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
endif(${VARIABLE})
endmacro(CHECK_INCLUDE_FILE_CONCAT)
# Check for header files # Check for header files
if(NOT UNIX) if(NOT UNIX)
check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H)
@@ -336,24 +462,13 @@ check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
check_include_file_concat("io.h" HAVE_IO_H) check_include_file_concat("io.h" HAVE_IO_H)
check_include_file_concat("krb.h" HAVE_KRB_H) check_include_file_concat("krb.h" HAVE_KRB_H)
check_include_file_concat("libgen.h" HAVE_LIBGEN_H) check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
check_include_file_concat("libssh2.h" HAVE_LIBSSH2_H)
check_include_file_concat("limits.h" HAVE_LIMITS_H) check_include_file_concat("limits.h" HAVE_LIMITS_H)
check_include_file_concat("locale.h" HAVE_LOCALE_H) check_include_file_concat("locale.h" HAVE_LOCALE_H)
check_include_file_concat("net/if.h" HAVE_NET_IF_H) check_include_file_concat("net/if.h" HAVE_NET_IF_H)
check_include_file_concat("netdb.h" HAVE_NETDB_H) check_include_file_concat("netdb.h" HAVE_NETDB_H)
check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H) check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H) check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
check_include_file_concat("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
check_include_file_concat("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
check_include_file_concat("openssl/err.h" HAVE_OPENSSL_ERR_H)
check_include_file_concat("openssl/pem.h" HAVE_OPENSSL_PEM_H)
check_include_file_concat("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
check_include_file_concat("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
check_include_file_concat("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
check_include_file_concat("openssl/x509.h" HAVE_OPENSSL_X509_H)
check_include_file_concat("openssl/rand.h" HAVE_OPENSSL_RAND_H)
endif(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
check_include_file_concat("pem.h" HAVE_PEM_H) check_include_file_concat("pem.h" HAVE_PEM_H)
check_include_file_concat("poll.h" HAVE_POLL_H) check_include_file_concat("poll.h" HAVE_POLL_H)
check_include_file_concat("pwd.h" HAVE_PWD_H) check_include_file_concat("pwd.h" HAVE_PWD_H)
@@ -382,25 +497,13 @@ check_include_file_concat("stddef.h" HAVE_STDDEF_H)
check_include_file_concat("dlfcn.h" HAVE_DLFCN_H) check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
check_include_file_concat("malloc.h" HAVE_MALLOC_H) check_include_file_concat("malloc.h" HAVE_MALLOC_H)
check_include_file_concat("memory.h" HAVE_MEMORY_H) check_include_file_concat("memory.h" HAVE_MEMORY_H)
check_include_file_concat("ldap.h" HAVE_LDAP_H)
check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H) check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
check_include_file_concat("stdint.h" HAVE_STDINT_H) check_include_file_concat("stdint.h" HAVE_STDINT_H)
check_include_file_concat("sockio.h" HAVE_SOCKIO_H) check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H) check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
check_include_file_concat("idna.h" HAVE_IDNA_H) check_include_file_concat("idna.h" HAVE_IDNA_H)
if(NOT HAVE_LDAP_H)
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
endif()
# No ldap, no ldaps.
if(CURL_DISABLE_LDAP)
if(NOT CURL_DISABLE_LDAPS)
message(STATUS "LDAP needs to be enabled to support LDAPS")
set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
endif()
endif()
check_type_size(size_t SIZEOF_SIZE_T) check_type_size(size_t SIZEOF_SIZE_T)
check_type_size(ssize_t SIZEOF_SSIZE_T) check_type_size(ssize_t SIZEOF_SSIZE_T)
@@ -574,76 +677,12 @@ if(NOT HAVE_STRICMP)
set(HAVE_LDAP_URL_PARSE 1) set(HAVE_LDAP_URL_PARSE 1)
endif(NOT HAVE_STRICMP) endif(NOT HAVE_STRICMP)
# For other curl specific tests, use this macro.
macro(CURL_INTERNAL_TEST CURL_TEST)
if("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_compile(${CURL_TEST}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
"${OUTPUT}\n")
else(${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}\n")
endif(${CURL_TEST})
endif("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
endmacro(CURL_INTERNAL_TEST)
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
if("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}")
if(${CURL_TEST}_COMPILE)
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"There was a problem running this test\n")
endif(${CURL_TEST}_COMPILE)
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"\n\n")
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
endmacro(CURL_INTERNAL_TEST_RUN)
# Do curl specific tests # Do curl specific tests
if(HAVE_LIBWS2_32)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
endif()
foreach(CURL_TEST foreach(CURL_TEST
HAVE_FCNTL_O_NONBLOCK HAVE_FCNTL_O_NONBLOCK
HAVE_IOCTLSOCKET HAVE_IOCTLSOCKET
@@ -835,14 +874,14 @@ endif(MSVC)
function(SETUP_CURL_DEPENDENCIES TARGET_NAME) function(SETUP_CURL_DEPENDENCIES TARGET_NAME)
if(CURL_ZLIB AND ZLIB_FOUND) if(CURL_ZLIB AND ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR}) include_directories(${ZLIB_INCLUDE_DIR})
#ADD_DEFINITIONS( -DHAVE_ZLIB_H -DHAVE_ZLIB -DHAVE_LIBZ )
endif() endif()
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND) if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
include_directories(${OPENSSL_INCLUDE_DIR}) include_directories(${OPENSSL_INCLUDE_DIR})
endif() endif()
if(CMAKE_USE_OPENSSL AND CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
#ADD_DEFINITIONS( -DUSE_SSLEAY ) if(CMAKE_USE_LIBSSH2 AND LIBSSH2_FOUND)
include_directories(${LIBSSH2_INCLUDE_DIR})
endif() endif()
target_link_libraries(${TARGET_NAME} ${CURL_LIBS}) target_link_libraries(${TARGET_NAME} ${CURL_LIBS})

View File

@@ -26,8 +26,7 @@ ACLOCAL_AMFLAGS = -I m4
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \ CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
CMake/CurlCheckCSourceCompiles.cmake CMake/CurlCheckCSourceRuns.cmake \ CMake/CurlCheckCSourceCompiles.cmake CMake/CurlCheckCSourceRuns.cmake \
CMake/CurlTests.c CMake/FindOpenSSL.cmake CMake/FindZLIB.cmake \ CMake/CurlTests.c CMake/OtherTests.cmake CMake/Platforms/WindowsCache.cmake \
CMake/OtherTests.cmake CMake/Platforms/WindowsCache.cmake \
CMake/Utilities.cmake include/curl/curlbuild.h.cmake CMake/Utilities.cmake include/curl/curlbuild.h.cmake
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl

View File

@@ -1,67 +1,92 @@
Curl and libcurl 7.37.1 Curl and libcurl 7.38.0
Public curl releases: 140 Public curl releases: 141
Command line options: 162 Command line options: 162
curl_easy_setopt() options: 208 curl_easy_setopt() options: 208
Public functions in libcurl: 58 Public functions in libcurl: 58
Contributors: 1155 Contributors: 1216
This release includes the following changes: This release includes the following changes:
o bits.close: introduce connection close tracking o CURLE_HTTP2 is a new error code
o darwinssl: Add support for --cacert o CURLAUTH_NEGOTIATE is a new auth define
o polarssl: add ALPN support o CURL_VERSION_GSSAPI is a new capability bit
o docs: Added new option man pages o no longer use fbopenssl for anything
o schannel: use CryptGenRandom for random numbers
o axtls: define curlssl_random using axTLS's PRNG
o cyassl: use RNG_GenerateBlock to generate a good random number
o findprotocol: show unsupported protocol within quotes
o version: detect and show LibreSSL
o version: detect and show BoringSSL
o imap/pop3/smtp: Kerberos (SASL GSSAPI) authentication via Windows SSPI
o http2: requires nghttp2 0.6.0 or later
This release includes the following bugfixes: This release includes the following bugfixes:
o build: Fixed incorrect reference to curl_setup.h in Visual Studio files o CVE-2014-3613: cookie leak with IP address as domain [25]
o build: Use $(TargetDir) and $(TargetName) macros for .pdb and .lib output o CVE-2014-3620: cookie leak for TLDs [26]
o curl.1: clarify that -u can't specify a user with colon [1]
o openssl: Fix uninitialized variable use in NPN callback o fix a build failure on Debian when NSS support is enabled [1]
o curl_easy_reset: reset the URL [2] o HTTP/2: fixed compiler warnings when built disabled [2]
o curl_version_info.3: returns a pointer to a static struct o cyassl: return the correct error code on no CA cert
o url-parser: only use if_nametoindex if detected by configure [3] o http: Deprecate GSS-Negotiate macros due to bad naming
o select: with winsock, avoid passing unsupported arguments to select() [4] o http: Fixed Negotiate: authentication
o gnutls: don't use deprecated type names anymore o multi: Improve proxy CONNECT performance (regression) [3]
o gnutls: allow building with nghttp2 but without ALPN support o ntlm_wb: Avoid invoking ntlm_auth helper with empty username
o tests: Fix portability issue with the tftpd server o ntlm_wb: Fix hard-coded limit on NTLM auth packet size
o curl_sasl_sspi: Fixed corrupt hostname in DIGEST-MD5 SPN o url.c: use the preferred symbol name: *READDATA [4]
o curl_sasl: extended native DIGEST-MD5 cnonce to be a 32-byte hex string o smtp: fixed a segfault during test 1320 torture test
o random: use Curl_rand() for proper random data [5] o cyassl: made it compile with version 2.0.6 again
o Curl_ossl_init: call OPENSSL_config for initing engines [6] o nss: do not check the version of NSS at run time
o config-win32.h: Updated for VC12 [7] o c-ares: fix build without IPv6 support [5]
o winbuild: Don't USE_WINSSL when WITH_SSL is being used o HTTP/2: use base64url encoding [6]
o getinfo: HTTP CONNECT code not reset between transfers [8] o SSPI Negotiate: Fix 3 memory leaks
o Curl_rand: Use a fake entropy for debug builds when CURL_ENTROPY set o libtest: fixed duplicated line in Makefile [7]
o http2: avoid segfault when using the plain-text http2 o conncache: fix compiler warning [8]
o conncache: move the connection counter to the cache struct o openssl: make ossl_send return CURLE_OK better
o http2: better return code error checking o HTTP/2: Support expect: 100-continue
o curlbuild: fix GCC build on SPARC systems without configure script o HTTP/2: Fix infinite loop in readwrite_data()
o tool_metalink: Support polarssl as digest provider o parsedate: fix the return code for an overflow edge condition
o curl.h: reverse the enum/define setup for old symbols o darwinssl: don't use strtok()
o curl.h: moved two really old deprecated symbols o http_negotiate_sspi: Fixed specific username and password not working [9]
o curl.h: renamed CURLOPT_DEPRECATEDx to CURLOPT_OBSOLETEx o openssl: replace call to OPENSSL_config [10]
o buildconf: do not search tools in current directory. o http2: show the received header for better debugging
o OS400: make it compilable again. Make RPG binding up to date o HTTP/2: Move :authority before non-pseudo header fields
o nss: do not abort on connection failure (failing tests 305 and 404) o HTTP/2: Reset promised stream, not its associated stream
o nss: make the fallback to SSLv3 work again o HTTP/2: added some more logging for debugging stream problems
o tool: prevent valgrind from reporting possibly lost memory (nss only) o ntlm: Added support for SSPI package info query
o progress callback: skip last callback update on errors [9] o ntlm: Fixed hard coded buffer for SSPI based auth packet generation
o nss: fix a memory leak when CURLOPT_CRLFILE is used o sasl_sspi: Fixed memory leak with not releasing Package Info struct
o compiler warnings: potentially uninitialized variables [10] o sasl_sspi: Fixed SPN not being converted to wchar under Unicode builds
o url.c: Fixed memory leak on OOM o sasl: Use a dynamic buffer for DIGEST-MD5 SPN generation
o gnutls: ignore invalid certificate dates with VERIFYPEER disabled o http_negotiate_sspi: Use a dynamic buffer for SPN generation
o gnutls: fix SRP support with versions of GnuTLS from 2.99.0 o sasl_sspi: Fixed missing free of challenge buffer on SPN failure
o gnutls: fixed a couple of uninitialized variable references o sasl_sspi: Fixed hard coded buffer for response generation
o gnutls: fixed compilation against versions < 2.12.0 o Curl_poll + Curl_wait_ms: fix timeout return value
o build: Fixed overridden compiler PDB settings in VC7 to VC12 o docs/SSLCERTS: update the section about NSS database
o ntlm_wb: Fixed buffer size not being large enough for NTLMv2 sessions [11] o create_conn: prune dead connections [11]
o netrc: don't abort if home dir cannot be found o openssl: fix version report for the 0.9.8 branch
o netrc: fixed thread safety problem by using getpwuid_r if available o mk-ca-bundle.pl: switched to using hg.mozilla.org [12]
o cookie: avoid mutex deadlock [12] o http: fix the Content-Range: parser [13]
o configure: respect host tool prefix for krb5-config o Curl_disconnect: don't free the URL [14]
o gnutls: handle IP address in cert name check o win32: Fixed WinSock 2 #if [15]
o NTLM: ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth
o curl.1: clarify --limit-rate's effect on both directions [16]
o disconnect: don't touch easy-related state on disconnects [17]
o Cmake: big cleanup and numerous fixes
o HTTP/2: supports draft-14 - moved :headers before the non-psuedo headers
o HTTP/2: Reset promised stream, not its associated stream
o configure.ac: Add support for recent GSS-API implementations for HP-UX
o CONNECT: close proxy connections that fail [18]
o CURLOPT_NOBODY.3: clarify this option is for downloads [19]
o darwinssl: fix CA certificate checking using PEM format [20]
o resolve: cache lookup for async resolvers [21]
o low-speed-limit: avoid timeout flood [22]
o polarssl: implement CURLOPT_SSLVERSION [23]
o multi: convert CURLM_STATE_CONNECT_PEND handling to a list [24]
o curl_multi_cleanup: remove superfluous NULL assigns
o polarssl: support CURLOPT_CAPATH / --capath
o progress: size_dl/size_ul are always >= 0, and clear "KNOWN" properly
This release includes the following known bugs: This release includes the following known bugs:
@@ -70,26 +95,43 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Alessandro Ghedini, Brad Spencer, Chris Young, Colin Hogben, Dan Fandrich, Alessandro Ghedini, Andre Heinecke, Anthon Pang, Askar Safin, Brandon Casey,
Daniel Stenberg, David Woodhouse, Dimitrios Siganos, Fabian Frank, Catalin Patulea, Dan Fandrich, Daniel Stenberg, Dave Reisner, David Meyer,
Glen A Johnson Jr., Hubert Kario, Jeff Pohlmeyer, Jonathan Cardoso Machado, David Shaw, David Woodhouse, Dimitrios Siganos, Ed Morley, Fabian Keil,
Kamil Dudka, Lindley French, Marcel Raad, Michał Górny, Nick Zitzmann, Florian Weimer, Frank Gevaerts, Frank Meier, Haris Okanovic, Jakub Zakrzewski,
Patrick Monnerat, Ray Satiro, Steve Holme, Tatsuhiro Tsujikawa, Jan Ehrhardt, John Coffey, Jonatan Vela, Jose Alf, Kamil Dudka,
Vilmos Nebehaj, Yousuke Kimoto, Dmitry Falko Leonardo Rosati, Marcel Raad, Michael Osipov, Michael Wallner, Paras S,
Patrick Monnerat, Paul Saab, Peter Wang, Rafaël Carré, Sergey Nikulov,
Spork Schivago, Steve Holme, Tatsuhiro Tsujikawa, Tim Ruehsen, Toby Peterson,
Vilmos Nebehaj,
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues: References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/bug/view.cgi?id=1375 [1] = http://curl.haxx.se/mail/lib-2014-07/0209.html
[2] = http://curl.haxx.se/mail/lib-2014-05/0235.html [2] = http://curl.haxx.se/mail/lib-2014-07/0202.html
[3] = http://curl.haxx.se/mail/lib-2014-05/0260.html [3] = http://curl.haxx.se/bug/view.cgi?id=1397
[4] = http://curl.haxx.se/mail/lib-2014-05/0278.html [4] = http://curl.haxx.se/bug/view.cgi?id=1398
[5] = http://curl.haxx.se/mail/lib-2014-06/0001.html [5] = http://curl.haxx.se/mail/lib-2014-07/0337.html
[6] = http://curl.haxx.se/mail/lib-2014-06/0003.html [6] = https://github.com/tatsuhiro-t/nghttp2/issues/62
[7] = http://curl.haxx.se/bug/view.cgi?id=1378 [7] = https://github.com/bagder/curl/pull/105
[8] = http://curl.haxx.se/bug/view.cgi?id=1380 [8] = http://curl.haxx.se/bug/view.cgi?id=1399
[9] = http://curl.haxx.se/mail/lib-2014-06/0062.html [9] = http://curl.haxx.se/mail/lib-2014-06/0224.html
[10] = http://curl.haxx.se/bug/view.cgi?id=1391 [10] = http://curl.haxx.se/bug/view.cgi?id=1401
[11] = http://curl.haxx.se/mail/lib-2014-07/0103.html [11] = http://curl.haxx.se/mail/lib-2014-06/0189.html
[12] = http://curl.haxx.se/mail/lib-2014-02/0184.html [12] = http://curl.haxx.se/bug/view.cgi?id=1409
[13] = http://curl.haxx.se/mail/lib-2014-06/0221.html
[14] = http://curl.haxx.se/mail/lib-2014-08/0148.html
[15] = http://curl.haxx.se/mail/lib-2014-08/0155.html
[16] = http://curl.haxx.se/bug/view.cgi?id=1414
[17] = http://curl.haxx.se/mail/lib-2014-08/0148.html
[18] = http://curl.haxx.se/bug/view.cgi?id=1381
[19] = http://curl.haxx.se/mail/lib-2014-08/0236.html
[20] = https://github.com/bagder/curl/pull/115
[21] = https://github.com/bagder/curl/pull/112
[22] = http://curl.haxx.se/mail/lib-2014-06/0235.html
[23] = http://curl.haxx.se/bug/view.cgi?id=1419
[24] = http://curl.haxx.se/mail/lib-2014-07/0206.html
[25] = http://curl.haxx.se/docs/adv_20140910A.html
[26] = http://curl.haxx.se/docs/adv_20140910B.html

View File

@@ -151,7 +151,6 @@ dnl initialize all the info variables
curl_ssh_msg="no (--with-libssh2)" curl_ssh_msg="no (--with-libssh2)"
curl_zlib_msg="no (--with-zlib)" curl_zlib_msg="no (--with-zlib)"
curl_gss_msg="no (--with-gssapi)" curl_gss_msg="no (--with-gssapi)"
curl_spnego_msg="no (--with-spnego)"
curl_tls_srp_msg="no (--enable-tls-srp)" curl_tls_srp_msg="no (--enable-tls-srp)"
curl_res_msg="default (--enable-ares / --enable-threaded-resolver)" curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
curl_ipv6_msg="no (--enable-ipv6)" curl_ipv6_msg="no (--enable-ipv6)"
@@ -1134,41 +1133,6 @@ no)
;; ;;
esac esac
dnl **********************************************************************
dnl Check for FBopenssl(SPNEGO) libraries
dnl **********************************************************************
AC_ARG_WITH(spnego,
AC_HELP_STRING([--with-spnego=DIR],
[Specify location of SPNEGO library fbopenssl]), [
SPNEGO_ROOT="$withval"
if test x"$SPNEGO_ROOT" != xno; then
want_spnego="yes"
fi
])
AC_MSG_CHECKING([if SPNEGO support is requested])
if test x"$want_spnego" = xyes; then
if test X"$SPNEGO_ROOT" = Xyes; then
AC_MSG_ERROR([FBOpenSSL libs and/or directories were not found where specified!])
AC_MSG_RESULT(no)
else
if test -z "$SPNEGO_LIB_DIR"; then
LDFLAGS="$LDFLAGS -L$SPNEGO_ROOT -lfbopenssl"
else
LDFLAGS="$LDFLAGS $SPNEGO_LIB_DIR"
fi
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SPNEGO, 1,
[Define this if you have the SPNEGO library fbopenssl])
curl_spnego_msg="enabled"
fi
else
AC_MSG_RESULT(no)
fi
dnl ********************************************************************** dnl **********************************************************************
dnl Check for GSS-API libraries dnl Check for GSS-API libraries
dnl ********************************************************************** dnl **********************************************************************
@@ -1284,7 +1248,7 @@ else
fi fi
if test x"$want_gss" = xyes; then if test x"$want_gss" = xyes; then
AC_DEFINE(HAVE_GSSAPI, 1, [if you have GSS-API libraries]) AC_DEFINE(HAVE_GSSAPI, 1, [if you have GSS-API libraries])
HAVE_GSSAPI=1
curl_gss_msg="enabled (MIT Kerberos/Heimdal)" curl_gss_msg="enabled (MIT Kerberos/Heimdal)"
if test -n "$gnu_gss"; then if test -n "$gnu_gss"; then
@@ -1296,12 +1260,6 @@ if test x"$want_gss" = xyes; then
*-*-darwin*) *-*-darwin*)
LIBS="-lgssapi_krb5 -lresolv $LIBS" LIBS="-lgssapi_krb5 -lresolv $LIBS"
;; ;;
*-hp-hpux*)
if test "$GSSAPI_ROOT" != "yes"; then
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
fi
LIBS="-lgss $LIBS"
;;
*) *)
if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then
dnl krb5-config doesn't have --libs-only-L or similar, put everything dnl krb5-config doesn't have --libs-only-L or similar, put everything
@@ -1313,11 +1271,22 @@ if test x"$want_gss" = xyes; then
dnl into LIBS dnl into LIBS
gss_libs=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi` gss_libs=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
LIBS="$gss_libs $LIBS" LIBS="$gss_libs $LIBS"
elif test "$GSSAPI_ROOT" != "yes"; then
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
LIBS="-lgssapi $LIBS"
else else
LIBS="-lgssapi $LIBS" case $host in
*-hp-hpux*)
gss_libname="gss"
;;
*)
gss_libname="gssapi"
;;
esac
if test "$GSSAPI_ROOT" != "yes"; then
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
LIBS="-l$gss_libname $LIBS"
else
LIBS="-l$gss_libname $LIBS"
fi
fi fi
;; ;;
esac esac
@@ -2114,6 +2083,10 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
if test "x$USE_NSS" = "xyes"; then if test "x$USE_NSS" = "xyes"; then
AC_MSG_NOTICE([detected NSS version $version]) AC_MSG_NOTICE([detected NSS version $version])
dnl needed when linking the curl tool without USE_EXPLICIT_LIB_DEPS
NSS_LIBS=$addlib
AC_SUBST([NSS_LIBS])
dnl when shared libs were found in a path that the run-time dnl when shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to dnl linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail dnl LD_LIBRARY_PATH to prevent further configure tests to fail
@@ -2787,7 +2760,7 @@ if test X"$want_h2" != Xno; then
CPPFLAGS="$CPPFLAGS $CPP_H2" CPPFLAGS="$CPPFLAGS $CPP_H2"
LIBS="$LIB_H2 $LIBS" LIBS="$LIB_H2 $LIBS"
AC_CHECK_LIB(nghttp2, nghttp2_session_client_new, AC_CHECK_LIB(nghttp2, nghttp2_session_callbacks_set_send_callback,
[ [
AC_CHECK_HEADERS(nghttp2/nghttp2.h, AC_CHECK_HEADERS(nghttp2/nghttp2.h,
curl_h2_msg="enabled (nghttp2)" curl_h2_msg="enabled (nghttp2)"
@@ -3388,6 +3361,16 @@ fi
if test "x$USE_WINDOWS_SSPI" = "x1"; then if test "x$USE_WINDOWS_SSPI" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES SSPI" SUPPORT_FEATURES="$SUPPORT_FEATURES SSPI"
fi fi
if test "x$HAVE_GSSAPI" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API"
fi
if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \
\( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then
SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO"
fi
if test "x$CURL_DISABLE_HTTP" != "x1" -a \ if test "x$CURL_DISABLE_HTTP" != "x1" -a \
"x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then "x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then
if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \ if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
@@ -3406,12 +3389,6 @@ fi
if test "x$USE_NGHTTP2" = "x1"; then if test "x$USE_NGHTTP2" = "x1"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2" SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2"
fi fi
if test "x$curl_spnego_msg" = "xenabled"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO"
fi
if test "x$want_gss" = "xyes"; then
SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API"
fi
AC_SUBST(SUPPORT_FEATURES) AC_SUBST(SUPPORT_FEATURES)
@@ -3560,7 +3537,6 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
SSH support: ${curl_ssh_msg} SSH support: ${curl_ssh_msg}
zlib support: ${curl_zlib_msg} zlib support: ${curl_zlib_msg}
GSS-API support: ${curl_gss_msg} GSS-API support: ${curl_gss_msg}
SPNEGO support: ${curl_spnego_msg}
TLS-SRP support: ${curl_tls_srp_msg} TLS-SRP support: ${curl_tls_srp_msg}
resolver: ${curl_res_msg} resolver: ${curl_res_msg}
ipv6 support: ${curl_ipv6_msg} ipv6 support: ${curl_ipv6_msg}

View File

@@ -39,12 +39,12 @@ fi
# sort all unique names # sort all unique names
# awk them into RELEASE-NOTES format # awk them into RELEASE-NOTES format
git log $start..HEAD | \ git log $start..HEAD | \
egrep '(Author|Commit|by):' | \ egrep -i '(Author|Commit|by):' | \
cut -d: -f2- | \ cut -d: -f2- | \
cut '-d<' -f1 | \ cut '-d<' -f1 | \
sed -e 's/^ //' -e 's/ $//g' | \ sed -e 's/^ //' -e 's/ $//g' | \
grep ' ' | \ grep ' ' | \
sort -u | sort -fu |
awk '{ awk '{
num++; num++;
n = sprintf("%s%s%s,", n, length(n)?" ":"", $0); n = sprintf("%s%s%s,", n, length(n)?" ":"", $0);

View File

@@ -80,6 +80,7 @@ FAQ
4.17 Non-functional connect timeouts on Windows 4.17 Non-functional connect timeouts on Windows
4.18 file:// URLs containing drive letters (Windows, NetWare) 4.18 file:// URLs containing drive letters (Windows, NetWare)
4.19 Why doesn't cURL return an error when the network cable is unplugged? 4.19 Why doesn't cURL return an error when the network cable is unplugged?
4.20 curl doesn't return error for HTTP non-200 responses!
5. libcurl Issues 5. libcurl Issues
5.1 Is libcurl thread-safe? 5.1 Is libcurl thread-safe?
@@ -136,11 +137,11 @@ FAQ
POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.
libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
kerberos, HTTP form based upload, proxies, cookies, user+password Kerberos, SPNEGO, HTTP form based upload, proxies, cookies, user+password
authentication, file transfer resume, http proxy tunneling and more! authentication, file transfer resume, http proxy tunneling and more!
libcurl is highly portable, it builds and works identically on numerous libcurl is highly portable, it builds and works identically on numerous
platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HP-UX,
IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac
OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF, OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF,
Android, Minix, IBM TPF and more... Android, Minix, IBM TPF and more...
@@ -238,10 +239,10 @@ FAQ
1.6 What do you get for making curl? 1.6 What do you get for making curl?
Project cURL is entirely free and open. No person gets paid for developing Project cURL is entirely free and open. No person gets paid for developing
(lib)curl on full or even part time. We do this voluntarily on our spare curl on full time. We do this voluntarily, mostly on spare time.
time. Occasionally companies pay individual developers to work on curl, but Occasionally companies pay individual developers to work on curl, but that's
that's up to each company and developer. It is not controlled by nor up to each company and developer. It is not controlled by nor supervised in
supervised in any way by the project. any way by the project.
We still get help from companies. Haxx provides web site, bandwidth, mailing We still get help from companies. Haxx provides web site, bandwidth, mailing
lists etc, sourceforge.net hosts project services we take advantage from, lists etc, sourceforge.net hosts project services we take advantage from,
@@ -1087,6 +1088,30 @@ FAQ
by having the application monitor the network connection on its own using an by having the application monitor the network connection on its own using an
OS-specific mechanism, then signalling libcurl to abort (see also item 5.13). OS-specific mechanism, then signalling libcurl to abort (see also item 5.13).
4.20 curl doesn't return error for HTTP non-200 responses!
Correct. Unless you use -f (--fail).
When doing HTTP transfers, curl will perform exactly what you're asking it
to do and if successful it will not return an error. You can use curl to
test your web server's "file not found" page (that gets 404 back), you can
use it to check your authentication protected web pages (that get a 401
back) and so on.
The specific HTTP response code does not constitute a problem or error for
curl. It simply sends and delivers HTTP as you asked and if that worked,
everything is fine and dandy. The response code is generally providing more
higher level error information that curl doesn't care about. The error was
not in the HTTP transfer.
If you want your command line to treat error codes in the 400 and up range
as errors and thus return a non-zero value and possibly show an error
message, curl has a dedicated option for that: -f (CURLOPT_FAILONERROR in
libcurl speak).
You can also use the -w option and the variable %{response_code} to extract
the exact response code that was return in the response.
5. libcurl Issues 5. libcurl Issues

View File

@@ -28,7 +28,7 @@ libcurl
- selectable network interface for outgoing traffic - selectable network interface for outgoing traffic
- IPv6 support on unix and Windows - IPv6 support on unix and Windows
- persistent connections - persistent connections
- socks5 support - socks 4 + 5 support, with or without local name resolving
- supports user name and password in proxy environment variables - supports user name and password in proxy environment variables
- operations through proxy "tunnel" (using CONNECT) - operations through proxy "tunnel" (using CONNECT)
- support for large files (>2GB and >4GB) during upload and download - support for large files (>2GB and >4GB) during upload and download
@@ -45,8 +45,8 @@ HTTP
- POST - POST
- Pipelining - Pipelining
- multipart formpost (RFC1867-style) - multipart formpost (RFC1867-style)
- authentication: Basic, Digest, NTLM (*9), GSS-Negotiate/Negotiate (*3) and - authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3)
SPNEGO (*4) to server and proxy to server and proxy
- resume (both GET and PUT) - resume (both GET and PUT)
- follow redirects - follow redirects
- maximum amount of redirects to follow - maximum amount of redirects to follow
@@ -64,6 +64,7 @@ HTTP
- Content-Encoding support for deflate and gzip - Content-Encoding support for deflate and gzip
- "Transfer-Encoding: chunked" support in uploads - "Transfer-Encoding: chunked" support in uploads
- data compression (*12) - data compression (*12)
- HTTP/2 (*4)
HTTPS (*1) HTTPS (*1)
- (all the HTTP features) - (all the HTTP features)
@@ -77,7 +78,7 @@ FTP
- download - download
- authentication - authentication
- kerberos4 (*5) - kerberos4 (*5)
- kerberos5 (*3) - Kerberos 5 (*14)
- active/passive using PORT, EPRT, PASV or EPSV - active/passive using PORT, EPRT, PASV or EPSV
- single file size information (compare to HTTP HEAD) - single file size information (compare to HTTP HEAD)
- 'type=' URL support - 'type=' URL support
@@ -179,8 +180,9 @@ FOOTNOTES
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native *1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native
Windows), Secure Transport (native iOS/OS X) or qssl (native IBM i) Windows), Secure Transport (native iOS/OS X) or qssl (native IBM i)
*2 = requires OpenLDAP *2 = requires OpenLDAP
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar *3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
*4 = requires FBopenssl SSPI (native Windows)
*4 = requires nghttp2 and possibly a recent TLS library
*5 = requires a krb4 library, such as the MIT one or similar *5 = requires a krb4 library, such as the MIT one or similar
*6 = requires c-ares *6 = requires c-ares
*7 = requires OpenSSL, NSS, qssl, WinSSL or Secure Transport; GnuTLS, for *7 = requires OpenSSL, NSS, qssl, WinSSL or Secure Transport; GnuTLS, for
@@ -194,3 +196,4 @@ FOOTNOTES
*12 = requires libz *12 = requires libz
*13 = requires libmetalink, and either an Apple or Microsoft operating *13 = requires libmetalink, and either an Apple or Microsoft operating
system, or OpenSSL, or GnuTLS, or NSS system, or OpenSSL, or GnuTLS, or NSS
*14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos)

View File

@@ -4,23 +4,31 @@
| (__| |_| | _ <| |___ | (__| |_| | _ <| |___
\___|\___/|_| \_\_____| \___|\___/|_| \_\_____|
How cURL Became Like This How cURL Became Like This
=========================
Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot
Towards the end of 1996, Daniel Stenberg came up with the idea to make for an Amiga related channel on EFnet. He then came up with the idea to make
currency-exchange calculations available to Internet Relay Chat (IRC) currency-exchange calculations available to Internet Relay Chat (IRC)
users. All the necessary data are published on the Web; he just needed to users. All the necessary data are published on the Web; he just needed to
automate their retrieval. automate their retrieval.
Daniel simply adopted an existing command-line open-source tool, httpget, that Daniel simply adopted an existing command-line open-source tool, httpget, that
Brazilian Rafael Sagula had written and recently release version 0.1 of. After Brazilian Rafael Sagula had written and recently release version 0.1 of. After
a few minor adjustments, it did just what he needed. HttpGet 1.0 was released a few minor adjustments, it did just what he needed.
on April 8th 1997 with brand new HTTP proxy support.
1997
----
HttpGet 1.0 was released on April 8th 1997 with brand new HTTP proxy support.
We soon found and fixed support for getting currencies over GOPHER. Once FTP We soon found and fixed support for getting currencies over GOPHER. Once FTP
download support was added, the name of the project was changed and urlget 2.0 download support was added, the name of the project was changed and urlget 2.0
was released in August 1997. The http-only days were already passed. was released in August 1997. The http-only days were already passed.
1998
----
The project slowly grew bigger. When upload capabilities were added and the The project slowly grew bigger. When upload capabilities were added and the
name once again was misleading, a second name change was made and on March 20, name once again was misleading, a second name change was made and on March 20,
1998 curl 4 was released. (The version numbering from the previous names was 1998 curl 4 was released. (The version numbering from the previous names was
@@ -33,33 +41,39 @@ was revealed to us much later.)
SSL support was added, powered by the SSLeay library. SSL support was added, powered by the SSLeay library.
August 1998, first announcement of curl on freshmeat.net. August, first announcement of curl on freshmeat.net.
October 1998, with the curl 4.9 release and the introduction of cookie October, with the curl 4.9 release and the introduction of cookie support,
support, curl was no longer released under the GPL license. Now we're at 4000 curl was no longer released under the GPL license. Now we're at 4000 lines of
lines of code, we switched over to the MPL license to restrict the effects of code, we switched over to the MPL license to restrict the effects of
"copyleft". "copyleft".
November 1998, configure script and reported successful compiles on several November, configure script and reported successful compiles on several
major operating systems. The never-quite-understood -F option was added and major operating systems. The never-quite-understood -F option was added and
curl could now simulate quite a lot of a browser. TELNET support was added. curl could now simulate quite a lot of a browser. TELNET support was added.
Curl 5 was released in December 1998 and introduced the first ever curl man Curl 5 was released in December 1998 and introduced the first ever curl man
page. People started making Linux RPM packages out of it. page. People started making Linux RPM packages out of it.
January 1999, DICT support added. 1999
----
January, DICT support added.
OpenSSL took over where SSLeay was abandoned. OpenSSL took over where SSLeay was abandoned.
May 1999, first Debian package. May, first Debian package.
August 1999, LDAP:// and FILE:// support added. The curl web site gets 1300 August, LDAP:// and FILE:// support added. The curl web site gets 1300 visits
visits weekly. weekly.
Released curl 6.0 in September. 15000 lines of code. Released curl 6.0 in September. 15000 lines of code.
December 28 1999, added the project on Sourceforge and started using its December 28, added the project on Sourceforge and started using its services
services for managing the project. for managing the project.
2000
----
Spring 2000, major internal overhaul to provide a suitable library interface. Spring 2000, major internal overhaul to provide a suitable library interface.
The first non-beta release was named 7.1 and arrived in August. This offered The first non-beta release was named 7.1 and arrived in August. This offered
@@ -67,19 +81,22 @@ the easy interface and turned out to be the beginning of actually getting
other software and programs to get based on and powered by libcurl. Almost other software and programs to get based on and powered by libcurl. Almost
20000 lines of code. 20000 lines of code.
August 2000, the curl web site gets 4000 visits weekly. August, the curl web site gets 4000 visits weekly.
The PHP guys adopted libcurl already the same month, when the first ever third The PHP guys adopted libcurl already the same month, when the first ever third
party libcurl binding showed up. CURL has been a supported module in PHP since party libcurl binding showed up. CURL has been a supported module in PHP since
the release of PHP 4.0.2. This would soon get followers. More than 16 the release of PHP 4.0.2. This would soon get followers. More than 16
different bindings exist at the time of this writing. different bindings exist at the time of this writing.
September 2000, kerberos4 support was added. September, kerberos4 support was added.
In November 2000 started the work on a test suite for curl. It was later In November started the work on a test suite for curl. It was later re-written
re-written from scratch again. The libcurl major SONAME number was set to 1. from scratch again. The libcurl major SONAME number was set to 1.
January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or 2001
----
January, Daniel released curl 7.5.2 under a new license again: MIT (or
MPL). The MIT license is extremely liberal and can be used combined with GPL MPL). The MIT license is extremely liberal and can be used combined with GPL
in other projects. This would finally put an end to the "complaints" from in other projects. This would finally put an end to the "complaints" from
people involved in GPLed projects that previously were prohibited from using people involved in GPLed projects that previously were prohibited from using
@@ -92,17 +109,20 @@ code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
The first experimental ftps:// support was added in March 2001. The first experimental ftps:// support was added in March 2001.
August 2001. curl is bundled in Mac OS X, 10.1. It was already becoming more August. curl is bundled in Mac OS X, 10.1. It was already becoming more and
and more of a standard utility of Linux distributions and a regular in the BSD more of a standard utility of Linux distributions and a regular in the BSD
ports collections. The curl web site gets 8000 visits weekly. Curl Corporation ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
contacted Daniel to discuss "the name issue". After Daniel's reply, they have contacted Daniel to discuss "the name issue". After Daniel's reply, they have
never since got in touch again. never since got in touch again.
September 2001, libcurl 7.9 introduces cookie jar and curl_formadd(). During September, libcurl 7.9 introduces cookie jar and curl_formadd(). During the
the forthcoming 7.9.x releases, we introduced the multi interface slowly and forthcoming 7.9.x releases, we introduced the multi interface slowly and
without much whistles. without much whistles.
June 2002, the curl web site gets 13000 visits weekly. curl and libcurl is 2002
----
June, the curl web site gets 13000 visits weekly. curl and libcurl is
35000 lines of code. Reported successful compiles on more than 40 combinations 35000 lines of code. Reported successful compiles on more than 40 combinations
of CPUs and operating systems. of CPUs and operating systems.
@@ -111,33 +131,36 @@ impossible. Around 5000 downloaded packages each week from the main site gives
a hint, but the packages are mirrored extensively, bundled with numerous OS a hint, but the packages are mirrored extensively, bundled with numerous OS
distributions and otherwise retrieved as part of other software. distributions and otherwise retrieved as part of other software.
September 2002, with the release of curl 7.10 it is released under the MIT September, with the release of curl 7.10 it is released under the MIT license
license only. only.
January 2003. Started working on the distributed curl tests. The autobuilds. 2003
----
February 2003, the curl site averages at 20000 visits weekly. At any given January. Started working on the distributed curl tests. The autobuilds.
moment, there's an average of 3 people browsing the curl.haxx.se site.
February, the curl site averages at 20000 visits weekly. At any given moment,
there's an average of 3 people browsing the curl.haxx.se site.
Multiple new authentication schemes are supported: Digest (May), NTLM (June) Multiple new authentication schemes are supported: Digest (May), NTLM (June)
and Negotiate (June). and Negotiate (June).
November 2003: curl 7.10.8 is released. 45000 lines of code. ~55000 unique November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors
visitors to the curl.haxx.se site. Five official web mirrors. to the curl.haxx.se site. Five official web mirrors.
December 2003, full-fledged SSL for FTP is supported. December, full-fledged SSL for FTP is supported.
January 2004: curl 7.11.0 introduced large file support. 2004
----
June 2004: January: curl 7.11.0 introduced large file support.
curl 7.12.0 introduced IDN support. 10 official web mirrors. June: curl 7.12.0 introduced IDN support. 10 official web mirrors.
This release bumped the major SONAME to 3 due to the removal of the This release bumped the major SONAME to 3 due to the removal of the
curl_formparse() function curl_formparse() function
August 2004: August: Curl and libcurl 7.12.1
Curl and libcurl 7.12.1
Public curl release number: 82 Public curl release number: 82
Releases counted from the very beginning: 109 Releases counted from the very beginning: 109
@@ -147,52 +170,45 @@ August 2004:
Amount of public web site mirrors: 12 Amount of public web site mirrors: 12
Number of known libcurl bindings: 26 Number of known libcurl bindings: 26
April 2005: 2005
----
GnuTLS can now optionally be used for the secure layer when curl is built. April. GnuTLS can now optionally be used for the secure layer when curl is
built.
September 2005: September: TFTP support was added.
TFTP support was added. More than 100,000 unique visitors of the curl web site. 25 mirrors.
More than 100,000 unique visitors of the curl web site. 25 mirrors. December: security vulnerability: libcurl URL Buffer Overflow
December 2005: 2006
----
security vulnerability: libcurl URL Buffer Overflow January. We dropped support for Gopher. We found bugs in the implementation
that turned out having been introduced years ago, so with the conclusion that
nobody had found out in all this time we removed it instead of fixing it.
January 2006: March: security vulnerability: libcurl TFTP Packet Buffer Overflow
We dropped support for Gopher. We found bugs in the implementation that April: Added the multi_socket() API
turned out having been introduced years ago, so with the conclusion that
nobody had found out in all this time we removed it instead of fixing it.
March 2006: September: The major SONAME number for libcurl was bumped to 4 due to the
removal of ftp third party transfer support.
security vulnerability: libcurl TFTP Packet Buffer Overflow November: Added SCP and SFTP support
April 2006: 2007
----
Added the multi_socket() API February: Added support for the Mozilla NSS library to do the SSL/TLS stuff
September 2006: July: security vulnerability: libcurl GnuTLS insufficient cert verification
The major SONAME number for libcurl was bumped to 4 due to the removal of 2008
ftp third party transfer support. ----
November 2006: November:
Added SCP and SFTP support
February 2007:
Added support for the Mozilla NSS library to do the SSL/TLS stuff
July 2007:
security vulnerability: libcurl GnuTLS insufficient cert verification
November 2008:
Command line options: 128 Command line options: 128
curl_easy_setopt() options: 158 curl_easy_setopt() options: 158
@@ -202,37 +218,30 @@ November 2008:
145,000 unique visitors. >100 GB downloaded. 145,000 unique visitors. >100 GB downloaded.
March 2009: 2009
----
security vulnerability: libcurl Arbitrary File Access March: security vulnerability: libcurl Arbitrary File Access
August 2009: August: security vulnerability: libcurl embedded zero in cert name
security vulnerability: libcurl embedded zero in cert name December: Added support for IMAP, POP3 and SMTP
December 2009: 2010
----
Added support for IMAP, POP3 and SMTP January: Added support for RTSP
January 2010: February: security vulnerability: libcurl data callback excessive length
Added support for RTSP March: The project switched over to use git (hosted by github) instead of CVS
for source code control
February 2010: May: Added support for RTMP
security vulnerability: libcurl data callback excessive length Added support for PolarSSL to do the SSL/TLS stuff
March 2010: August:
The project switched over to use git instead of CVS for source code control
May 2010:
Added support for RTMP
Added support for PolarSSL to do the SSL/TLS stuff
August 2010:
Public curl releases: 117 Public curl releases: 117
Command line options: 138 Command line options: 138
@@ -242,3 +251,25 @@ August 2010:
Contributors: 808 Contributors: 808
Gopher support added (re-added actually) Gopher support added (re-added actually)
2012
----
July: Added support for Schannel (native Windows TLS backend) and Darwin SSL
(Native Mac OS X and iOS TLS backend).
Supports metalink
October: SSH-agent support.
2013
----
February: Cleaned up internals to always uses the "multi" non-blocking
approach internally and only expose the blocking API with a wrapper.
September: First small steps on supporting HTTP/2 with nghttp2.
October: Removed krb4 support.
December: Happy eyeballs.

View File

@@ -47,6 +47,7 @@ Portability
axTLS 1.2.7 axTLS 1.2.7
PolarSSL 1.3.0 PolarSSL 1.3.0
Heimdal ? Heimdal ?
nghttp2 0.6.0
On systems where configure runs, we aim at working on them all - if they have On systems where configure runs, we aim at working on them all - if they have
a suitable C compiler. On systems that don't run configure, we strive to keep a suitable C compiler. On systems that don't run configure, we strive to keep

View File

@@ -51,10 +51,6 @@ may have been fixed since this was written!
any file at all. Like when using FTP. any file at all. Like when using FTP.
http://curl.haxx.se/bug/view.cgi?id=1063 http://curl.haxx.se/bug/view.cgi?id=1063
77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
"abuses" the underlying connection re-use system and if connections are
forced to close they break the NTLM support.
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on 76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
that platform), and long is only 32 bits. It makes it impossible for that platform), and long is only 32 bits. It makes it impossible for
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
@@ -216,9 +212,9 @@ may have been fixed since this was written!
acknowledged after the actual TCP connect (during the SOCKS "negotiate" acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase). phase).
10. To get HTTP Negotiate authentication to work fine, you need to provide a 10. To get HTTP Negotiate (SPNEGO) authentication to work fine, you need to
(fake) user name (this concerns both curl and the lib) because the code provide a (fake) user name (this concerns both curl and the lib) because the
wrongly only considers authentication if there's a user name provided. code wrongly only considers authentication if there's a user name provided.
http://curl.haxx.se/bug/view.cgi?id=440 How? http://curl.haxx.se/bug/view.cgi?id=440 How?
http://curl.haxx.se/mail/lib-2004-08/0182.html http://curl.haxx.se/mail/lib-2004-08/0182.html

View File

@@ -94,12 +94,6 @@ GNU GSS http://www.gnu.org/software/gss/
may not distribute binary curl packages that uses this if you build may not distribute binary curl packages that uses this if you build
curl to also link and use any Original BSD licensed libraries! curl to also link and use any Original BSD licensed libraries!
fbopenssl
(Used for SPNEGO support) Unclear license. Based on its name, I assume
that it uses the OpenSSL license and thus shares the same issues as
described for OpenSSL above.
libidn http://josefsson.org/libidn/ libidn http://josefsson.org/libidn/
(Used for IDNA support) Uses the GNU Lesser General Public (Used for IDNA support) Uses the GNU Lesser General Public

View File

@@ -14,6 +14,7 @@ MAIL ETIQUETTE
1.5 Moderation of new posters 1.5 Moderation of new posters
1.6 Handling trolls and spam 1.6 Handling trolls and spam
1.7 How to unsubscribe 1.7 How to unsubscribe
1.8 I posted, now what?
2. Sending mail 2. Sending mail
2.1 Reply or New Mail 2.1 Reply or New Mail
@@ -125,6 +126,42 @@ MAIL ETIQUETTE
You NEVER EVER email the mailing list requesting someone else to get you off You NEVER EVER email the mailing list requesting someone else to get you off
the list. the list.
1.8 I posted, now what?
If you aren't subscribed with the exact same email address that you used to
send the email, your post will just be silently discarded.
If you posted for the first time to the mailing list, you first need to wait
for an administrator to allow your email to go through. This normally
happens very quickly but in case we're asleep, you may have to wait a few
hours.
Once your email goes through it is sent out to several hundred or even
thousand recipients. Your email may cover an area that not that many people
know about or are interested in. Or possibly the person who knows about it
is on vacation or under a very heavy work load right now. You have to wait
for a response and you must not expect to get a response at all, but
hopefully you get an answer within a couple of days.
You do yourself and all of us a service when you include as many details as
possible already in your first email. Mention your operating system and
environment. Tell us which curl version you're using and tell us what you
did, what happened and what you expected would happen. Preferably, show us
what you did in details enough to allow others to help point out the problem
or repeat the same steps in their places.
Failing to include details will only delay responses and make people respond
and ask for the details and you have to send a follow-up email that includes
them.
Expect the responses to primarily help YOU debug the issue, or ask you
questions that can lead you or others towards a solution or explanation to
whatever you experience.
If you are a repeat offender to the guidelines outlined in this document,
chances are that people will ignore you at will and your chances to get
responses will greatly diminish.
2. Sending mail 2. Sending mail

View File

@@ -108,10 +108,10 @@ USING PASSWORDS
curl -u name:passwd http://machine.domain/full/path/to/file curl -u name:passwd http://machine.domain/full/path/to/file
HTTP offers many different methods of authentication and curl supports HTTP offers many different methods of authentication and curl supports
several: Basic, Digest, NTLM and Negotiate. Without telling which method to several: Basic, Digest, NTLM and Negotiate (SPNEGO). Without telling which
use, curl defaults to Basic. You can also ask curl to pick the most secure method to use, curl defaults to Basic. You can also ask curl to pick the
ones out of the ones that the server accepts for the given URL, by using most secure ones out of the ones that the server accepts for the given URL,
--anyauth. by using --anyauth.
NOTE! According to the URL specification, HTTP URLs can not contain a user NOTE! According to the URL specification, HTTP URLs can not contain a user
and password, so that style will not work when using curl via a proxy, even and password, so that style will not work when using curl via a proxy, even

View File

@@ -89,3 +89,15 @@ announcement.
mentioned. mentioned.
[1] = http://oss-security.openwall.org/wiki/mailing-lists/distros [1] = http://oss-security.openwall.org/wiki/mailing-lists/distros
CURL-SECURITY (at haxx dot se)
Who is on this list? There are a couple of criteria you must meet, and then we
might ask you to join the list or you can ask to join it. It really isn't very
formal. We basically only require that you have a long-term presence in the
curl project and you have shown an understanding for the project and its way
of working. You must've been around for a good while and you should have no
plans in vanishing in the near future.
We do not make the list of partipants public mostly because it tends to vary
somewhat over time and a list somewhere will only risk getting outdated.

View File

@@ -1,5 +1,5 @@
Peer SSL Certificate Verification Peer SSL Certificate Verification
================================= =================================
(NOTE: If libcurl was built with Schannel or Secure Transport support, then (NOTE: If libcurl was built with Schannel or Secure Transport support, then
this does not apply to you. Scroll down for details on how the OS-native this does not apply to you. Scroll down for details on how the OS-native
@@ -26,13 +26,13 @@ impersonating your favorite site, and you want to transfer files from this
server, do one of the following: server, do one of the following:
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with 1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); `curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);`
With the curl command line tool, you disable this with -k/--insecure. With the curl command line tool, you disable this with -k/--insecure.
2. Get a CA certificate that can verify the remote server and use the proper 2. Get a CA certificate that can verify the remote server and use the proper
option to point out this CA cert for verification when connecting. For option to point out this CA cert for verification when connecting. For
libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath); libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);`
With the curl command line tool: --cacert [file] With the curl command line tool: --cacert [file]
@@ -46,32 +46,32 @@ server, do one of the following:
If you use Internet Explorer, this is one way to get extract the CA cert If you use Internet Explorer, this is one way to get extract the CA cert
for a particular server: for a particular server:
o View the certificate by double-clicking the padlock - View the certificate by double-clicking the padlock
o Find out where the CA certificate is kept (Certificate> - Find out where the CA certificate is kept (Certificate>
Authority Information Access>URL) Authority Information Access>URL)
o Get a copy of the crt file using curl - Get a copy of the crt file using curl
o Convert it from crt to PEM using the openssl tool: - Convert it from crt to PEM using the openssl tool:
openssl x509 -inform DES -in yourdownloaded.crt \ openssl x509 -inform DES -in yourdownloaded.crt \
-out outcert.pem -text -out outcert.pem -text
o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone - Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
as described below. as described below.
If you use the 'openssl' tool, this is one way to get extract the CA cert If you use the 'openssl' tool, this is one way to get extract the CA cert
for a particular server: for a particular server:
o openssl s_client -connect xxxxx.com:443 |tee logfile - `openssl s_client -connect xxxxx.com:443 |tee logfile`
o type "QUIT", followed by the "ENTER" key - type "QUIT", followed by the "ENTER" key
o The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE" - The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
markers. markers.
o If you want to see the data in the certificate, you can do: "openssl - If you want to see the data in the certificate, you can do: "openssl
x509 -inform PEM -in certfile -text -out certdata" where certfile is x509 -inform PEM -in certfile -text -out certdata" where certfile is
the cert you extracted from logfile. Look in certdata. the cert you extracted from logfile. Look in certdata.
o If you want to trust the certificate, you can append it to your - If you want to trust the certificate, you can append it to your
cert_bundle or use it stand-alone as described. Just remember that the cert bundle or use it stand-alone as described. Just remember that the
security is no better than the way you obtained the certificate. security is no better than the way you obtained the certificate.
4. If you're using the curl command line tool, you can specify your own CA 4. If you're using the curl command line tool, you can specify your own CA
cert path by setting the environment variable CURL_CA_BUNDLE to the path cert path by setting the environment variable `CURL_CA_BUNDLE` to the path
of your choice. of your choice.
If you're using the curl command line tool on Windows, curl will search If you're using the curl command line tool on Windows, curl will search
@@ -86,9 +86,7 @@ server, do one of the following:
5. Get a better/different/newer CA cert bundle! One option is to extract the 5. Get a better/different/newer CA cert bundle! One option is to extract the
one a recent Firefox browser uses by running 'make ca-bundle' in the curl one a recent Firefox browser uses by running 'make ca-bundle' in the curl
build tree root, or possibly download a version that was generated this build tree root, or possibly download a version that was generated this
way for you: way for you: [CA Extract](http://curl.haxx.se/docs/caextract.html)
http://curl.haxx.se/docs/caextract.html
Neglecting to use one of the above methods when dealing with a server using a Neglecting to use one of the above methods when dealing with a server using a
certificate that isn't signed by one of the certificates in the installed CA certificate that isn't signed by one of the certificates in the installed CA
@@ -96,32 +94,26 @@ cert bundle, will cause SSL to report an error ("certificate verify failed")
during the handshake and SSL will then refuse further communication with that during the handshake and SSL will then refuse further communication with that
server. server.
Peer SSL Certificate Verification with NSS Peer SSL Certificate Verification with NSS
========================================== ==========================================
If libcurl was built with NSS support, then depending on the OS distribution, If libcurl was built with NSS support, then depending on the OS distribution,
it is probably required to take some additional steps to use the system-wide CA it is probably required to take some additional steps to use the system-wide CA
cert db. RedHat ships with an additional module, libnsspem.so, which enables cert db. RedHat ships with an additional module, libnsspem.so, which enables
NSS to read the OpenSSL PEM CA bundle. This library is missing in OpenSuSE, and NSS to read the OpenSSL PEM CA bundle. This library is missing in OpenSuSE, and
without it, NSS can only work with its own internal formats. NSS also has a new without it, NSS can only work with its own internal formats. NSS also has a new
database format: https://wiki.mozilla.org/NSS_Shared_DB [database format](https://wiki.mozilla.org/NSS_Shared_DB).
Starting with version 7.19.7, libcurl will check for the NSS version it runs, Starting with version 7.19.7, libcurl automatically adds the 'sql:' prefix to
and automatically add the 'sql:' prefix to the certdb directory (either the the certdb directory (either the hardcoded default /etc/pki/nssdb or the
hardcoded default /etc/pki/nssdb or the directory configured with SSL_DIR directory configured with SSL_DIR environment variable). To check which certdb
environment variable) if version 3.12.0 or later is detected. To check which format your distribution provides, examine the default certdb location:
certdb format your distribution provides, examine the default /etc/pki/nssdb; the new certdb format can be identified by the filenames
certdb location: /etc/pki/nssdb; the new certdb format can be identified by cert9.db, key4.db, pkcs11.txt; filenames of older versions are cert8.db,
the filenames cert9.db, key4.db, pkcs11.txt; filenames of older versions are key3.db, secmod.db.
cert8.db, key3.db, modsec.db.
Usually these cert databases are empty, but NSS also has built-in CAs which are Peer SSL Certificate Verification with Schannel and Secure Transport
provided through a shared library, libnssckbi.so; if you want to use these ====================================================================
built-in CAs, then create a symlink to libnssckbi.so in /etc/pki/nssdb:
ln -s /usr/lib[64]/libnssckbi.so /etc/pki/nssdb/libnssckbi.so
Peer SSL Certificate Verification with Schannel and Secure Transport
====================================================================
If libcurl was built with Schannel (Microsoft's TLS/SSL engine) or Secure If libcurl was built with Schannel (Microsoft's TLS/SSL engine) or Secure
Transport (Apple's TLS/SSL engine) support, then libcurl will still perform Transport (Apple's TLS/SSL engine) support, then libcurl will still perform

View File

@@ -22,7 +22,7 @@ Alan Pinstein
Albert Chin-A-Young Albert Chin-A-Young
Albert Choy Albert Choy
Ale Vesely Ale Vesely
Alejandro Alvarez Alejandro Alvarez Ayllon
Aleksandar Milivojevic Aleksandar Milivojevic
Aleksey Tulinov Aleksey Tulinov
Alessandro Ghedini Alessandro Ghedini
@@ -48,6 +48,7 @@ Alexey Zakhlestin
Alexis Carvalho Alexis Carvalho
Alfred Gebert Alfred Gebert
Allen Pulsifer Allen Pulsifer
Alona Rossen
Amol Pattekar Amol Pattekar
Amr Shahin Amr Shahin
Anatoli Tubman Anatoli Tubman
@@ -55,6 +56,7 @@ Anders Gustafsson
Anders Havn Anders Havn
Andi Jahja Andi Jahja
Andre Guibert de Bruet Andre Guibert de Bruet
Andre Heinecke
Andreas Damm Andreas Damm
Andreas Faerber Andreas Faerber
Andreas Farber Andreas Farber
@@ -66,6 +68,7 @@ Andreas Schuldei
Andreas Wurf Andreas Wurf
Andrei Benea Andrei Benea
Andrei Cipu Andrei Cipu
Andrei Kurushin
Andrej E Baranov Andrej E Baranov
Andres Garcia Andres Garcia
Andrew Benham Andrew Benham
@@ -83,6 +86,7 @@ Andy Cedilnik
Andy Serpa Andy Serpa
Andy Tsouladze Andy Tsouladze
Angus Mackay Angus Mackay
Anthon Pang
Anthony Bryan Anthony Bryan
Anthony G. Basile Anthony G. Basile
Antoine Calando Antoine Calando
@@ -97,6 +101,8 @@ Arnaud Ebalard
Arthur Murray Arthur Murray
Arve Knudsen Arve Knudsen
Arvid Norberg Arvid Norberg
Ask Bjørn Hansen
Askar Safin
Ates Goral Ates Goral
Augustus Saunders Augustus Saunders
Avery Fay Avery Fay
@@ -116,6 +122,7 @@ Benbuck Nason
Benjamin Gerard Benjamin Gerard
Benjamin Gilbert Benjamin Gilbert
Benjamin Johnson Benjamin Johnson
Benoit Neil
Benoit Sigoure Benoit Sigoure
Bernard Leak Bernard Leak
Bernhard Reutner-Fischer Bernhard Reutner-Fischer
@@ -138,6 +145,7 @@ Brad Hards
Brad King Brad King
Brad Spencer Brad Spencer
Bradford Bruce Bradford Bruce
Brandon Casey
Brandon Wang Brandon Wang
Brendan Jurd Brendan Jurd
Brent Beardsley Brent Beardsley
@@ -157,6 +165,7 @@ Camille Moncelier
Caolan McNamara Caolan McNamara
Carsten Lange Carsten Lange
Casey O'Donnell Casey O'Donnell
Catalin Patulea
Cedric Deltheil Cedric Deltheil
Chad Monroe Chad Monroe
Chandrakant Bagul Chandrakant Bagul
@@ -173,6 +182,7 @@ Chris Gaukroger
Chris Maltby Chris Maltby
Chris Mumford Chris Mumford
Chris Smowton Chris Smowton
Chris Young
Christian Grothoff Christian Grothoff
Christian Hägele Christian Hägele
Christian Krause Christian Krause
@@ -195,6 +205,7 @@ Clifford Wolf
Cody Jones Cody Jones
Cody Mack Cody Mack
Colby Ranger Colby Ranger
Colin Blair
Colin Hogben Colin Hogben
Colin Watson Colin Watson
Colm Buckley Colm Buckley
@@ -254,6 +265,7 @@ David Kimdon
David Lang David Lang
David LeBlanc David LeBlanc
David McCreedy David McCreedy
David Meyer
David Odin David Odin
David Phillips David Phillips
David Rosenstrauch David Rosenstrauch
@@ -267,6 +279,7 @@ David Woodhouse
David Wright David Wright
David Yan David Yan
Dengminwen Dengminwen
Dennis Clarke
Derek Higgins Derek Higgins
Detlef Schmier Detlef Schmier
Didier Brisebourg Didier Brisebourg
@@ -275,6 +288,7 @@ Dilyan Palauzov
Dima Barsky Dima Barsky
Dima Tisnek Dima Tisnek
Dimitre Dimitrov Dimitre Dimitrov
Dimitrios Siganos
Dimitris Sarris Dimitris Sarris
Dinar Dinar
Dirk Eddelbuettel Dirk Eddelbuettel
@@ -282,6 +296,7 @@ Dirk Manske
Dmitri Shubin Dmitri Shubin
Dmitriy Sergeyev Dmitriy Sergeyev
Dmitry Bartsevich Dmitry Bartsevich
Dmitry Falko
Dmitry Kurochkin Dmitry Kurochkin
Dmitry Popov Dmitry Popov
Dmitry Rechkin Dmitry Rechkin
@@ -297,13 +312,13 @@ Douglas R. Horner
Douglas Steinwand Douglas Steinwand
Dov Murik Dov Murik
Duane Cathey Duane Cathey
Duncan
Duncan Mac-Vicar Prett Duncan Mac-Vicar Prett
Dustin Boswell Dustin Boswell
Dylan Ellicott Dylan Ellicott
Dylan Salisbury Dylan Salisbury
Early Ehlinger Early Ehlinger
Ebenezer Ikonne Ebenezer Ikonne
Ed Morley
Edin Kadribasic Edin Kadribasic
Eduard Bloch Eduard Bloch
Edward Rudd Edward Rudd
@@ -333,8 +348,10 @@ Eric Wong
Eric Young Eric Young
Erick Nuwendam Erick Nuwendam
Erik Johansson Erik Johansson
Ernest Beinrohr
Erwan Legrand Erwan Legrand
Erwin Authried Erwin Authried
Ethan Glasser Camp
Eugene Kotlyarov Eugene Kotlyarov
Evan Jordan Evan Jordan
Evgeny Turnaev Evgeny Turnaev
@@ -348,6 +365,7 @@ Felix Yan
Felix von Leitner Felix von Leitner
Feng Tu Feng Tu
Florian Schoppmann Florian Schoppmann
Florian Weimer
Forrest Cahoon Forrest Cahoon
Francois Charlier Francois Charlier
Frank Hempel Frank Hempel
@@ -357,6 +375,7 @@ Frank Meier
Frank Ticheler Frank Ticheler
Frank Van Uffelen Frank Van Uffelen
František Kučera František Kučera
François Charlier
Fred Machado Fred Machado
Fred New Fred New
Fred Noz Fred Noz
@@ -390,6 +409,7 @@ Gilles Blanc
Gisle Vanem Gisle Vanem
Giuseppe Attardi Giuseppe Attardi
Giuseppe D'Ambrosio Giuseppe D'Ambrosio
Glen A Johnson Jr.
Glen Nakamura Glen Nakamura
Glen Scott Glen Scott
Glenn Sheridan Glenn Sheridan
@@ -400,14 +420,17 @@ Grant Erickson
Greg Hewgill Greg Hewgill
Greg Morse Greg Morse
Greg Onufer Greg Onufer
Greg Pratt
Greg Zavertnik Greg Zavertnik
Grigory Entin Grigory Entin
Guenole Bescon Guenole Bescon
Guenter Knauf Guenter Knauf
Guido Berhoerster Guido Berhoerster
Guillaume Arluison Guillaume Arluison
Gunter Knauf
Gustaf Hui Gustaf Hui
Gwenole Beauchesne Gwenole Beauchesne
Gökhan Şengün
Götz Babin-Ebell Götz Babin-Ebell
Hamish Mackenzie Hamish Mackenzie
Hang Kin Lau Hang Kin Lau
@@ -416,12 +439,14 @@ Hanno Kranzhoff
Hans Steegers Hans Steegers
Hans-Jurgen May Hans-Jurgen May
Hardeep Singh Hardeep Singh
Haris Okanovic
Harshal Pradhan Harshal Pradhan
Hauke Duden Hauke Duden
He Qin He Qin
Heikki Korpela Heikki Korpela
Heinrich Ko Heinrich Ko
Heinrich Schaefer Heinrich Schaefer
Helwing Lutz
Hendrik Visage Hendrik Visage
Henrik Storner Henrik Storner
Henry Ludemann Henry Ludemann
@@ -457,6 +482,7 @@ Jacky Lam
Jacob Meuser Jacob Meuser
Jacob Moshenko Jacob Moshenko
Jad Chamcham Jad Chamcham
Jakub Zakrzewski
James Bursa James Bursa
James Cheng James Cheng
James Clancy James Clancy
@@ -476,6 +502,7 @@ Jan Schaumann
Jan Van Boghout Jan Van Boghout
Jared Jennings Jared Jennings
Jared Lundell Jared Lundell
Jari Aalto
Jari Sundell Jari Sundell
Jason Glasgow Jason Glasgow
Jason Liu Jason Liu
@@ -490,7 +517,7 @@ Jean-Claude Chauve
Jean-Francois Bertrand Jean-Francois Bertrand
Jean-Louis Lemaire Jean-Louis Lemaire
Jean-Marc Ranger Jean-Marc Ranger
Jean-Noel Rouvignac Jean-Noël Rouvignac
Jean-Philippe Barrette-LaPierre Jean-Philippe Barrette-LaPierre
Jeff Connelly Jeff Connelly
Jeff Hodges Jeff Hodges
@@ -500,11 +527,11 @@ Jeff Lawson
Jeff Phillips Jeff Phillips
Jeff Pohlmeyer Jeff Pohlmeyer
Jeff Weber Jeff Weber
Jeffrey Pohlmeyer
Jeremy Friesner Jeremy Friesner
Jeremy Huddleston Jeremy Huddleston
Jeroen Koekkoek Jeroen Koekkoek
Jerome Muffat-Meridol Jerome Muffat-Meridol
Jerome Robert
Jerome Vouillon Jerome Vouillon
Jerry Krinock Jerry Krinock
Jerry Wu Jerry Wu
@@ -529,7 +556,9 @@ Johan Anderson
Johan Nilsson Johan Nilsson
Johan van Selst Johan van Selst
Johannes Bauer Johannes Bauer
Johannes Ernst
John Bradshaw John Bradshaw
John Coffey
John Crow John Crow
John Dennis John Dennis
John Dunn John Dunn
@@ -540,6 +569,7 @@ John Joseph Bachir
John Kelly John Kelly
John Lask John Lask
John Lightsey John Lightsey
John Malmberg
John Marino John Marino
John McGowan John McGowan
John P. McCaskey John P. McCaskey
@@ -556,9 +586,12 @@ Jon Turner
Jonas Forsman Jonas Forsman
Jonas Schnelli Jonas Schnelli
Jonatan Lander Jonatan Lander
Jonatan Vela
Jonathan Cardoso Machado
Jonathan Hseu Jonathan Hseu
Jonathan Nieder Jonathan Nieder
Jongki Suwandi Jongki Suwandi
Jose Alf
Jose Kahan Jose Kahan
Josef Wolf Josef Wolf
Josh Kapell Josh Kapell
@@ -624,6 +657,7 @@ Lachlan O'Dea
Larry Campbell Larry Campbell
Larry Fahnoe Larry Fahnoe
Larry Lin Larry Lin
Larry Stone
Lars Buitinck Lars Buitinck
Lars Gustafsson Lars Gustafsson
Lars J. Aas Lars J. Aas
@@ -639,9 +673,11 @@ Len Krause
Lenaic Lefever Lenaic Lefever
Lenny Rachitsky Lenny Rachitsky
Leon Winter Leon Winter
Leonardo Rosati
Liam Healy Liam Healy
Lijo Antony Lijo Antony
Linas Vepstas Linas Vepstas
Lindley French
Ling Thio Ling Thio
Linus Nielsen Feltzing Linus Nielsen Feltzing
Lisa Xu Lisa Xu
@@ -652,12 +688,14 @@ Loren Kirkby
Luca Altea Luca Altea
Luca Alteas Luca Alteas
Lucas Adamski Lucas Adamski
Ludek Finstrle
Ludovico Cavedon Ludovico Cavedon
Lukasz Czekierda Lukasz Czekierda
Luke Amery Luke Amery
Luke Call Luke Call
Luke Dashjr Luke Dashjr
Luong Dinh Dung Luong Dinh Dung
Lyndon Hill
Maciej Karpiuk Maciej Karpiuk
Maciej Puzio Maciej Puzio
Maciej W. Rozycki Maciej W. Rozycki
@@ -713,6 +751,7 @@ Mateusz Loskot
Mathias Axelsson Mathias Axelsson
Mats Lidell Mats Lidell
Matt Arsenault Matt Arsenault
Matt Ford
Matt Kraai Matt Kraai
Matt Veenstra Matt Veenstra
Matt Witherspoon Matt Witherspoon
@@ -748,10 +787,12 @@ Michael Stillwell
Michael Wallner Michael Wallner
Michal Bonino Michal Bonino
Michal Gorny Michal Gorny
Michal Kowalczyk
Michal Marek Michal Marek
Michał Górny
Michał Kowalczyk
Michele Bini Michele Bini
Miguel Angel Miguel Angel
Miguel Diaz
Mihai Ionescu Mihai Ionescu
Mikael Johansson Mikael Johansson
Mikael Sennerholm Mikael Sennerholm
@@ -760,12 +801,14 @@ Mike Crowe
Mike Dobbs Mike Dobbs
Mike Giancola Mike Giancola
Mike Hasselberg Mike Hasselberg
Mike Henshaw
Mike Hommey Mike Hommey
Mike Mio Mike Mio
Mike Power Mike Power
Mike Protts Mike Protts
Mike Revi Mike Revi
Miklos Nemeth Miklos Nemeth
Miroslav Spousta
Mitz Wark Mitz Wark
Mohamed Lrhazi Mohamed Lrhazi
Mohammad AlSaleh Mohammad AlSaleh
@@ -803,11 +846,12 @@ Nodak Sodak
Norbert Frese Norbert Frese
Norbert Novotny Norbert Novotny
Ofer Ofer
Ola Mork
Olaf Flebbe Olaf Flebbe
Olaf Stueben
Olaf Stüben Olaf Stüben
Oliver Gondža Oliver Gondža
Oliver Kuckertz Oliver Kuckertz
Oliver Schindler
Olivier Berger Olivier Berger
Oren Tirosh Oren Tirosh
Ori Avtalion Ori Avtalion
@@ -818,10 +862,12 @@ Paolo Piacentini
Paras Sethia Paras Sethia
Pascal Terjan Pascal Terjan
Pasha Kuznetsov Pasha Kuznetsov
Pasi Karkkainen
Pat Ray Pat Ray
Patrice Guerin Patrice Guerin
Patricia Muscalu Patricia Muscalu
Patrick Bihan-Faou Patrick Bihan-Faou
Patrick McManus
Patrick Monnerat Patrick Monnerat
Patrick Scott Patrick Scott
Patrick Smith Patrick Smith
@@ -836,6 +882,7 @@ Paul Marquis
Paul Moore Paul Moore
Paul Nolan Paul Nolan
Paul Querna Paul Querna
Paul Saab
Pavel Cenek Pavel Cenek
Pavel Orehov Pavel Orehov
Pavel Raiskup Pavel Raiskup
@@ -858,6 +905,7 @@ Peter Su
Peter Sylvester Peter Sylvester
Peter Todd Peter Todd
Peter Verhas Peter Verhas
Peter Wang
Peter Wullinger Peter Wullinger
Peteris Krumins Peteris Krumins
Petr Bahula Petr Bahula
@@ -889,6 +937,7 @@ Quinn Slack
Radu Simionescu Radu Simionescu
Rafa Muyo Rafa Muyo
Rafael Sagula Rafael Sagula
Rafaël Carré
Rainer Canavan Rainer Canavan
Rainer Jung Rainer Jung
Rainer Koenig Rainer Koenig
@@ -901,6 +950,7 @@ Randy McMurchy
Ravi Pratap Ravi Pratap
Ray Dassen Ray Dassen
Ray Pekowski Ray Pekowski
Ray Satiro
Reinout van Schouwen Reinout van Schouwen
Remi Gacogne Remi Gacogne
Renato Botelho Renato Botelho
@@ -921,6 +971,7 @@ Richard Clayton
Richard Cooper Richard Cooper
Richard Gorton Richard Gorton
Richard Michael Richard Michael
Richard Moore
Richard Prescott Richard Prescott
Richard Silverman Richard Silverman
Rick Jones Rick Jones
@@ -944,6 +995,7 @@ Robin Johnson
Robin Kay Robin Kay
Robson Braga Araujo Robson Braga Araujo
Rodney Simmons Rodney Simmons
Rodric Glaser
Rodrigo Silva Rodrigo Silva
Roland Blom Roland Blom
Roland Krikava Roland Krikava
@@ -952,6 +1004,7 @@ Rolland Dudemaine
Roman Koifman Roman Koifman
Roman Mamedov Roman Mamedov
Romulo A. Ceccon Romulo A. Ceccon
Ron Parker
Ron Zapp Ron Zapp
Rosimildo da Silva Rosimildo da Silva
Roy Shan Roy Shan
@@ -978,6 +1031,7 @@ Santhana Todatry
Saqib Ali Saqib Ali
Sara Golemon Sara Golemon
Saran Neti Saran Neti
Sascha Swiercy
Saul good Saul good
Scott Bailey Scott Bailey
Scott Barrett Scott Barrett
@@ -1008,6 +1062,7 @@ Song Ma
Sonia Subramanian Sonia Subramanian
Spacen Jasset Spacen Jasset
Spiridonoff A.V Spiridonoff A.V
Spork Schivago
Stadler Stephan Stadler Stephan
Stan van de Burgt Stan van de Burgt
Stanislav Ivochkin Stanislav Ivochkin
@@ -1017,6 +1072,7 @@ Stefan Neis
Stefan Teleman Stefan Teleman
Stefan Tomanek Stefan Tomanek
Stefan Ulrich Stefan Ulrich
Steinar H. Gunderson
Stephan Bergmann Stephan Bergmann
Stephen Collyer Stephen Collyer
Stephen Kick Stephen Kick
@@ -1036,6 +1092,7 @@ Steven Gu
Steven M. Schweda Steven M. Schweda
Steven Parkes Steven Parkes
Stoned Elipot Stoned Elipot
Sune Ahlgren
Sven Anders Sven Anders
Sven Neuhaus Sven Neuhaus
Sven Wegener Sven Wegener
@@ -1064,6 +1121,7 @@ Tim Harder
Tim Heckman Tim Heckman
Tim Newsome Tim Newsome
Tim Sneddon Tim Sneddon
Tim Starling
Timo Sirainen Timo Sirainen
Tinus van den Berg Tinus van den Berg
Tobias Markus Tobias Markus
@@ -1136,6 +1194,7 @@ Wez Furlong
Wilfredo Sanchez Wilfredo Sanchez
Will Dietz Will Dietz
Willem Sparreboom Willem Sparreboom
William Ahern
Wojciech Zwiefka Wojciech Zwiefka
Wouter Van Rooy Wouter Van Rooy
Wu Yongzheng Wu Yongzheng
@@ -1144,10 +1203,12 @@ Yaakov Selkowitz
Yamada Yasuharu Yamada Yasuharu
Yang Tse Yang Tse
Yarram Sunil Yarram Sunil
Yasuharu Yamada
Yehezkel Horowitz Yehezkel Horowitz
Yehoshua Hershberg Yehoshua Hershberg
Yi Huang Yi Huang
Yingwei Liu Yingwei Liu
Yousuke Kimoto
Yukihiro Kawada Yukihiro Kawada
Yuriy Sosov Yuriy Sosov
Yves Arrouye Yves Arrouye
@@ -1159,3 +1220,4 @@ Zvi Har'El
nk nk
swalkaus at yahoo.com swalkaus at yahoo.com
tommink[at]post.pl tommink[at]post.pl
Никита Дорохин

View File

@@ -33,6 +33,7 @@
4.3 Earlier bad letter detection 4.3 Earlier bad letter detection
4.4 REST for large files 4.4 REST for large files
4.5 ASCII support 4.5 ASCII support
4.6 GSSAPI via Windows SSPI
5. HTTP 5. HTTP
5.1 Better persistency for HTTP 1.0 5.1 Better persistency for HTTP 1.0
@@ -40,6 +41,7 @@
5.3 Rearrange request header order 5.3 Rearrange request header order
5.4 SPDY 5.4 SPDY
5.5 auth= in URLs 5.5 auth= in URLs
5.6 Digest via Windows SSPI
6. TELNET 6. TELNET
6.1 ditch stdin 6.1 ditch stdin
@@ -80,6 +82,7 @@
14. SASL 14. SASL
14.1 Other authentication mechanisms 14.1 Other authentication mechanisms
14.2 GSSAPI via GSS-API libraries
15. Client 15. Client
15.1 sync 15.1 sync
@@ -251,6 +254,12 @@
FTP ASCII transfers do not follow RFC959. They don't convert the data FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly. accordingly.
4.6 GSSAPI via Windows SSPI
In addition to currently supporting the SASL GSSAPI mechanism (Kerberos V5)
via third-party GSS-API libraries, such as Heimdal or MIT Kerberos, also add
support for GSSAPI authentication via Windows SSPI.
5. HTTP 5. HTTP
5.1 Better persistency for HTTP 1.0 5.1 Better persistency for HTTP 1.0
@@ -296,6 +305,12 @@
Additionally this should be implemented for proxy base URLs as well. Additionally this should be implemented for proxy base URLs as well.
5.6 Digest via Windows SSPI
libcurl already supports HTTP Digest Authentication via native routines as well
as SASL Digest via both Windows SSPI and native routines. In addition to this
libcurl should also support HTTP Digest Authentication via Windows SSPI.
6. TELNET 6. TELNET
6.1 ditch stdin 6.1 ditch stdin
@@ -440,7 +455,13 @@ to provide the data to send.
14.1 Other authentication mechanisms 14.1 Other authentication mechanisms
Add support for GSSAPI to SMTP, POP3 and IMAP. Add support for other authentication mechanisms such as EXTERNAL, OLP,
GSS-SPNEGO and others.
14.2 GSSAPI via GSS-API libraries
Add support for GSSAPI authentication via third-party GSS-API libraries, such
as Heimdal and MIT Kerberos.
15. Client 15. Client

View File

@@ -20,7 +20,7 @@
.\" * .\" *
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl 1 "27 July 2012" "Curl 7.27.0" "Curl Manual" .TH curl 1 "2 Aug 2014" "Curl 7.38.0" "Curl Manual"
.SH NAME .SH NAME
curl \- transfer a URL curl \- transfer a URL
.SH SYNOPSIS .SH SYNOPSIS
@@ -699,6 +699,10 @@ See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options.
Starting in 7.37.0, you need \fI--proxy-header\fP to send custom headers Starting in 7.37.0, you need \fI--proxy-header\fP to send custom headers
intended for a proxy. intended for a proxy.
Example:
\&# curl -H "X-First-Name: Joe" http://192.168.0.1/
This option can be used multiple times to add/replace/remove multiple headers. This option can be used multiple times to add/replace/remove multiple headers.
.IP "--hostpubmd5 <md5>" .IP "--hostpubmd5 <md5>"
(SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should (SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should
@@ -827,9 +831,8 @@ If this option is used several times, the last one will be used.
should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use
a level that is not one of these, 'private' will instead be used. a level that is not one of these, 'private' will instead be used.
This option requires a library built with kerberos4 or GSSAPI This option requires a library built with kerberos4 support. This is not
(GSS-Negotiate) support. This is not very common. Use \fI-V, --version\fP to very common. Use \fI-V, --version\fP to see if your curl supports it.
see if your curl supports it.
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-l, --list-only" .IP "-l, --list-only"
@@ -866,6 +869,10 @@ When curl follows a redirect and the request is not a plain GET (for example
POST or PUT), it will do the following request with a GET if the HTTP response POST or PUT), it will do the following request with a GET if the HTTP response
was 301, 302, or 303. If the response code was any other 3xx code, curl will was 301, 302, or 303. If the response code was any other 3xx code, curl will
re-send the following request using the same unmodified method. re-send the following request using the same unmodified method.
You can tell curl to not change the non-GET request method to GET after a 30x
response by using the dedicated options for that: \fI--post301\fP,
\fI--post302\fP and \fI-post303\fP.
.IP "--libcurl <file>" .IP "--libcurl <file>"
Append this option to any ordinary curl command line, and you will get a Append this option to any ordinary curl command line, and you will get a
libcurl-using C source code written to the file that does the equivalent libcurl-using C source code written to the file that does the equivalent
@@ -874,9 +881,10 @@ of what your command-line operation does!
If this option is used several times, the last given file name will be If this option is used several times, the last given file name will be
used. (Added in 7.16.1) used. (Added in 7.16.1)
.IP "--limit-rate <speed>" .IP "--limit-rate <speed>"
Specify the maximum transfer rate you want curl to use. This feature is useful Specify the maximum transfer rate you want curl to use - for both downloads
if you have a limited pipe and you'd like your transfer not to use your entire and uploads. This feature is useful if you have a limited pipe and you'd like
bandwidth. your transfer not to use your entire bandwidth. To make it slower than it
otherwise would be.
The given speed is measured in bytes/second, unless a suffix is appended. The given speed is measured in bytes/second, unless a suffix is appended.
Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
@@ -1024,18 +1032,13 @@ Very similar to \fI--netrc\fP, but this option makes the .netrc usage
\fBoptional\fP and not mandatory as the \fI--netrc\fP option does. \fBoptional\fP and not mandatory as the \fI--netrc\fP option does.
.IP "--negotiate" .IP "--negotiate"
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was (HTTP) Enables Negotiate (SPNEGO) authentication.
designed by Microsoft and is used in their web applications. It is primarily
meant as a support for Kerberos5 authentication but may be also used along
with another authentication method. For more information see IETF draft
draft-brezak-spnego-http-04.txt.
If you want to enable Negotiate for your proxy authentication, then use If you want to enable Negotiate (SPNEGO) for proxy authentication, then use
\fI--proxy-negotiate\fP. \fI--proxy-negotiate\fP.
This option requires a library built with GSSAPI support. This is This option requires a library built with GSS-API or SSPI support. Use \fI-V,
not very common. Use \fI-V, --version\fP to see if your version supports --version\fP to see if your curl supports GSS-API/SSPI and SPNEGO.
GSS-Negotiate.
When using this option, you must also provide a fake \fI-u, --user\fP option to When using this option, you must also provide a fake \fI-u, --user\fP option to
activate the authentication code properly. Sending a '-u :' is enough as the activate the authentication code properly. Sending a '-u :' is enough as the
@@ -1254,8 +1257,8 @@ the default authentication method curl uses with proxies.
Tells curl to use HTTP Digest authentication when communicating with the given Tells curl to use HTTP Digest authentication when communicating with the given
proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host. proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
.IP "--proxy-negotiate" .IP "--proxy-negotiate"
Tells curl to use HTTP Negotiate authentication when communicating Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating
with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate (SPNEGO)
with a remote host. (Added in 7.17.1) with a remote host. (Added in 7.17.1)
.IP "--proxy-ntlm" .IP "--proxy-ntlm"
Tells curl to use HTTP NTLM authentication when communicating with the given Tells curl to use HTTP NTLM authentication when communicating with the given
@@ -1518,7 +1521,7 @@ sockd/proxy-name --socks5 proxy-name \fI--socks5-gssapi-service\fP
sockd/real-name would use sockd/real-name for cases where the proxy-name does sockd/real-name would use sockd/real-name for cases where the proxy-name does
not match the principal name. (Added in 7.19.4). not match the principal name. (Added in 7.19.4).
.IP "--socks5-gssapi-nec" .IP "--socks5-gssapi-nec"
As part of the gssapi negotiation a protection mode is negotiated. RFC 1961 As part of the GSS-API negotiation a protection mode is negotiated. RFC 1961
says in section 4.3/4.4 it should be protected, but the NEC reference says in section 4.3/4.4 it should be protected, but the NEC reference
implementation does not. The option \fI--socks5-gssapi-nec\fP allows the implementation does not. The option \fI--socks5-gssapi-nec\fP allows the
unprotected exchange of the protection mode negotiation. (Added in 7.19.4). unprotected exchange of the protection mode negotiation. (Added in 7.19.4).
@@ -1633,17 +1636,31 @@ The user name and passwords are split up on the first colon, which makes it
impossible to use a colon in the user name with this option. The password can, impossible to use a colon in the user name with this option. The password can,
still. still.
If you use an SSPI-enabled curl binary and perform NTLM authentication, you When using Kerberos V5 with a Windows based server you should include the
can force curl to select the user name and password from your environment by Windows domain name in the user name, in order for the server to succesfully
specifying a single colon with this option: "-u :". obtain a Kerberos Ticket. If you don't then the initial authentication
handshake may fail.
When using NTLM, the user name can be specified simply as the user name,
without the domain, if there is a single domain and forest in your setup
for example.
To specify the domain name use either Down-Level Logon Name or UPN (User
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
respectively.
If you use a Windows SSPI-enabled curl binary and perform Kerberos V5,
Negotiate or NTLM authentication then you can tell curl to select the user
name and password from your environment by specifying a single colon with this
option: "-u :".
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "-U, --proxy-user <user:password>" .IP "-U, --proxy-user <user:password>"
Specify the user name and password to use for proxy authentication. Specify the user name and password to use for proxy authentication.
If you use an SSPI-enabled curl binary and do NTLM authentication, you can If you use a Windows SSPI-enabled curl binary and do either Negotiate or NTLM
force curl to pick up the user name and password from your environment by authentication then you can tell curl to select the user name and password
simply specifying a single colon with this option: "-U :". from your environment by specifying a single colon with this option: "-U :".
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.
.IP "--url <URL>" .IP "--url <URL>"
@@ -1917,22 +1934,21 @@ HTTPS and FTPS are supported.
Automatic decompression of compressed files over HTTP is supported. Automatic decompression of compressed files over HTTP is supported.
.IP "NTLM" .IP "NTLM"
NTLM authentication is supported. NTLM authentication is supported.
.IP "GSS-Negotiate"
Negotiate authentication and krb5 for FTP is supported.
.IP "Debug" .IP "Debug"
This curl uses a libcurl built with Debug. This enables more error-tracking This curl uses a libcurl built with Debug. This enables more error-tracking
and memory debugging etc. For curl-developers only! and memory debugging etc. For curl-developers only!
.IP "AsynchDNS" .IP "AsynchDNS"
This curl uses asynchronous name resolves. This curl uses asynchronous name resolves.
.IP "SPNEGO" .IP "SPNEGO"
SPNEGO Negotiate authentication is supported. SPNEGO authentication is supported.
.IP "Largefile" .IP "Largefile"
This curl supports transfers of large files, files larger than 2GB. This curl supports transfers of large files, files larger than 2GB.
.IP "IDN" .IP "IDN"
This curl supports IDN - international domain names. This curl supports IDN - international domain names.
.IP "GSS-API"
GSS-API is supported.
.IP "SSPI" .IP "SSPI"
SSPI is supported. If you use NTLM and set a blank user name, curl will SSPI is supported.
authenticate with your current user and password.
.IP "TLS-SRP" .IP "TLS-SRP"
SRP (Secure Remote Password) authentication is supported for TLS. SRP (Secure Remote Password) authentication is supported for TLS.
.IP "Metalink" .IP "Metalink"

View File

@@ -148,9 +148,6 @@ endif
ifeq ($(findstring -sspi,$(CFG)),-sspi) ifeq ($(findstring -sspi,$(CFG)),-sspi)
SSPI = 1 SSPI = 1
endif endif
ifeq ($(findstring -spnego,$(CFG)),-spnego)
SPNEGO = 1
endif
ifeq ($(findstring -ldaps,$(CFG)),-ldaps) ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
LDAPS = 1 LDAPS = 1
endif endif
@@ -230,9 +227,6 @@ ifdef SSPI
CFLAGS += -DUSE_SCHANNEL CFLAGS += -DUSE_SCHANNEL
endif endif
endif endif
ifdef SPNEGO
CFLAGS += -DHAVE_SPNEGO
endif
ifdef IPV6 ifdef IPV6
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501 CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
endif endif

View File

@@ -211,9 +211,6 @@ endif
ifeq ($(findstring -idn,$(CFG)),-idn) ifeq ($(findstring -idn,$(CFG)),-idn)
WITH_IDN = 1 WITH_IDN = 1
endif endif
ifeq ($(findstring -spnego,$(CFG)),-spnego)
WITH_SPNEGO = 1
endif
ifeq ($(findstring -ipv6,$(CFG)),-ipv6) ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
ENABLE_IPV6 = 1 ENABLE_IPV6 = 1
endif endif
@@ -247,10 +244,6 @@ ifdef WITH_SSL
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT) LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess IMPORTS += GetProcessSwitchCount RunningProcess
ifdef WITH_SPNEGO
# INCLUDES += -I$(FBOPENSSL_PATH)/include
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
endif
else else
ifdef WITH_AXTLS ifdef WITH_AXTLS
INCLUDES += -I$(AXTLS_PATH)/inc INCLUDES += -I$(AXTLS_PATH)/inc

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -26,7 +26,7 @@ struct callback_data {
FILE *output; FILE *output;
}; };
static long file_is_comming(struct curl_fileinfo *finfo, static long file_is_coming(struct curl_fileinfo *finfo,
struct callback_data *data, struct callback_data *data,
int remains); int remains);
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L); curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
/* callback is called before download of concrete file started */ /* callback is called before download of concrete file started */
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming); curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
/* callback is called after data from the file have been transferred */ /* callback is called after data from the file have been transferred */
curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded); curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
@@ -89,7 +89,7 @@ int main(int argc, char **argv)
return rc; return rc;
} }
static long file_is_comming(struct curl_fileinfo *finfo, static long file_is_coming(struct curl_fileinfo *finfo,
struct callback_data *data, struct callback_data *data,
int remains) int remains)
{ {

View File

@@ -225,10 +225,10 @@ content is for the specific named data. See also the certinfo.c example. NOTE:
this option is only available in libcurl built with OpenSSL, NSS, GSKit or this option is only available in libcurl built with OpenSSL, NSS, GSKit or
QsoSSL support. (Added in 7.19.1) QsoSSL support. (Added in 7.19.1)
.IP CURLINFO_TLS_SESSION .IP CURLINFO_TLS_SESSION
Pass a pointer to a 'struct curl_tlsinfo *'. The pointer will be initialized Pass a pointer to a 'struct curl_tlssessioninfo *'. The pointer will be
to refer to a 'struct curl_tlsinfo *' that will contain an enum indicating the initialized to refer to a 'struct curl_tlssessioninfo *' that will contain an
SSL library used for the handshake and the respective internal TLS session enum indicating the SSL library used for the handshake and the respective
structure of this underlying SSL library. internal TLS session structure of this underlying SSL library.
This may then be used to extract certificate information in a format This may then be used to extract certificate information in a format
convenient for further processing, such as manual validation. NOTE: this convenient for further processing, such as manual validation. NOTE: this

View File

@@ -86,6 +86,10 @@ you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
.IP CURLFORM_CONTENTSLENGTH .IP CURLFORM_CONTENTSLENGTH
followed by a long giving the length of the contents. Note that for followed by a long giving the length of the contents. Note that for
\fICURLFORM_STREAM\fP contents, this option is mandatory. \fICURLFORM_STREAM\fP contents, this option is mandatory.
If you pass a 0 (zero) for this option, libcurl will instead do a strlen() on
the contents to figure out the size. If you really want to send a zero byte
content then you must make sure strlen() on the data pointer returns zero.
.IP CURLFORM_FILECONTENT .IP CURLFORM_FILECONTENT
followed by a filename, causes that file to be read and its contents used followed by a filename, causes that file to be read and its contents used
as data in this part. This part does \fInot\fP automatically become a file as data in this part. This part does \fInot\fP automatically become a file

View File

@@ -20,7 +20,7 @@
.\" * .\" *
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH curl_version_info 3 "18 Feb 2014" "libcurl 7.33.0" "libcurl Manual" .TH curl_version_info 3 "2 Aug 2014" "libcurl 7.38.0" "libcurl Manual"
.SH NAME .SH NAME
curl_version_info - returns run-time libcurl version info curl_version_info - returns run-time libcurl version info
.SH SYNOPSIS .SH SYNOPSIS
@@ -124,9 +124,14 @@ libcurl was built with support for IDNA, domain names with international
letters. (Added in 7.12.0) letters. (Added in 7.12.0)
.IP CURL_VERSION_SSPI .IP CURL_VERSION_SSPI
libcurl was built with support for SSPI. This is only available on Windows and libcurl was built with support for SSPI. This is only available on Windows and
makes libcurl use Windows-provided functions for NTLM authentication. It also makes libcurl use Windows-provided functions for NTLM, SPNEGO and SASL DIGEST-MD5
allows libcurl to use the current user and the current user's password without authentication. It also allows libcurl to use the current user credentials without
the app having to pass them on. (Added in 7.13.2) the app having to pass them on. (Added in 7.13.2)
.IP CURL_VERSION_GSSAPI
libcurl was built with support for GSS-API. This makes libcurl use provided
functions for Kerberos and SPNEGO authentication. It also allows libcurl
to use the current user credentials without the app having to pass them on.
(Added in 7.38.0)
.IP CURL_VERSION_CONV .IP CURL_VERSION_CONV
libcurl was built with support for character conversions, as provided by the libcurl was built with support for character conversions, as provided by the
CURLOPT_CONV_* callbacks. (Added in 7.15.4) CURLOPT_CONV_* callbacks. (Added in 7.15.4)
@@ -142,8 +147,7 @@ libcurl was built with support for HTTP2.
\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl \fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
has no SSL support, this is NULL. has no SSL support, this is NULL.
\fIssl_version_num\fP is the numerical OpenSSL version value as defined by the \fIssl_version_num\fP is always 0.
OpenSSL project. If libcurl has no SSL support, this is 0.
\fIlibz_version\fP is an ASCII string (there is no numerical version). If \fIlibz_version\fP is an ASCII string (there is no numerical version). If
libcurl has no libz support, this is NULL. libcurl has no libz support, this is NULL.

View File

@@ -1,6 +1,6 @@
An overview of the six time values available from curl_easy_getinfo() An overview of the six time values available from curl_easy_getinfo()
curk_easy_perform() curl_easy_perform()
| |
|--NT |--NT
|--|--CT |--|--CT

View File

@@ -83,6 +83,9 @@ FTP servers return a 227-line as a response to a PASV command. If libcurl
fails to parse that line, this return code is passed back. fails to parse that line, this return code is passed back.
.IP "CURLE_FTP_CANT_GET_HOST (15)" .IP "CURLE_FTP_CANT_GET_HOST (15)"
An internal failure to lookup the host used for the new connection. An internal failure to lookup the host used for the new connection.
.IP "CURLE_HTTP2 (16)"
A problem was detected in the HTTP2 framing layer. This is somewhat generic
and can be one out of several problems, see the error buffer for details.
.IP "CURLE_FTP_COULDNT_SET_TYPE (17)" .IP "CURLE_FTP_COULDNT_SET_TYPE (17)"
Received an error when trying to set the transfer mode to binary or ASCII. Received an error when trying to set the transfer mode to binary or ASCII.
.IP "CURLE_PARTIAL_FILE (18)" .IP "CURLE_PARTIAL_FILE (18)"

View File

@@ -20,7 +20,7 @@
.\" * .\" *
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH libcurl-tutorial 3 "4 Mar 2009" "libcurl" "libcurl programming" .TH libcurl-tutorial 3 "2 Aug 2014" "libcurl" "libcurl programming"
.SH NAME .SH NAME
libcurl-tutorial \- libcurl programming tutorial libcurl-tutorial \- libcurl programming tutorial
.SH "Objective" .SH "Objective"
@@ -442,7 +442,7 @@ authentication method is called 'Basic', which is sending the name and
password in clear-text in the HTTP request, base64-encoded. This is insecure. password in clear-text in the HTTP request, base64-encoded. This is insecure.
At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM, At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM,
Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use Negotiate (SPNEGO). You can tell libcurl which one to use
with \fICURLOPT_HTTPAUTH(3)\fP as in: with \fICURLOPT_HTTPAUTH(3)\fP as in:
curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

View File

@@ -40,7 +40,7 @@ details.
To transfer files, you create an "easy handle" using \fIcurl_easy_init(3)\fP To transfer files, you create an "easy handle" using \fIcurl_easy_init(3)\fP
for a single individual transfer (in either direction). You then set your for a single individual transfer (in either direction). You then set your
desired set of options in that handle with \fIcurk_easy_setopt(3)\fP. Options desired set of options in that handle with \fIcurl_easy_setopt(3)\fP. Options
you set with \fIcurl_easy_setopt(3)\fP stick. They will be used on every you set with \fIcurl_easy_setopt(3)\fP stick. They will be used on every
repeated use of this handle until you either change the option, or you reset repeated use of this handle until you either change the option, or you reset
them all with \fIcurl_easy_reset(3)\fP. them all with \fIcurl_easy_reset(3)\fP.

View File

@@ -1,3 +1,24 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2006, David Shaw <dshaw@jabberwocky.com>
#
# 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.
#
###########################################################################
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], # LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
# [ACTION-IF-YES], [ACTION-IF-NO]) # [ACTION-IF-YES], [ACTION-IF-NO])
# ---------------------------------------------------------- # ----------------------------------------------------------

View File

@@ -52,4 +52,5 @@ If built TLS enabled
Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
CURLE_OUT_OF_MEMORY if there was insufficient heap space. CURLE_OUT_OF_MEMORY if there was insufficient heap space.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR CURLOPT_CAPATH "(3), "
.BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_SSL_VERIFYHOST "(3), " .BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_SSL_VERIFYHOST "(3), "

View File

@@ -32,10 +32,10 @@ Pass a char * to a zero terminated string naming a directory holding multiple
CA certificates to verify the peer with. If libcurl is built against OpenSSL, CA certificates to verify the peer with. If libcurl is built against OpenSSL,
the certificate directory must be prepared using the openssl c_rehash utility. the certificate directory must be prepared using the openssl c_rehash utility.
This makes sense only when used in combination with the This makes sense only when used in combination with the
\fICURLOPT_SSL_VERIFYPEER(3)\fP option. If \fICURLOPT_SSL_VERIFYPEER(3)\fP is \fICURLOPT_SSL_VERIFYPEER(3)\fP option.
zero, \fICURLOPT_CAPATH(3)\fP need not even indicate an accessible path. The
\fICURLOPT_CAPATH(3)\fP function apparently does not work in Windows due to The \fICURLOPT_CAPATH(3)\fP function apparently does not work in Windows due
some limitation in openssl. to some limitation in openssl.
.SH DEFAULT .SH DEFAULT
NULL NULL
.SH PROTOCOLS .SH PROTOCOLS
@@ -50,4 +50,5 @@ compatibility.
Returns CURLE_OK if TLS enabled, and CURLE_UNKNOWN_OPTION if not, or Returns CURLE_OK if TLS enabled, and CURLE_UNKNOWN_OPTION if not, or
CURLE_OUT_OF_MEMORY if there was insufficient heap space. CURLE_OUT_OF_MEMORY if there was insufficient heap space.
.SH "SEE ALSO" .SH "SEE ALSO"
.BR CURLOPT_CAINFO "(3), "
.BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), " .BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), "

View File

@@ -40,7 +40,7 @@ This callback function gets called by libcurl before a part of the stream is
going to be transferred (if the transfer supports chunks). going to be transferred (if the transfer supports chunks).
The \fItransfer_info\fP pointer will point to a struct curl_fileinfo with The \fItransfer_info\fP pointer will point to a struct curl_fileinfo with
details about the file that is about to get transfered. details about the file that is about to get transferred.
This callback makes sense only when using the \fICURLOPT_WILDCARDMATCH(3)\fP This callback makes sense only when using the \fICURLOPT_WILDCARDMATCH(3)\fP
option for now. option for now.

View File

@@ -22,7 +22,7 @@
.\" .\"
.TH CURLOPT_FTPSSLAUTH 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options" .TH CURLOPT_FTPSSLAUTH 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
.SH NAME .SH NAME
CURLOPT_FTPSSLAUTH \- set order to attemp TSL vs SSL when using FTP CURLOPT_FTPSSLAUTH \- set order in which to attempt TLS vs SSL when using FTP
.SH SYNOPSIS .SH SYNOPSIS
#include <curl/curl.h> #include <curl/curl.h>

View File

@@ -41,7 +41,7 @@ sent to a server and not to a proxy. Proxy headers must be set with
\fICURLOPT_PROXYHEADER(3)\fP to get used. Note that if a non-CONNECT request \fICURLOPT_PROXYHEADER(3)\fP to get used. Note that if a non-CONNECT request
is sent to a proxy, libcurl will send both server headers and proxy is sent to a proxy, libcurl will send both server headers and proxy
headers. When doing CONNECT, libcurl will send \fICURLOPT_PROXYHEADER(3)\fP headers. When doing CONNECT, libcurl will send \fICURLOPT_PROXYHEADER(3)\fP
headers only do the proxy and then \fICURLOPT_HTTPHEADER(3)\fP headers only to headers only to the proxy and then \fICURLOPT_HTTPHEADER(3)\fP headers only to
the server. the server.
.SH DEFAULT .SH DEFAULT
CURLHEADER_UNIFIED CURLHEADER_UNIFIED

View File

@@ -20,7 +20,7 @@
.\" * .\" *
.\" ************************************************************************** .\" **************************************************************************
.\" .\"
.TH CURLOPT_HTTPAUTH 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options" .TH CURLOPT_HTTPAUTH 3 "2 Aug 2014" "libcurl 7.38.0" "curl_easy_setopt options"
.SH NAME .SH NAME
CURLOPT_HTTPAUTH \- set HTTP server authentication methods to try CURLOPT_HTTPAUTH \- set HTTP server authentication methods to try
.SH SYNOPSIS .SH SYNOPSIS
@@ -56,14 +56,12 @@ defined in RFC2617 and is a more secure way to do authentication over public
networks than the regular old-fashioned Basic method. The IE flavor is simply networks than the regular old-fashioned Basic method. The IE flavor is simply
that libcurl will use a special "quirk" that IE is known to have used before that libcurl will use a special "quirk" that IE is known to have used before
version 7 and that some servers require the client to use. version 7 and that some servers require the client to use.
.IP CURLAUTH_GSSNEGOTIATE .IP CURLAUTH_NEGOTIATE
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain HTTP Negotiate (SPNEGO) authentication. Negotiate authentication is defined
\&"Negotiate") method was designed by Microsoft and is used in their web in RFC 4559 and is the most secure way to perform authentication over HTTP.
applications. It is primarily meant as a support for Kerberos5 authentication
but may also be used along with other authentication methods. For more
information see IETF draft draft-brezak-spnego-http-04.txt.
You need to build libcurl with a suitable GSS-API library for this to work. You need to build libcurl with a suitable GSS-API library or SSPI on Windows
for this to work.
.IP CURLAUTH_NTLM .IP CURLAUTH_NTLM
HTTP NTLM authentication. A proprietary protocol invented and used by HTTP NTLM authentication. A proprietary protocol invented and used by
Microsoft. It uses a challenge-response and hash concept similar to Digest, to Microsoft. It uses a challenge-response and hash concept similar to Digest, to

View File

@@ -57,7 +57,7 @@ The callback MUST return \fICURLIOE_UNKNOWNCMD\fP if the input \fIcmd\fP is
not \fICURLIOCMD_RESTARTREAD\fP. not \fICURLIOCMD_RESTARTREAD\fP.
The \fIclientp\fP argument to the callback is set with the The \fIclientp\fP argument to the callback is set with the
\fUICURLOPT_IOCTLDATA(3)\fP option. \fICURLOPT_IOCTLDATA(3)\fP option.
This option is deprecated! Do not use it. Use \fICURLOPT_SEEKFUNCTION(3)\fP This option is deprecated! Do not use it. Use \fICURLOPT_SEEKFUNCTION(3)\fP
instead to provide seeking! If \fICURLOPT_SEEKFUNCTION(3)\fP is set, this instead to provide seeking! If \fICURLOPT_SEEKFUNCTION(3)\fP is set, this

View File

@@ -22,15 +22,18 @@
.\" .\"
.TH CURLOPT_NOBODY 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options" .TH CURLOPT_NOBODY 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
.SH NAME .SH NAME
CURLOPT_NOBODY \- do the request without getting the body CURLOPT_NOBODY \- do the download request without getting the body
.SH SYNOPSIS .SH SYNOPSIS
#include <curl/curl.h> #include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOBODY, long opt); CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOBODY, long opt);
.SH DESCRIPTION .SH DESCRIPTION
A long parameter set to 1 tells libcurl to not include the body-part in the A long parameter set to 1 tells libcurl to not include the body-part in the
output. For HTTP(S), this makes libcurl do a HEAD request. For most other output when doing what would otherwise be a download. For HTTP(S), this makes
protocols ie means just not asking for transferring the body data. libcurl do a HEAD request. For most other protocols it means just not asking
to transfer the body data.
Enabling this option means asking for a download but without a body.
.SH DEFAULT .SH DEFAULT
0, the body is transferred 0, the body is transferred
.SH PROTOCOLS .SH PROTOCOLS

View File

@@ -32,7 +32,7 @@ A parameter set to 1 tells the library to use HTTP PUT to transfer data. The
data should be set with \fICURLOPT_READDATA(3)\fP and data should be set with \fICURLOPT_READDATA(3)\fP and
\fICURLOPT_INFILESIZE(3)\fP. \fICURLOPT_INFILESIZE(3)\fP.
This option is \dBdeprecated\fP since version 7.12.1. Use This option is \fBdeprecated\fP since version 7.12.1. Use
\fICURLOPT_UPLOAD(3)\fP! \fICURLOPT_UPLOAD(3)\fP!
.SH DEFAULT .SH DEFAULT
0, disabled 0, disabled

View File

@@ -41,7 +41,7 @@ All
.SH EXAMPLE .SH EXAMPLE
TODO TODO
.SH AVAILABILITY .SH AVAILABILITY
Added in 7.19.4, before then it would follow all protcols. Added in 7.19.4, before then it would follow all protocols.
.SH RETURN VALUE .SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not. Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO" .SH "SEE ALSO"

View File

@@ -22,7 +22,7 @@
.\" .\"
.TH CURLOPT_SSH_KEYDATA 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options" .TH CURLOPT_SSH_KEYDATA 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
.SH NAME .SH NAME
CURLOPT_SSH_KEYDATA \- pointer to apss to the SSH key callback CURLOPT_SSH_KEYDATA \- pointer to pass to the SSH key callback
.SH SYNOPSIS .SH SYNOPSIS
#include <curl/curl.h> #include <curl/curl.h>

View File

@@ -51,6 +51,12 @@ typically also want to ensure that the server is the server you mean to be
talking to. Use \fICURLOPT_SSL_VERIFYHOST(3)\fP for that. The check that the talking to. Use \fICURLOPT_SSL_VERIFYHOST(3)\fP for that. The check that the
host name in the certificate is valid for the host name you're connecting to host name in the certificate is valid for the host name you're connecting to
is done independently of the \fICURLOPT_SSL_VERIFYPEER(3)\fP option. is done independently of the \fICURLOPT_SSL_VERIFYPEER(3)\fP option.
WARNING: disabling verification of the certificate allows bad guys to
man-in-the-middle the communication without you knowing it. Disabling
verification makes the communication insecure. Just having encryption on a
transfer is not enough as you cannot be sure that you are communicating with
the correct end-point.
.SH DEFAULT .SH DEFAULT
By default, curl assumes a value of 1. By default, curl assumes a value of 1.
.SH PROTOCOLS .SH PROTOCOLS

View File

@@ -22,7 +22,7 @@
.\" .\"
.TH CURLOPT_URL 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options" .TH CURLOPT_URL 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
.SH NAME .SH NAME
CURLOPT_URL \- provide the URL to use in the reqest CURLOPT_URL \- provide the URL to use in the request
.SH SYNOPSIS .SH SYNOPSIS
#include <curl/curl.h> #include <curl/curl.h>

View File

@@ -37,6 +37,22 @@ user name to use for the transfer.
authentication. You should not use this option together with the (older) authentication. You should not use this option together with the (older)
\fICURLOPT_USERPWD(3)\fP option. \fICURLOPT_USERPWD(3)\fP option.
When using Kerberos V5 authentication with a Windows based server, you should
include the domain name in order for the server to successfully obtain a
Kerberos Ticket. If you don't then the initial part of the authentication
handshake may fail.
When using NTLM, the user name can be specified simply as the user name
without the domain name should the server be part of a single domain and
forest.
To include the domain name use either Down-Level Logon Name or UPN (User
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
respectively.
Some HTTP servers (on Windows) support inclusion of the domain for Basic
authentication as well.
To specify the password and login options, along with the user name, use the To specify the password and login options, along with the user name, use the
\fICURLOPT_PASSWORD(3)\fP and \fICURLOPT_LOGIN_OPTIONS(3)\fP options. \fICURLOPT_PASSWORD(3)\fP and \fICURLOPT_LOGIN_OPTIONS(3)\fP options.
.SH DEFAULT .SH DEFAULT

View File

@@ -31,10 +31,21 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_USERPWD, char *userpwd);
Pass a char * as parameter, pointing to a zero terminated login details string Pass a char * as parameter, pointing to a zero terminated login details string
for the connection. The format of which is: [user name]:[password]. for the connection. The format of which is: [user name]:[password].
When using NTLM, you can set the domain by prepending it to the user name and When using Kerberos V5 authentication with a Windows based server, you should
separating the domain and name with a forward (/) or backward slash (\\). Like specify the user name part with the domain name in order for the server to
this: "domain/user:password" or "domain\\user:password". Some HTTP servers (on successfully obtain a Kerberos Ticket. If you don't then the initial part of
Windows) support this style even for Basic authentication. the authentication handshake may fail.
When using NTLM, the user name can be specified simply as the user name
without the domain name should the server be part of a single domain and
forest.
To specify the domain name use either Down-Level Logon Name or UPN (User
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
respectively.
Some HTTP servers (on Windows) support inclusion of the domain for Basic
authentication as well.
When using HTTP and \fICURLOPT_FOLLOWLOCATION(3)\fP, libcurl might perform When using HTTP and \fICURLOPT_FOLLOWLOCATION(3)\fP, libcurl might perform
several requests to possibly different hosts. libcurl will only send this user several requests to possibly different hosts. libcurl will only send this user

View File

@@ -17,7 +17,8 @@ CURLAUTH_ANYSAFE 7.10.6
CURLAUTH_BASIC 7.10.6 CURLAUTH_BASIC 7.10.6
CURLAUTH_DIGEST 7.10.6 CURLAUTH_DIGEST 7.10.6
CURLAUTH_DIGEST_IE 7.19.3 CURLAUTH_DIGEST_IE 7.19.3
CURLAUTH_GSSNEGOTIATE 7.10.6 CURLAUTH_GSSNEGOTIATE 7.10.6 7.38.0
CURLAUTH_NEGOTIATE 7.38.0
CURLAUTH_NONE 7.10.6 CURLAUTH_NONE 7.10.6
CURLAUTH_NTLM 7.10.6 CURLAUTH_NTLM 7.10.6
CURLAUTH_NTLM_WB 7.22.0 CURLAUTH_NTLM_WB 7.22.0
@@ -78,6 +79,7 @@ CURLE_HTTP_PORT_FAILED 7.3 7.12.0
CURLE_HTTP_POST_ERROR 7.1 CURLE_HTTP_POST_ERROR 7.1
CURLE_HTTP_RANGE_ERROR 7.1 7.17.0 CURLE_HTTP_RANGE_ERROR 7.1 7.17.0
CURLE_HTTP_RETURNED_ERROR 7.10.3 CURLE_HTTP_RETURNED_ERROR 7.10.3
CURLE_HTTP2 7.38.0
CURLE_INTERFACE_FAILED 7.12.0 CURLE_INTERFACE_FAILED 7.12.0
CURLE_LDAP_CANNOT_BIND 7.1 CURLE_LDAP_CANNOT_BIND 7.1
CURLE_LDAP_INVALID_URL 7.10.8 CURLE_LDAP_INVALID_URL 7.10.8
@@ -602,6 +604,7 @@ CURLSSH_AUTH_KEYBOARD 7.16.1
CURLSSH_AUTH_NONE 7.16.1 CURLSSH_AUTH_NONE 7.16.1
CURLSSH_AUTH_PASSWORD 7.16.1 CURLSSH_AUTH_PASSWORD 7.16.1
CURLSSH_AUTH_PUBLICKEY 7.16.1 CURLSSH_AUTH_PUBLICKEY 7.16.1
CURLSSLBACKEND_AXTLS 7.38.0
CURLSSLBACKEND_CYASSL 7.34.0 CURLSSLBACKEND_CYASSL 7.34.0
CURLSSLBACKEND_DARWINSSL 7.34.0 CURLSSLBACKEND_DARWINSSL 7.34.0
CURLSSLBACKEND_GNUTLS 7.34.0 CURLSSLBACKEND_GNUTLS 7.34.0
@@ -727,7 +730,8 @@ CURL_VERSION_ASYNCHDNS 7.10.7
CURL_VERSION_CONV 7.15.4 CURL_VERSION_CONV 7.15.4
CURL_VERSION_CURLDEBUG 7.19.6 CURL_VERSION_CURLDEBUG 7.19.6
CURL_VERSION_DEBUG 7.10.6 CURL_VERSION_DEBUG 7.10.6
CURL_VERSION_GSSNEGOTIATE 7.10.6 CURL_VERSION_GSSAPI 7.38.0
CURL_VERSION_GSSNEGOTIATE 7.10.6 7.38.0
CURL_VERSION_HTTP2 7.33.0 CURL_VERSION_HTTP2 7.33.0
CURL_VERSION_IDN 7.12.0 CURL_VERSION_IDN 7.12.0
CURL_VERSION_IPV6 7.10 CURL_VERSION_IPV6 7.10

View File

@@ -423,7 +423,9 @@ typedef enum {
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
CURLE_FTP_CANT_GET_HOST, /* 15 */ CURLE_FTP_CANT_GET_HOST, /* 15 */
CURLE_OBSOLETE16, /* 16 - NOT USED */ CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
[was obsoleted in August 2007 for 7.17.0,
reused in July 2014 for 7.38.0] */
CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
CURLE_PARTIAL_FILE, /* 18 */ CURLE_PARTIAL_FILE, /* 18 */
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
@@ -525,7 +527,10 @@ typedef enum {
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */ the obsolete stuff removed! */
/* Previously obsoletes error codes re-used in 7.24.0 */ /* Previously obsolete error code re-used in 7.38.0 */
#define CURLE_OBSOLETE16 CURLE_HTTP2
/* Previously obsolete error codes re-used in 7.24.0 */
#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED #define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT #define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
@@ -619,7 +624,8 @@ typedef enum {
* CURLAUTH_NONE - No HTTP authentication * CURLAUTH_NONE - No HTTP authentication
* CURLAUTH_BASIC - HTTP Basic authentication (default) * CURLAUTH_BASIC - HTTP Basic authentication (default)
* CURLAUTH_DIGEST - HTTP Digest authentication * CURLAUTH_DIGEST - HTTP Digest authentication
* CURLAUTH_GSSNEGOTIATE - HTTP GSS-Negotiate authentication * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
* CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
* CURLAUTH_NTLM - HTTP NTLM authentication * CURLAUTH_NTLM - HTTP NTLM authentication
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
@@ -632,7 +638,9 @@ typedef enum {
#define CURLAUTH_NONE ((unsigned long)0) #define CURLAUTH_NONE ((unsigned long)0)
#define CURLAUTH_BASIC (((unsigned long)1)<<0) #define CURLAUTH_BASIC (((unsigned long)1)<<0)
#define CURLAUTH_DIGEST (((unsigned long)1)<<1) #define CURLAUTH_DIGEST (((unsigned long)1)<<1)
#define CURLAUTH_GSSNEGOTIATE (((unsigned long)1)<<2) #define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
#define CURLAUTH_NTLM (((unsigned long)1)<<3) #define CURLAUTH_NTLM (((unsigned long)1)<<3)
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) #define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) #define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
@@ -2025,7 +2033,8 @@ typedef enum {
CURLSSLBACKEND_POLARSSL = 6, CURLSSLBACKEND_POLARSSL = 6,
CURLSSLBACKEND_CYASSL = 7, CURLSSLBACKEND_CYASSL = 7,
CURLSSLBACKEND_SCHANNEL = 8, CURLSSLBACKEND_SCHANNEL = 8,
CURLSSLBACKEND_DARWINSSL = 9 CURLSSLBACKEND_DARWINSSL = 9,
CURLSSLBACKEND_AXTLS = 10
} curl_sslbackend; } curl_sslbackend;
/* Information about the SSL library used and the respective internal SSL /* Information about the SSL library used and the respective internal SSL
@@ -2231,10 +2240,11 @@ typedef struct {
#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ #define CURL_VERSION_SSL (1<<2) /* SSL options are present */
#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ #define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ #define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ #define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support
(deprecated) */
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ #define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ #define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ #define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ #define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ #define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ #define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
@@ -2243,6 +2253,7 @@ typedef struct {
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ #define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */ #define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ #define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
#define CURL_VERSION_GSSAPI (1<<17) /* GSS-API is supported */
/* /*
* NAME curl_version_info() * NAME curl_version_info()

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# install - install a program, script, or datafile # install - install a program, script, or datafile
scriptversion=2011-01-19.21; # UTC scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC
# FSF changes to this file are in the public domain. # FSF changes to this file are in the public domain.
# #
# Calling this script install-sh is preferred over install.sh, to prevent # Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it # 'make' implicit rules from creating a file called install from it
# when there is no Makefile. # when there is no Makefile.
# #
# This script is compatible with the BSD install script, but was written # This script is compatible with the BSD install script, but was written
@@ -156,7 +156,7 @@ while test $# -ne 0; do
-s) stripcmd=$stripprog;; -s) stripcmd=$stripprog;;
-t) dst_arg=$2 -t) dst_arg=$2
# Protect names problematic for `test' and other utilities. # Protect names problematic for 'test' and other utilities.
case $dst_arg in case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;; -* | [=\(\)!]) dst_arg=./$dst_arg;;
esac esac
@@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
fi fi
shift # arg shift # arg
dst_arg=$arg dst_arg=$arg
# Protect names problematic for `test' and other utilities. # Protect names problematic for 'test' and other utilities.
case $dst_arg in case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;; -* | [=\(\)!]) dst_arg=./$dst_arg;;
esac esac
@@ -202,7 +202,7 @@ if test $# -eq 0; then
echo "$0: no input file specified." >&2 echo "$0: no input file specified." >&2
exit 1 exit 1
fi fi
# It's OK to call `install-sh -d' without argument. # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories. # This can happen when creating conditional directories.
exit 0 exit 0
fi fi
@@ -240,7 +240,7 @@ fi
for src for src
do do
# Protect names problematic for `test' and other utilities. # Protect names problematic for 'test' and other utilities.
case $src in case $src in
-* | [=\(\)!]) src=./$src;; -* | [=\(\)!]) src=./$src;;
esac esac
@@ -354,7 +354,7 @@ do
if test -z "$dir_arg" || { if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m. # Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't. # other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"` ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in case $ls_ld_tmpdir in

View File

@@ -60,7 +60,7 @@ SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h"
CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm & CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm &
-wcd=201 -bt=nt -d+ -dWIN32 -dCURL_WANTS_CA_BUNDLE_ENV & -wcd=201 -bt=nt -d+ -dWIN32 -dCURL_WANTS_CA_BUNDLE_ENV &
-dBUILDING_LIBCURL -dHAVE_SPNEGO=1 -I. -I"../include" $(SYS_INCL) -dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL)
!ifdef %debug !ifdef %debug
DEBUG = -dDEBUG=1 -dDEBUGBUILD DEBUG = -dDEBUG=1 -dDEBUGBUILD

View File

@@ -137,9 +137,6 @@ endif
ifeq ($(findstring -sspi,$(CFG)),-sspi) ifeq ($(findstring -sspi,$(CFG)),-sspi)
SSPI = 1 SSPI = 1
endif endif
ifeq ($(findstring -spnego,$(CFG)),-spnego)
SPNEGO = 1
endif
ifeq ($(findstring -ldaps,$(CFG)),-ldaps) ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
LDAPS = 1 LDAPS = 1
endif endif

View File

@@ -217,9 +217,6 @@ endif
ifeq ($(findstring -idn,$(CFG)),-idn) ifeq ($(findstring -idn,$(CFG)),-idn)
WITH_IDN = 1 WITH_IDN = 1
endif endif
ifeq ($(findstring -spnego,$(CFG)),-spnego)
WITH_SPNEGO = 1
endif
ifeq ($(findstring -ipv6,$(CFG)),-ipv6) ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
ENABLE_IPV6 = 1 ENABLE_IPV6 = 1
endif endif
@@ -247,10 +244,6 @@ ifdef WITH_SSL
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT) LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess IMPORTS += GetProcessSwitchCount RunningProcess
INSTDEP += ca-bundle.crt INSTDEP += ca-bundle.crt
ifdef WITH_SPNEGO
INCLUDES += -I$(FBOPENSSL_PATH)/include
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
endif
else else
ifdef WITH_AXTLS ifdef WITH_AXTLS
INCLUDES += -I$(AXTLS_PATH)/inc INCLUDES += -I$(AXTLS_PATH)/inc

View File

@@ -235,7 +235,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000); milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
if(milli == 0) if(milli == 0)
milli += 10; milli += 10;
Curl_expire(conn->data, milli); Curl_expire_latest(conn->data, milli);
return max; return max;
} }
@@ -669,7 +669,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data, CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
const char *local_ip6) const char *local_ip6)
{ {
#if (ARES_VERSION >= 0x010704) #if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
unsigned char a6[INET6_ADDRSTRLEN]; unsigned char a6[INET6_ADDRSTRLEN];
if((!local_ip6) || (local_ip6[0] == 0)) { if((!local_ip6) || (local_ip6[0] == 0)) {

View File

@@ -166,6 +166,7 @@ struct thread_sync_data {
#ifdef HAVE_GETADDRINFO #ifdef HAVE_GETADDRINFO
struct addrinfo hints; struct addrinfo hints;
#endif #endif
struct thread_data *td; /* for thread-self cleanup */
}; };
struct thread_data { struct thread_data {
@@ -202,13 +203,16 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
/* Initialize resolver thread synchronization data */ /* Initialize resolver thread synchronization data */
static static
int init_thread_sync_data(struct thread_sync_data * tsd, int init_thread_sync_data(struct thread_data * td,
const char * hostname, const char * hostname,
int port, int port,
const struct addrinfo *hints) const struct addrinfo *hints)
{ {
struct thread_sync_data *tsd = &td->tsd;
memset(tsd, 0, sizeof(*tsd)); memset(tsd, 0, sizeof(*tsd));
tsd->td = td;
tsd->port = port; tsd->port = port;
#ifdef HAVE_GETADDRINFO #ifdef HAVE_GETADDRINFO
DEBUGASSERT(hints); DEBUGASSERT(hints);
@@ -266,6 +270,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg) static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
{ {
struct thread_sync_data *tsd = (struct thread_sync_data*)arg; struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
struct thread_data *td = tsd->td;
char service[12]; char service[12];
int rc; int rc;
@@ -280,8 +285,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
} }
Curl_mutex_acquire(tsd->mtx); Curl_mutex_acquire(tsd->mtx);
if(tsd->done) {
/* too late, gotta clean up the mess */
Curl_mutex_release(tsd->mtx);
destroy_thread_sync_data(tsd);
free(td);
}
else {
tsd->done = 1; tsd->done = 1;
Curl_mutex_release(tsd->mtx); Curl_mutex_release(tsd->mtx);
}
return 0; return 0;
} }
@@ -294,6 +307,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
static unsigned int CURL_STDCALL gethostbyname_thread (void *arg) static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
{ {
struct thread_sync_data *tsd = (struct thread_sync_data *)arg; struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port); tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
@@ -304,8 +318,16 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
} }
Curl_mutex_acquire(tsd->mtx); Curl_mutex_acquire(tsd->mtx);
if(tsd->done) {
/* too late, gotta clean up the mess */
Curl_mutex_release(tsd->mtx);
destroy_thread_sync_data(tsd);
free(td);
}
else {
tsd->done = 1; tsd->done = 1;
Curl_mutex_release(tsd->mtx); Curl_mutex_release(tsd->mtx);
}
return 0; return 0;
} }
@@ -317,12 +339,23 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
*/ */
static void destroy_async_data (struct Curl_async *async) static void destroy_async_data (struct Curl_async *async)
{ {
if(async->hostname)
free(async->hostname);
if(async->os_specific) { if(async->os_specific) {
struct thread_data *td = (struct thread_data*) async->os_specific; struct thread_data *td = (struct thread_data*) async->os_specific;
int done;
/*
* if the thread is still blocking in the resolve syscall, detach it and
* let the thread do the cleanup...
*/
Curl_mutex_acquire(td->tsd.mtx);
done = td->tsd.done;
td->tsd.done = 1;
Curl_mutex_release(td->tsd.mtx);
if(!done) {
Curl_thread_destroy(td->thread_hnd);
}
else {
if(td->thread_hnd != curl_thread_t_null) if(td->thread_hnd != curl_thread_t_null)
Curl_thread_join(&td->thread_hnd); Curl_thread_join(&td->thread_hnd);
@@ -330,8 +363,13 @@ static void destroy_async_data (struct Curl_async *async)
free(async->os_specific); free(async->os_specific);
} }
async->hostname = NULL; }
async->os_specific = NULL; async->os_specific = NULL;
if(async->hostname)
free(async->hostname);
async->hostname = NULL;
} }
/* /*
@@ -357,7 +395,7 @@ static bool init_resolve_thread (struct connectdata *conn,
conn->async.dns = NULL; conn->async.dns = NULL;
td->thread_hnd = curl_thread_t_null; td->thread_hnd = curl_thread_t_null;
if(!init_thread_sync_data(&td->tsd, hostname, port, hints)) if(!init_thread_sync_data(td, hostname, port, hints))
goto err_exit; goto err_exit;
Curl_safefree(conn->async.hostname); Curl_safefree(conn->async.hostname);
@@ -503,7 +541,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
td->poll_interval = 250; td->poll_interval = 250;
td->interval_end = elapsed + td->poll_interval; td->interval_end = elapsed + td->poll_interval;
Curl_expire(conn->data, td->poll_interval); Curl_expire_latest(conn->data, td->poll_interval);
} }
return CURLE_OK; return CURLE_OK;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -37,9 +37,14 @@
#include "memdebug.h" #include "memdebug.h"
/* ---- Base64 Encoding/Decoding Table --- */ /* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]= static const char base64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
section 5 */
static const char base64url[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static size_t decodeQuantum(unsigned char *dest, const char *src) static size_t decodeQuantum(unsigned char *dest, const char *src)
{ {
size_t padding = 0; size_t padding = 0;
@@ -54,7 +59,7 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
padding++; padding++;
} }
else { else {
p = table64; p = base64;
while(*p && (*p != *s)) { while(*p && (*p != *s)) {
v++; v++;
@@ -167,24 +172,8 @@ CURLcode Curl_base64_decode(const char *src,
return CURLE_OK; return CURLE_OK;
} }
/* static CURLcode base64_encode(const char *table64,
* Curl_base64_encode() struct SessionHandle *data,
*
* Given a pointer to an input buffer and an input size, encode it and
* return a pointer in *outptr to a newly allocated memory area holding
* encoded data. Size of encoded data is returned in variable pointed by
* outlen.
*
* Input length of 0 indicates input buffer holds a NUL-terminated string.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When encoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize, const char *inputbuff, size_t insize,
char **outptr, size_t *outlen) char **outptr, size_t *outlen)
{ {
@@ -274,4 +263,52 @@ CURLcode Curl_base64_encode(struct SessionHandle *data,
return CURLE_OK; return CURLE_OK;
} }
/*
* Curl_base64_encode()
*
* Given a pointer to an input buffer and an input size, encode it and
* return a pointer in *outptr to a newly allocated memory area holding
* encoded data. Size of encoded data is returned in variable pointed by
* outlen.
*
* Input length of 0 indicates input buffer holds a NUL-terminated string.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When encoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
}
/*
* Curl_base64url_encode()
*
* Given a pointer to an input buffer and an input size, encode it and
* return a pointer in *outptr to a newly allocated memory area holding
* encoded data. Size of encoded data is returned in variable pointed by
* outlen.
*
* Input length of 0 indicates input buffer holds a NUL-terminated string.
*
* Returns CURLE_OK on success, otherwise specific error code. Function
* output shall not be considered valid unless CURLE_OK is returned.
*
* When encoded data length is 0, returns NULL in *outptr.
*
* @unittest: 1302
*/
CURLcode Curl_base64url_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen)
{
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
}
/* ---- End of Base64 Encoding ---- */ /* ---- End of Base64 Encoding ---- */

View File

@@ -69,7 +69,6 @@
#define HAVE_SETMODE 1 #define HAVE_SETMODE 1
#define HAVE_SIGNAL 1 #define HAVE_SIGNAL 1
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
#define HAVE_SPNEGO 1
#define HAVE_STRDUP 1 #define HAVE_STRDUP 1
#define HAVE_STRICMP 1 #define HAVE_STRICMP 1
#define HAVE_STRTOLL 1 #define HAVE_STRTOLL 1

View File

@@ -175,6 +175,15 @@
/* Define if you have GSS API. */ /* Define if you have GSS API. */
#define HAVE_GSSAPI #define HAVE_GSSAPI
/* Define if you have the GNU gssapi libraries */
#undef HAVE_GSSGNU
/* Define if you have the Heimdal gssapi libraries */
#define HAVE_GSSHEIMDAL
/* Define if you have the MIT gssapi libraries */
#undef HAVE_GSSMIT
/* Define if you have the `ucb' library (-lucb). */ /* Define if you have the `ucb' library (-lucb). */
#undef HAVE_LIBUCB #undef HAVE_LIBUCB

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -260,7 +260,8 @@
/* Define to 1 if you have the IoctlSocket camel case function. */ /* Define to 1 if you have the IoctlSocket camel case function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL */ /* #undef HAVE_IOCTLSOCKET_CAMEL */
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO
function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
/* Define to 1 if you have the <io.h> header file. */ /* Define to 1 if you have the <io.h> header file. */
@@ -480,9 +481,6 @@
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
/* Define this if you have the SPNEGO library fbopenssl */
/* #undef HAVE_SPNEGO */
/* Define to 1 if you have the `SSL_get_shutdown' function. */ /* Define to 1 if you have the `SSL_get_shutdown' function. */
/*#define HAVE_SSL_GET_SHUTDOWN 1*/ /*#define HAVE_SSL_GET_SHUTDOWN 1*/
@@ -659,7 +657,8 @@
/*#define PACKAGE "curl"*/ /*#define PACKAGE "curl"*/
/* Define to the address where bug reports for this package should be sent. */ /* Define to the address where bug reports for this package should be sent. */
/*#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"*/ /*#define PACKAGE_BUGREPORT \
"a suitable curl mailing list => http://curl.haxx.se/mail/"*/
/* Define to the full name of this package. */ /* Define to the full name of this package. */
/*#define PACKAGE_NAME "curl"*/ /*#define PACKAGE_NAME "curl"*/

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -246,7 +246,8 @@
/* Define to 1 if you have the IoctlSocket camel case function. */ /* Define to 1 if you have the IoctlSocket camel case function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL */ /* #undef HAVE_IOCTLSOCKET_CAMEL */
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO
function. */
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
/* Define to 1 if you have the <io.h> header file. */ /* Define to 1 if you have the <io.h> header file. */
@@ -436,9 +437,6 @@
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
/* Define this if you have the SPNEGO library fbopenssl */
/* #undef HAVE_SPNEGO */
/* Define to 1 if you have the <ssl.h> header file. */ /* Define to 1 if you have the <ssl.h> header file. */
/* #undef HAVE_SSL_H */ /* #undef HAVE_SSL_H */
#define HAVE_SSL_H 1 #define HAVE_SSL_H 1
@@ -581,7 +579,8 @@
#define PACKAGE "curl" #define PACKAGE "curl"
/* Define to the address where bug reports for this package should be sent. */ /* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/" #define PACKAGE_BUGREPORT \
"a suitable curl mailing list => http://curl.haxx.se/mail/"
/* Define to the full name of this package. */ /* Define to the full name of this package. */
#define PACKAGE_NAME "curl" #define PACKAGE_NAME "curl"

View File

@@ -547,9 +547,6 @@
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1 #define HAVE_SOCKET 1
/* Define this if you have the SPNEGO library fbopenssl */
/* #undef HAVE_SPNEGO */
/* Define to 1 if you have the `SSL_get_shutdown' function. */ /* Define to 1 if you have the `SSL_get_shutdown' function. */
#define HAVE_SSL_GET_SHUTDOWN 1 #define HAVE_SSL_GET_SHUTDOWN 1

View File

@@ -202,6 +202,7 @@ void Curl_conncache_foreach(struct conncache *connc,
struct connectdata *conn; struct connectdata *conn;
bundle = he->ptr; bundle = he->ptr;
he = Curl_hash_next_element(&iter);
curr = bundle->conn_list->head; curr = bundle->conn_list->head;
while(curr) { while(curr) {
@@ -213,8 +214,6 @@ void Curl_conncache_foreach(struct conncache *connc,
if(1 == func(conn, param)) if(1 == func(conn, param))
return; return;
} }
he = Curl_hash_next_element(&iter);
} }
} }

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012, 2013, Linus Nielsen Feltzing, <linus@haxx.se> * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -25,7 +25,8 @@
struct conncache { struct conncache {
struct curl_hash *hash; struct curl_hash *hash;
size_t num_connections; size_t num_connections;
size_t next_connection_id; long next_connection_id;
struct timeval last_cleanup;
}; };
struct conncache *Curl_conncache_init(int size); struct conncache *Curl_conncache_init(int size);

View File

@@ -94,7 +94,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error);
#define KEEPALIVE_FACTOR(x) #define KEEPALIVE_FACTOR(x)
#endif #endif
#if defined(HAVE_WINSOCK_H) && !defined(SIO_KEEPALIVE_VALS) #if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
struct tcp_keepalive { struct tcp_keepalive {
@@ -1054,7 +1054,7 @@ singleipconnect(struct connectdata *conn,
conn->connecttime = Curl_tvnow(); conn->connecttime = Curl_tvnow();
if(conn->num_addr > 1) if(conn->num_addr > 1)
Curl_expire(data, conn->timeoutms_per_addr); Curl_expire_latest(data, conn->timeoutms_per_addr);
/* Connect TCP sockets, bind UDP */ /* Connect TCP sockets, bind UDP */
if(!isconnected && (conn->socktype == SOCK_STREAM)) { if(!isconnected && (conn->socktype == SOCK_STREAM)) {

View File

@@ -95,6 +95,7 @@ Example set of cookies:
#include "strtoofft.h" #include "strtoofft.h"
#include "rawstr.h" #include "rawstr.h"
#include "curl_memrchr.h" #include "curl_memrchr.h"
#include "inet_pton.h"
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
@@ -319,6 +320,28 @@ static void remove_expired(struct CookieInfo *cookies)
} }
} }
/*
* Return true if the given string is an IP(v4|v6) address.
*/
static bool isip(const char *domain)
{
struct in_addr addr;
#ifdef ENABLE_IPV6
struct in6_addr addr6;
#endif
if(Curl_inet_pton(AF_INET, domain, &addr)
#ifdef ENABLE_IPV6
|| Curl_inet_pton(AF_INET6, domain, &addr6)
#endif
) {
/* domain name given as IP address */
return TRUE;
}
return FALSE;
}
/**************************************************************************** /****************************************************************************
* *
* Curl_cookie_add() * Curl_cookie_add()
@@ -439,22 +462,31 @@ Curl_cookie_add(struct SessionHandle *data,
} }
} }
else if(Curl_raw_equal("domain", name)) { else if(Curl_raw_equal("domain", name)) {
bool is_ip;
const char *dotp;
/* Now, we make sure that our host is within the given domain, /* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */ or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0]) if('.' == whatptr[0])
whatptr++; /* ignore preceding dot */ whatptr++; /* ignore preceding dot */
if(!domain || tailmatch(whatptr, domain)) { is_ip = isip(domain ? domain : whatptr);
const char *tailptr=whatptr;
if(tailptr[0] == '.') /* check for more dots */
tailptr++; dotp = strchr(whatptr, '.');
strstore(&co->domain, tailptr); /* don't prefix w/dots if(!dotp)
internally */ domain=":";
if(!domain
|| (is_ip && !strcmp(whatptr, domain))
|| (!is_ip && tailmatch(whatptr, domain))) {
strstore(&co->domain, whatptr);
if(!co->domain) { if(!co->domain) {
badcookie = TRUE; badcookie = TRUE;
break; break;
} }
if(!is_ip)
co->tailmatch=TRUE; /* we always do that if the domain name was co->tailmatch=TRUE; /* we always do that if the domain name was
given */ given */
} }
@@ -968,6 +1000,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
time_t now = time(NULL); time_t now = time(NULL);
struct Cookie *mainco=NULL; struct Cookie *mainco=NULL;
size_t matches = 0; size_t matches = 0;
bool is_ip;
if(!c || !c->cookies) if(!c || !c->cookies)
return NULL; /* no cookie struct or no cookies in the struct */ return NULL; /* no cookie struct or no cookies in the struct */
@@ -975,6 +1008,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/* at first, remove expired cookies */ /* at first, remove expired cookies */
remove_expired(c); remove_expired(c);
/* check if host is an IP(v4|v6) address */
is_ip = isip(host);
co = c->cookies; co = c->cookies;
while(co) { while(co) {
@@ -986,8 +1022,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/* now check if the domain is correct */ /* now check if the domain is correct */
if(!co->domain || if(!co->domain ||
(co->tailmatch && tailmatch(co->domain, host)) || (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
(!co->tailmatch && Curl_raw_equal(host, co->domain)) ) { ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
/* the right part of the host matches the domain stuff in the /* the right part of the host matches the domain stuff in the
cookie data */ cookie data */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -25,6 +25,9 @@
CURLcode Curl_base64_encode(struct SessionHandle *data, CURLcode Curl_base64_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize, const char *inputbuff, size_t insize,
char **outptr, size_t *outlen); char **outptr, size_t *outlen);
CURLcode Curl_base64url_encode(struct SessionHandle *data,
const char *inputbuff, size_t insize,
char **outptr, size_t *outlen);
CURLcode Curl_base64_decode(const char *src, CURLcode Curl_base64_decode(const char *src,
unsigned char **outptr, size_t *outlen); unsigned char **outptr, size_t *outlen);

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -27,15 +27,21 @@
#include "curl_gssapi.h" #include "curl_gssapi.h"
#include "sendf.h" #include "sendf.h"
static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
OM_uint32 Curl_gss_init_sec_context( OM_uint32 Curl_gss_init_sec_context(
struct SessionHandle *data, struct SessionHandle *data,
OM_uint32 * minor_status, OM_uint32 *minor_status,
gss_ctx_id_t * context, gss_ctx_id_t *context,
gss_name_t target_name, gss_name_t target_name,
gss_OID mech_type,
gss_channel_bindings_t input_chan_bindings, gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token, gss_buffer_t input_token,
gss_buffer_t output_token, gss_buffer_t output_token,
OM_uint32 * ret_flags) OM_uint32 *ret_flags)
{ {
OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
@@ -55,7 +61,7 @@ OM_uint32 Curl_gss_init_sec_context(
GSS_C_NO_CREDENTIAL, /* cred_handle */ GSS_C_NO_CREDENTIAL, /* cred_handle */
context, context,
target_name, target_name,
GSS_C_NO_OID, /* mech_type */ mech_type,
req_flags, req_flags,
0, /* time_req */ 0, /* time_req */
input_chan_bindings, input_chan_bindings,

View File

@@ -39,18 +39,21 @@
# include <gssapi.h> # include <gssapi.h>
#endif #endif
extern gss_OID_desc Curl_spnego_mech_oid;
extern gss_OID_desc Curl_krb5_mech_oid;
/* Common method for using gss api */ /* Common method for using GSS-API */
OM_uint32 Curl_gss_init_sec_context( OM_uint32 Curl_gss_init_sec_context(
struct SessionHandle *data, struct SessionHandle *data,
OM_uint32 * minor_status, OM_uint32 *minor_status,
gss_ctx_id_t * context, gss_ctx_id_t *context,
gss_name_t target_name, gss_name_t target_name,
gss_OID mech_type,
gss_channel_bindings_t input_chan_bindings, gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token, gss_buffer_t input_token,
gss_buffer_t output_token, gss_buffer_t output_token,
OM_uint32 * ret_flags); OM_uint32 *ret_flags);
#endif /* HAVE_GSSAPI */ #endif /* HAVE_GSSAPI */

View File

@@ -353,6 +353,9 @@ void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
ntlm->has_handles = 0; ntlm->has_handles = 0;
} }
ntlm->max_token_length = 0;
Curl_safefree(ntlm->output_token);
Curl_sspi_free_identity(ntlm->p_identity); Curl_sspi_free_identity(ntlm->p_identity);
ntlm->p_identity = NULL; ntlm->p_identity = NULL;
} }
@@ -409,11 +412,11 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
(*) -> Optional (*) -> Optional
*/ */
unsigned char ntlmbuf[NTLM_BUFSIZE];
size_t size; size_t size;
#ifdef USE_WINDOWS_SSPI #ifdef USE_WINDOWS_SSPI
PSecPkgInfo SecurityPackage;
SecBuffer type_1_buf; SecBuffer type_1_buf;
SecBufferDesc type_1_desc; SecBufferDesc type_1_desc;
SECURITY_STATUS status; SECURITY_STATUS status;
@@ -422,6 +425,22 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
Curl_ntlm_sspi_cleanup(ntlm); Curl_ntlm_sspi_cleanup(ntlm);
/* Query the security package for NTLM */
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("NTLM"),
&SecurityPackage);
if(status != SEC_E_OK)
return CURLE_NOT_BUILT_IN;
ntlm->max_token_length = SecurityPackage->cbMaxToken;
/* Release the package buffer as it is not required anymore */
s_pSecFn->FreeContextBuffer(SecurityPackage);
/* Allocate our output buffer */
ntlm->output_token = malloc(ntlm->max_token_length);
if(!ntlm->output_token)
return CURLE_OUT_OF_MEMORY;
if(userp && *userp) { if(userp && *userp) {
CURLcode result; CURLcode result;
@@ -450,9 +469,9 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
type_1_desc.ulVersion = SECBUFFER_VERSION; type_1_desc.ulVersion = SECBUFFER_VERSION;
type_1_desc.cBuffers = 1; type_1_desc.cBuffers = 1;
type_1_desc.pBuffers = &type_1_buf; type_1_desc.pBuffers = &type_1_buf;
type_1_buf.cbBuffer = NTLM_BUFSIZE;
type_1_buf.BufferType = SECBUFFER_TOKEN; type_1_buf.BufferType = SECBUFFER_TOKEN;
type_1_buf.pvBuffer = ntlmbuf; type_1_buf.pvBuffer = ntlm->output_token;
type_1_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
/* Generate our type-1 message */ /* Generate our type-1 message */
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL, status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
@@ -478,6 +497,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
#else #else
unsigned char ntlmbuf[NTLM_BUFSIZE];
const char *host = ""; /* empty */ const char *host = ""; /* empty */
const char *domain = ""; /* empty */ const char *domain = ""; /* empty */
size_t hostlen = 0; size_t hostlen = 0;
@@ -555,7 +575,12 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
}); });
/* Return with binary blob encoded into base64 */ /* Return with binary blob encoded into base64 */
#ifdef USE_WINDOWS_SSPI
return Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
outptr, outlen);
#else
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
#endif
} }
/* /*
@@ -602,10 +627,10 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
(*) -> Optional (*) -> Optional
*/ */
unsigned char ntlmbuf[NTLM_BUFSIZE];
size_t size; size_t size;
#ifdef USE_WINDOWS_SSPI #ifdef USE_WINDOWS_SSPI
CURLcode result = CURLE_OK;
SecBuffer type_2_buf; SecBuffer type_2_buf;
SecBuffer type_3_buf; SecBuffer type_3_buf;
SecBufferDesc type_2_desc; SecBufferDesc type_2_desc;
@@ -631,8 +656,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
type_3_desc.cBuffers = 1; type_3_desc.cBuffers = 1;
type_3_desc.pBuffers = &type_3_buf; type_3_desc.pBuffers = &type_3_buf;
type_3_buf.BufferType = SECBUFFER_TOKEN; type_3_buf.BufferType = SECBUFFER_TOKEN;
type_3_buf.pvBuffer = ntlmbuf; type_3_buf.pvBuffer = ntlm->output_token;
type_3_buf.cbBuffer = NTLM_BUFSIZE; type_3_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
/* Generate our type-3 message */ /* Generate our type-3 message */
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, status = s_pSecFn->InitializeSecurityContext(&ntlm->handle,
@@ -651,9 +676,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
size = type_3_buf.cbBuffer; size = type_3_buf.cbBuffer;
/* Return with binary blob encoded into base64 */
result = Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
outptr, outlen);
Curl_ntlm_sspi_cleanup(ntlm); Curl_ntlm_sspi_cleanup(ntlm);
return result;
#else #else
unsigned char ntlmbuf[NTLM_BUFSIZE];
int lmrespoff; int lmrespoff;
unsigned char lmresp[24]; /* fixed-size */ unsigned char lmresp[24]; /* fixed-size */
#if USE_NTRESPONSES #if USE_NTRESPONSES
@@ -969,10 +1002,9 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
if(res) if(res)
return CURLE_CONV_FAILED; return CURLE_CONV_FAILED;
#endif
/* Return with binary blob encoded into base64 */ /* Return with binary blob encoded into base64 */
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
#endif
} }
#endif /* USE_NTLM */ #endif /* USE_NTLM */

View File

@@ -39,6 +39,9 @@
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
#include <signal.h> #include <signal.h>
#endif #endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
@@ -117,6 +120,10 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
char *slash, *domain = NULL; char *slash, *domain = NULL;
const char *ntlm_auth = NULL; const char *ntlm_auth = NULL;
char *ntlm_auth_alloc = NULL; char *ntlm_auth_alloc = NULL;
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
struct passwd pw, *pw_res;
char pwbuf[1024];
#endif
int error; int error;
/* Return if communication with ntlm_auth already set up */ /* Return if communication with ntlm_auth already set up */
@@ -125,6 +132,30 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
return CURLE_OK; return CURLE_OK;
username = userp; username = userp;
/* The real ntlm_auth really doesn't like being invoked with an
empty username. It won't make inferences for itself, and expects
the client to do so (mostly because it's really designed for
servers like squid to use for auth, and client support is an
afterthought for it). So try hard to provide a suitable username
if we don't already have one. But if we can't, provide the
empty one anyway. Perhaps they have an implementation of the
ntlm_auth helper which *doesn't* need it so we might as well try */
if(!username || !username[0]) {
username = getenv("NTLMUSER");
if(!username || !username[0])
username = getenv("LOGNAME");
if(!username || !username[0])
username = getenv("USER");
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
if((!username || !username[0]) &&
!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
pw_res) {
username = pw.pw_name;
}
#endif
if(!username || !username[0])
username = userp;
}
slash = strpbrk(username, "\\/"); slash = strpbrk(username, "\\/");
if(slash) { if(slash) {
if((domain = strdup(username)) == NULL) if((domain = strdup(username)) == NULL)
@@ -227,11 +258,11 @@ done:
static CURLcode ntlm_wb_response(struct connectdata *conn, static CURLcode ntlm_wb_response(struct connectdata *conn,
const char *input, curlntlm state) const char *input, curlntlm state)
{ {
ssize_t size; char *buf = malloc(NTLM_BUFSIZE);
char buf[NTLM_BUFSIZE]; size_t len_in = strlen(input), len_out = 0;
char *tmpbuf = buf;
size_t len_in = strlen(input); if(!buf)
size_t len_out = sizeof(buf); return CURLE_OUT_OF_MEMORY;
while(len_in > 0) { while(len_in > 0) {
ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in); ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
@@ -246,8 +277,11 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
len_in -= written; len_in -= written;
} }
/* Read one line */ /* Read one line */
while(len_out > 0) { while(1) {
size = sread(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out); ssize_t size;
char *newbuf;
size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
if(size == -1) { if(size == -1) {
if(errno == EINTR) if(errno == EINTR)
continue; continue;
@@ -255,22 +289,28 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
} }
else if(size == 0) else if(size == 0)
goto done; goto done;
else if(tmpbuf[size - 1] == '\n') {
tmpbuf[size - 1] = '\0'; len_out += size;
if(buf[len_out - 1] == '\n') {
buf[len_out - 1] = '\0';
goto wrfinish; goto wrfinish;
} }
tmpbuf += size; newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
len_out -= size; if(!newbuf) {
free(buf);
return CURLE_OUT_OF_MEMORY;
}
buf = newbuf;
} }
goto done; goto done;
wrfinish: wrfinish:
/* Samba/winbind installed but not configured */ /* Samba/winbind installed but not configured */
if(state == NTLMSTATE_TYPE1 && if(state == NTLMSTATE_TYPE1 &&
size == 3 && len_out == 3 &&
buf[0] == 'P' && buf[1] == 'W') buf[0] == 'P' && buf[1] == 'W')
return CURLE_REMOTE_ACCESS_DENIED; return CURLE_REMOTE_ACCESS_DENIED;
/* invalid response */ /* invalid response */
if(size < 4) if(len_out < 4)
goto done; goto done;
if(state == NTLMSTATE_TYPE1 && if(state == NTLMSTATE_TYPE1 &&
(buf[0]!='Y' || buf[1]!='R' || buf[2]!=' ')) (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
@@ -280,9 +320,11 @@ wrfinish:
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' ')) (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
goto done; goto done;
conn->response_header = aprintf("NTLM %.*s", size - 4, buf + 3); conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
free(buf);
return CURLE_OK; return CURLE_OK;
done: done:
free(buf);
return CURLE_REMOTE_ACCESS_DENIED; return CURLE_REMOTE_ACCESS_DENIED;
} }

View File

@@ -53,6 +53,10 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
#if defined(USE_WINDOWS_SSPI)
extern void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI) #if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
#define DIGEST_QOP_VALUE_AUTH (1 << 0) #define DIGEST_QOP_VALUE_AUTH (1 << 0)
#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) #define DIGEST_QOP_VALUE_AUTH_INT (1 << 1)
@@ -120,6 +124,26 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
} }
#endif #endif
#if !defined(USE_WINDOWS_SSPI)
/*
* Curl_sasl_build_spn()
*
* This is used to build a SPN string in the format service/host.
*
* Parameters:
*
* serivce [in] - The service type such as www, smtp, pop or imap.
* instance [in] - The instance name such as the host nme or realm.
*
* Returns a pointer to the newly allocated SPN.
*/
char *Curl_sasl_build_spn(const char *service, const char *host)
{
/* Generate and return our SPN */
return aprintf("%s/%s", service, host);
}
#endif
/* /*
* Curl_sasl_create_plain_message() * Curl_sasl_create_plain_message()
* *
@@ -421,7 +445,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
char nonceCount[] = "00000001"; char nonceCount[] = "00000001";
char method[] = "AUTHENTICATE"; char method[] = "AUTHENTICATE";
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH; char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
char uri[128]; char *spn = NULL;
/* Decode the challange message */ /* Decode the challange message */
result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
@@ -486,19 +510,24 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
for(i = 0; i < MD5_DIGEST_LEN; i++) for(i = 0; i < MD5_DIGEST_LEN; i++)
snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
/* Prepare the URL string */ /* Generate our SPN */
snprintf(uri, sizeof(uri), "%s/%s", service, realm); spn = Curl_sasl_build_spn(service, realm);
if(!spn)
return CURLE_OUT_OF_MEMORY;
/* Calculate H(A2) */ /* Calculate H(A2) */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5); ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
if(!ctxt) if(!ctxt) {
Curl_safefree(spn);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
Curl_MD5_update(ctxt, (const unsigned char *) method, Curl_MD5_update(ctxt, (const unsigned char *) method,
curlx_uztoui(strlen(method))); curlx_uztoui(strlen(method)));
Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
Curl_MD5_update(ctxt, (const unsigned char *) uri, Curl_MD5_update(ctxt, (const unsigned char *) spn,
curlx_uztoui(strlen(uri))); curlx_uztoui(strlen(spn)));
Curl_MD5_final(ctxt, digest); Curl_MD5_final(ctxt, digest);
for(i = 0; i < MD5_DIGEST_LEN; i++) for(i = 0; i < MD5_DIGEST_LEN; i++)
@@ -506,8 +535,11 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
/* Now calculate the response hash */ /* Now calculate the response hash */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5); ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
if(!ctxt) if(!ctxt) {
Curl_safefree(spn);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN); Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN);
Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
@@ -536,17 +568,19 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s," "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s,"
"qop=%s", "qop=%s",
userp, realm, nonce, userp, realm, nonce,
cnonce, nonceCount, uri, resp_hash_hex, qop); cnonce, nonceCount, spn, resp_hash_hex, qop);
Curl_safefree(spn);
if(!response) if(!response)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
/* Base64 encode the response */ /* Base64 encode the response */
result = Curl_base64_encode(data, response, 0, outptr, outlen); result = Curl_base64_encode(data, response, 0, outptr, outlen);
free(response); Curl_safefree(response);
return result; return result;
} }
#endif /* USE_WINDOWS_SSPI */ #endif /* !USE_WINDOWS_SSPI */
#endif /* CURL_DISABLE_CRYPTO_AUTH */ #endif /* CURL_DISABLE_CRYPTO_AUTH */
@@ -688,12 +722,17 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
*/ */
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
{ {
#if defined(USE_WINDOWS_SSPI)
/* Cleanup the gssapi structure */
if(authused == SASL_MECH_GSSAPI) {
Curl_sasl_gssapi_cleanup(&conn->krb5);
}
#ifdef USE_NTLM #ifdef USE_NTLM
/* Cleanup the ntlm structure */ /* Cleanup the ntlm structure */
if(authused == SASL_MECH_NTLM) { else if(authused == SASL_MECH_NTLM) {
Curl_ntlm_sspi_cleanup(&conn->ntlm); Curl_ntlm_sspi_cleanup(&conn->ntlm);
} }
(void)conn; #endif
#else #else
/* Reserved for future use */ /* Reserved for future use */
(void)conn; (void)conn;

View File

@@ -28,6 +28,10 @@ struct SessionHandle;
struct connectdata; struct connectdata;
struct ntlmdata; struct ntlmdata;
#if defined(USE_WINDOWS_SSPI)
struct kerberos5data;
#endif
/* Authentication mechanism values */ /* Authentication mechanism values */
#define SASL_AUTH_NONE 0 #define SASL_AUTH_NONE 0
#define SASL_AUTH_ANY ~0U #define SASL_AUTH_ANY ~0U
@@ -57,6 +61,13 @@ struct ntlmdata;
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \ (wordlen == (sizeof(mech) - 1) / sizeof(char) && \
!memcmp(line, mech, wordlen)) !memcmp(line, mech, wordlen))
/* This is used to build a SPN string */
#if !defined(USE_WINDOWS_SSPI)
char *Curl_sasl_build_spn(const char *service, const char *instance);
#else
TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
#endif
/* This is used to generate a base64 encoded PLAIN authentication message */ /* This is used to generate a base64 encoded PLAIN authentication message */
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
const char *userp, const char *userp,
@@ -112,6 +123,27 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
#endif /* USE_NTLM */ #endif /* USE_NTLM */
#if defined(USE_WINDOWS_SSPI)
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
message */
CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
const char *userp,
const char *passwdp,
const char *service,
const bool mutual,
const char *chlg64,
struct kerberos5data *krb5,
char **outptr, size_t *outlen);
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
token message */
CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
const char *input,
struct kerberos5data *krb5,
char **outptr,
size_t *outlen);
#endif
/* This is used to generate a base64 encoded XOAUTH2 authentication message /* This is used to generate a base64 encoded XOAUTH2 authentication message
containing the user name and bearer token */ containing the user name and bearer token */
CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data, CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,

View File

@@ -5,6 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2014, Steve Holme, <steve_holme@hotmail.com>.
* Copyright (C) 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
@@ -20,12 +21,13 @@
* *
* RFC2831 DIGEST-MD5 authentication * RFC2831 DIGEST-MD5 authentication
* RFC4422 Simple Authentication and Security Layer (SASL) * RFC4422 Simple Authentication and Security Layer (SASL)
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
* *
***************************************************************************/ ***************************************************************************/
#include "curl_setup.h" #include "curl_setup.h"
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_CRYPTO_AUTH) #if defined(USE_WINDOWS_SSPI)
#include <curl/curl.h> #include <curl/curl.h>
@@ -34,6 +36,7 @@
#include "curl_base64.h" #include "curl_base64.h"
#include "warnless.h" #include "warnless.h"
#include "curl_memory.h" #include "curl_memory.h"
#include "curl_multibyte.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -41,6 +44,55 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
/*
* Curl_sasl_build_spn()
*
* This is used to build a SPN string in the format service/host.
*
* Parameters:
*
* serivce [in] - The service type such as www, smtp, pop or imap.
* instance [in] - The instance name such as the host nme or realm.
*
* Returns a pointer to the newly allocated SPN.
*/
TCHAR *Curl_sasl_build_spn(const char *service, const char *host)
{
char *utf8_spn = NULL;
TCHAR *tchar_spn = NULL;
/* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
than doing this ourselves but the first is only available in Windows XP
and Windows Server 2003 and the latter is only available in Windows 2000
but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
Client Extensions are installed. As such it is far simpler for us to
formulate the SPN instead. */
/* Allocate our UTF8 based SPN */
utf8_spn = aprintf("%s/%s", service, host);
if(!utf8_spn) {
return NULL;
}
/* Allocate our TCHAR based SPN */
tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
if(!tchar_spn) {
Curl_safefree(utf8_spn);
return NULL;
}
/* Release the UTF8 variant when operating with Unicode */
if(utf8_spn != tchar_spn)
Curl_safefree(utf8_spn);
/* Return our newly allocated SPN */
return tchar_spn;
}
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
/* /*
* Curl_sasl_create_digest_md5_message() * Curl_sasl_create_digest_md5_message()
* *
@@ -68,10 +120,11 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
char **outptr, size_t *outlen) char **outptr, size_t *outlen)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
char *spn = NULL; TCHAR *spn = NULL;
size_t chlglen = 0; size_t chlglen = 0;
size_t resp_max = 0;
unsigned char *chlg = NULL; unsigned char *chlg = NULL;
unsigned char resp[1024]; unsigned char *resp = NULL;
CredHandle handle; CredHandle handle;
CtxtHandle ctx; CtxtHandle ctx;
PSecPkgInfo SecurityPackage; PSecPkgInfo SecurityPackage;
@@ -107,18 +160,37 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
&SecurityPackage); &SecurityPackage);
if(status != SEC_E_OK) { if(status != SEC_E_OK) {
Curl_safefree(chlg); Curl_safefree(chlg);
return CURLE_NOT_BUILT_IN; return CURLE_NOT_BUILT_IN;
} }
/* Calculate our SPN */ resp_max = SecurityPackage->cbMaxToken;
spn = aprintf("%s/%s", service, data->easy_conn->host.name);
if(!spn) /* Release the package buffer as it is not required anymore */
s_pSecFn->FreeContextBuffer(SecurityPackage);
/* Allocate our response buffer */
resp = malloc(resp_max);
if(!resp) {
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
}
/* Generate our SPN */
spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
if(!spn) {
Curl_safefree(resp);
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Populate our identity structure */ /* Populate our identity structure */
result = Curl_create_sspi_identity(userp, passwdp, &identity); result = Curl_create_sspi_identity(userp, passwdp, &identity);
if(result) { if(result) {
Curl_safefree(spn); Curl_safefree(spn);
Curl_safefree(resp);
Curl_safefree(chlg); Curl_safefree(chlg);
return result; return result;
@@ -134,6 +206,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
if(status != SEC_E_OK) { if(status != SEC_E_OK) {
Curl_sspi_free_identity(&identity); Curl_sspi_free_identity(&identity);
Curl_safefree(spn); Curl_safefree(spn);
Curl_safefree(resp);
Curl_safefree(chlg); Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
@@ -153,17 +226,12 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
resp_desc.pBuffers = &resp_buf; resp_desc.pBuffers = &resp_buf;
resp_buf.BufferType = SECBUFFER_TOKEN; resp_buf.BufferType = SECBUFFER_TOKEN;
resp_buf.pvBuffer = resp; resp_buf.pvBuffer = resp;
resp_buf.cbBuffer = sizeof(resp); resp_buf.cbBuffer = curlx_uztoul(resp_max);
/* Generate our challenge-response message */ /* Generate our challenge-response message */
status = s_pSecFn->InitializeSecurityContext(&handle, status = s_pSecFn->InitializeSecurityContext(&handle, NULL, spn, 0, 0, 0,
NULL, &chlg_desc, 0, &ctx,
(TCHAR *) spn, &resp_desc, &attrs, &tsDummy);
0, 0, 0,
&chlg_desc,
0, &ctx,
&resp_desc,
&attrs, &tsDummy);
if(status == SEC_I_COMPLETE_AND_CONTINUE || if(status == SEC_I_COMPLETE_AND_CONTINUE ||
status == SEC_I_CONTINUE_NEEDED) status == SEC_I_CONTINUE_NEEDED)
@@ -172,6 +240,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
s_pSecFn->FreeCredentialsHandle(&handle); s_pSecFn->FreeCredentialsHandle(&handle);
Curl_sspi_free_identity(&identity); Curl_sspi_free_identity(&identity);
Curl_safefree(spn); Curl_safefree(spn);
Curl_safefree(resp);
Curl_safefree(chlg); Curl_safefree(chlg);
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
@@ -191,10 +260,437 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
/* Free the SPN */ /* Free the SPN */
Curl_safefree(spn); Curl_safefree(spn);
/* Free the response buffer */
Curl_safefree(resp);
/* Free the decoeded challenge message */ /* Free the decoeded challenge message */
Curl_safefree(chlg); Curl_safefree(chlg);
return result; return result;
} }
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */ #endif /* !CURL_DISABLE_CRYPTO_AUTH */
/*
* Curl_sasl_create_gssapi_user_message()
*
* This is used to generate an already encoded GSSAPI (Kerberos V5) user token
* message ready for sending to the recipient.
*
* Parameters:
*
* data [in] - The session handle.
* userp [in] - The user name.
* passdwp [in] - The user's password.
* service [in] - The service type such as www, smtp, pop or imap.
* mutual_auth [in] - Flag specifing whether or not mutual authentication
* is enabled.
* chlg64 [in] - Pointer to the optional base64 encoded challenge
* message.
* krb5 [in/out] - The gssapi data struct being used and modified.
* 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_create_gssapi_user_message(struct SessionHandle *data,
const char *userp,
const char *passwdp,
const char *service,
const bool mutual_auth,
const char *chlg64,
struct kerberos5data *krb5,
char **outptr, size_t *outlen)
{
CURLcode result = CURLE_OK;
size_t chlglen = 0;
unsigned char *chlg = NULL;
CtxtHandle context;
PSecPkgInfo SecurityPackage;
SecBuffer chlg_buf;
SecBuffer resp_buf;
SecBufferDesc chlg_desc;
SecBufferDesc resp_desc;
SECURITY_STATUS status;
unsigned long attrs;
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
if(!krb5->credentials) {
/* Query the security package for Kerberos */
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Kerberos"),
&SecurityPackage);
if(status != SEC_E_OK) {
return CURLE_NOT_BUILT_IN;
}
krb5->token_max = SecurityPackage->cbMaxToken;
/* Release the package buffer as it is not required anymore */
s_pSecFn->FreeContextBuffer(SecurityPackage);
/* Generate our SPN */
krb5->spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
if(!krb5->spn)
return CURLE_OUT_OF_MEMORY;
if(userp && *userp) {
/* Populate our identity structure */
result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity);
if(result)
return result;
/* Allow proper cleanup of the identity structure */
krb5->p_identity = &krb5->identity;
/* Allocate our response buffer */
krb5->output_token = malloc(krb5->token_max);
if(!krb5->output_token)
return CURLE_OUT_OF_MEMORY;
}
else
/* Use the current Windows user */
krb5->p_identity = NULL;
/* Allocate our credentials handle */
krb5->credentials = malloc(sizeof(CredHandle));
if(!krb5->credentials)
return CURLE_OUT_OF_MEMORY;
memset(krb5->credentials, 0, sizeof(CredHandle));
/* Acquire our credientials handle */
status = s_pSecFn->AcquireCredentialsHandle(NULL,
(TCHAR *) TEXT("Kerberos"),
SECPKG_CRED_OUTBOUND, NULL,
krb5->p_identity, NULL, NULL,
krb5->credentials, &tsDummy);
if(status != SEC_E_OK)
return CURLE_OUT_OF_MEMORY;
/* Allocate our new context handle */
krb5->context = malloc(sizeof(CtxtHandle));
if(!krb5->context)
return CURLE_OUT_OF_MEMORY;
memset(krb5->context, 0, sizeof(CtxtHandle));
}
else {
/* Decode the base-64 encoded challenge message */
if(strlen(chlg64) && *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;
/* Setup the challenge "input" security buffer */
chlg_desc.ulVersion = SECBUFFER_VERSION;
chlg_desc.cBuffers = 1;
chlg_desc.pBuffers = &chlg_buf;
chlg_buf.BufferType = SECBUFFER_TOKEN;
chlg_buf.pvBuffer = chlg;
chlg_buf.cbBuffer = curlx_uztoul(chlglen);
}
/* Setup the response "output" security buffer */
resp_desc.ulVersion = SECBUFFER_VERSION;
resp_desc.cBuffers = 1;
resp_desc.pBuffers = &resp_buf;
resp_buf.BufferType = SECBUFFER_TOKEN;
resp_buf.pvBuffer = krb5->output_token;
resp_buf.cbBuffer = curlx_uztoul(krb5->token_max);
/* Generate our challenge-response message */
status = s_pSecFn->InitializeSecurityContext(krb5->credentials,
chlg ? krb5->context : NULL,
krb5->spn,
(mutual_auth ?
ISC_REQ_MUTUAL_AUTH : 0),
0, SECURITY_NATIVE_DREP,
chlg ? &chlg_desc : NULL, 0,
&context,
&resp_desc, &attrs,
&tsDummy);
if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
Curl_safefree(chlg);
return CURLE_RECV_ERROR;
}
if(memcmp(&context, krb5->context, sizeof(context))) {
s_pSecFn->DeleteSecurityContext(krb5->context);
memcpy(krb5->context, &context, sizeof(context));
}
if(resp_buf.cbBuffer) {
/* Base64 encode the response */
result = Curl_base64_encode(data, (char *)resp_buf.pvBuffer,
resp_buf.cbBuffer, outptr, outlen);
}
/* Free the decoded challenge */
Curl_safefree(chlg);
return result;
}
/*
* Curl_sasl_create_gssapi_security_message()
*
* This is used to generate an already encoded GSSAPI (Kerberos V5) security
* token message ready for sending to the recipient.
*
* Parameters:
*
* data [in] - The session handle.
* chlg64 [in] - Pointer to the optional base64 encoded challenge message.
* krb5 [in/out] - The gssapi data struct being used and modified.
* 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_create_gssapi_security_message(struct SessionHandle *data,
const char *chlg64,
struct kerberos5data *krb5,
char **outptr,
size_t *outlen)
{
CURLcode result = CURLE_OK;
size_t offset = 0;
size_t chlglen = 0;
size_t messagelen = 0;
size_t appdatalen = 0;
unsigned char *chlg = NULL;
unsigned char *trailer = NULL;
unsigned char *message = NULL;
unsigned char *padding = NULL;
unsigned char *appdata = NULL;
SecBuffer input_buf[2];
SecBuffer wrap_buf[3];
SecBufferDesc input_desc;
SecBufferDesc wrap_desc;
unsigned long indata = 0;
unsigned long outdata = 0;
unsigned long qop = 0;
unsigned long sec_layer = 0;
unsigned long max_size = 0;
SecPkgContext_Sizes sizes;
SecPkgCredentials_Names names;
SECURITY_STATUS status;
/* TODO: Verify the unicodeness of this function */
/* Decode the base-64 encoded input message */
if(strlen(chlg64) && *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;
/* Get our response size information */
status = s_pSecFn->QueryContextAttributes(krb5->context,
SECPKG_ATTR_SIZES,
&sizes);
if(status != SEC_E_OK) {
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Get the fully qualified username back from the context */
status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
SECPKG_CRED_ATTR_NAMES,
&names);
if(status != SEC_E_OK) {
Curl_safefree(chlg);
return CURLE_RECV_ERROR;
}
/* Setup the "input" security buffer */
input_desc.ulVersion = SECBUFFER_VERSION;
input_desc.cBuffers = 2;
input_desc.pBuffers = input_buf;
input_buf[0].BufferType = SECBUFFER_STREAM;
input_buf[0].pvBuffer = chlg;
input_buf[0].cbBuffer = curlx_uztoul(chlglen);
input_buf[1].BufferType = SECBUFFER_DATA;
input_buf[1].pvBuffer = NULL;
input_buf[1].cbBuffer = 0;
/* Decrypt in the inbound challenge obtaining the qop */
status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
if(status != SEC_E_OK) {
Curl_safefree(chlg);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Not 4 octets long to fail as per RFC4752 Section 3.1 */
if(input_buf[1].cbBuffer != 4) {
Curl_safefree(chlg);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Copy the data out into a coinput_bufnvenient variable and free the SSPI
allocated buffer as it is not required anymore */
memcpy(&indata, input_buf[1].pvBuffer, 4);
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
/* Extract the security layer */
sec_layer = indata & 0x000000FF;
if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
Curl_safefree(chlg);
return CURLE_BAD_CONTENT_ENCODING;
}
/* Extract the maximum message size the server can receive */
max_size = ntohl(indata & 0xFFFFFF00);
if(max_size > 0) {
/* The server has told us it supports a maximum receive buffer, however, as
we don't require one unless we are encrypting data we, tell the server
our receive buffer is zero. */
max_size = 0;
}
outdata = htonl(max_size) | sec_layer;
/* Allocate the trailer */
trailer = malloc(sizes.cbSecurityTrailer);
if(!trailer) {
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Allocate our message */
messagelen = 4 + strlen(names.sUserName) + 1;
message = malloc(messagelen);
if(!message) {
Curl_safefree(trailer);
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Populate the message with the security layer, client supported receive
message size and authorization identity including the 0x00 based
terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
identity is not terminated with the zero-valued (%x00) octet." it seems
necessary to include it. */
memcpy(message, &outdata, 4);
strcpy((char *)message + 4, names.sUserName);
/* Allocate the padding */
padding = malloc(sizes.cbBlockSize);
if(!padding) {
Curl_safefree(message);
Curl_safefree(trailer);
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Setup the "authentication data" security buffer */
wrap_desc.ulVersion = SECBUFFER_VERSION;
wrap_desc.cBuffers = 3;
wrap_desc.pBuffers = wrap_buf;
wrap_buf[0].BufferType = SECBUFFER_TOKEN;
wrap_buf[0].pvBuffer = trailer;
wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer;
wrap_buf[1].BufferType = SECBUFFER_DATA;
wrap_buf[1].pvBuffer = message;
wrap_buf[1].cbBuffer = curlx_uztoul(messagelen);
wrap_buf[2].BufferType = SECBUFFER_PADDING;
wrap_buf[2].pvBuffer = padding;
wrap_buf[2].cbBuffer = sizes.cbBlockSize;
/* Encrypt the data */
status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
&wrap_desc, 0);
if(status != SEC_E_OK) {
Curl_safefree(padding);
Curl_safefree(message);
Curl_safefree(trailer);
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Allocate the encryption (wrap) buffer */
appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer +
wrap_buf[2].cbBuffer;
appdata = malloc(appdatalen);
if(!appdata) {
Curl_safefree(padding);
Curl_safefree(message);
Curl_safefree(trailer);
Curl_safefree(chlg);
return CURLE_OUT_OF_MEMORY;
}
/* Populate the encryption buffer */
memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer);
offset += wrap_buf[0].cbBuffer;
memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer);
offset += wrap_buf[1].cbBuffer;
memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer);
/* Base64 encode the response */
result = Curl_base64_encode(data, (char *)appdata, appdatalen, outptr,
outlen);
/* Free all of our local buffers */
Curl_safefree(appdata);
Curl_safefree(padding);
Curl_safefree(message);
Curl_safefree(trailer);
Curl_safefree(chlg);
return result;
}
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
{
/* Free the context */
if(krb5->context) {
s_pSecFn->DeleteSecurityContext(krb5->context);
free(krb5->context);
krb5->context = NULL;
}
/* Free the credientials handle */
if(krb5->credentials) {
s_pSecFn->FreeCredentialsHandle(krb5->credentials);
free(krb5->credentials);
krb5->credentials = NULL;
}
/* Free our identity */
Curl_sspi_free_identity(krb5->p_identity);
krb5->p_identity = NULL;
/* Free the SPN and output token */
Curl_safefree(krb5->spn);
Curl_safefree(krb5->output_token);
/* Reset any variables */
krb5->token_max = 0;
}
#endif /* USE_WINDOWS_SSPI */

View File

@@ -610,7 +610,7 @@ int netware_init(void);
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ #if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
#define USE_HTTP_NEGOTIATE #define USE_SPNEGO
#endif #endif
/* Single point where USE_NTLM definition might be done */ /* Single point where USE_NTLM definition might be done */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -304,5 +304,12 @@ extern PSecurityFunctionTable s_pSecFn;
(unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
#endif #endif
/*
* Definitions required from ntsecapi.h are directly provided below this point
* to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
*/
#define KERB_WRAP_NO_ENCRYPT 0x80000001
#endif /* USE_WINDOWS_SSPI */ #endif /* USE_WINDOWS_SSPI */
#endif /* HEADER_CURL_SSPI_H */ #endif /* HEADER_CURL_SSPI_H */

View File

@@ -4470,8 +4470,8 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
Curl_pgrsSetUploadCounter(data, 0); Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0); Curl_pgrsSetDownloadCounter(data, 0);
Curl_pgrsSetUploadSize(data, 0); Curl_pgrsSetUploadSize(data, -1);
Curl_pgrsSetDownloadSize(data, 0); Curl_pgrsSetDownloadSize(data, -1);
ftpc->ctl_valid = TRUE; /* starts good */ ftpc->ctl_valid = TRUE; /* starts good */

View File

@@ -285,6 +285,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
struct curl_tlssessioninfo *tsi = &data->tsi; struct curl_tlssessioninfo *tsi = &data->tsi;
struct connectdata *conn = data->easy_conn; struct connectdata *conn = data->easy_conn;
unsigned int sockindex = 0; unsigned int sockindex = 0;
void *internals = NULL;
*tsip = tsi; *tsip = tsi;
tsi->backend = CURLSSLBACKEND_NONE; tsi->backend = CURLSSLBACKEND_NONE;
@@ -303,25 +304,24 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
/* Return the TLS session information from the relevant backend */ /* Return the TLS session information from the relevant backend */
#ifdef USE_SSLEAY #ifdef USE_SSLEAY
tsi->backend = CURLSSLBACKEND_OPENSSL; internals = conn->ssl[sockindex].ctx;
tsi->internals = conn->ssl[sockindex].ctx;
#endif #endif
#ifdef USE_GNUTLS #ifdef USE_GNUTLS
tsi->backend = CURLSSLBACKEND_GNUTLS; internals = conn->ssl[sockindex].session;
tsi->internals = conn->ssl[sockindex].session;
#endif #endif
#ifdef USE_NSS #ifdef USE_NSS
tsi->backend = CURLSSLBACKEND_NSS; internals = conn->ssl[sockindex].handle;
tsi->internals = conn->ssl[sockindex].handle;
#endif #endif
#ifdef USE_QSOSSL #ifdef USE_QSOSSL
tsi->backend = CURLSSLBACKEND_QSOSSL; internals = conn->ssl[sockindex].handle;
tsi->internals = conn->ssl[sockindex].handle;
#endif #endif
#ifdef USE_GSKIT #ifdef USE_GSKIT
tsi->backend = CURLSSLBACKEND_GSKIT; internals = conn->ssl[sockindex].handle;
tsi->internals = conn->ssl[sockindex].handle;
#endif #endif
if(internals) {
tsi->backend = Curl_ssl_backend();
tsi->internals = internals;
}
/* NOTE: For other SSL backends, it is not immediately clear what data /* 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 to return from 'struct ssl_connect_data'; thus, for now we keep the
backend as CURLSSLBACKEND_NONE in those cases, which should be backend as CURLSSLBACKEND_NONE in those cases, which should be

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -318,6 +318,48 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
sigjmp_buf curl_jmpenv; sigjmp_buf curl_jmpenv;
#endif #endif
/*
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
*
* Curl_resolv() checks initially and multi_runsingle() checks each time
* it discovers the handle in the state WAITRESOLVE whether the hostname
* has already been resolved and the address has already been stored in
* the DNS cache. This short circuits waiting for a lot of pending
* lookups for the same hostname requested by different handles.
*
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
*/
struct Curl_dns_entry *
Curl_fetch_addr(struct connectdata *conn,
const char *hostname,
int port, int *stale)
{
char *entry_id = NULL;
struct Curl_dns_entry *dns = NULL;
size_t entry_len;
struct SessionHandle *data = conn->data;
/* Create an entry id, based upon the hostname and port */
entry_id = create_hostcache_id(hostname, port);
/* If we can't create the entry id, fail */
if(!entry_id)
return dns;
entry_len = strlen(entry_id);
/* See if its already in our dns cache */
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
/* free the allocated entry_id again */
free(entry_id);
/* See whether the returned entry is stale. Done before we release lock */
*stale = remove_entry_if_stale(data, dns);
if(*stale)
dns = NULL; /* the memory deallocation is being handled by the hash */
return dns;
}
/* /*
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
@@ -403,39 +445,22 @@ int Curl_resolv(struct connectdata *conn,
int port, int port,
struct Curl_dns_entry **entry) struct Curl_dns_entry **entry)
{ {
char *entry_id = NULL;
struct Curl_dns_entry *dns = NULL; struct Curl_dns_entry *dns = NULL;
size_t entry_len;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
CURLcode result; CURLcode result;
int rc = CURLRESOLV_ERROR; /* default to failure */ int stale, rc = CURLRESOLV_ERROR; /* default to failure */
*entry = NULL; *entry = NULL;
/* Create an entry id, based upon the hostname and port */
entry_id = create_hostcache_id(hostname, port);
/* If we can't create the entry id, fail */
if(!entry_id)
return rc;
entry_len = strlen(entry_id);
if(data->share) if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
/* See if its already in our dns cache */ dns = Curl_fetch_addr(conn, hostname, port, &stale);
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
/* free the allocated entry_id again */ infof(data, "Hostname was %sfound in DNS cache\n", dns||stale?"":"NOT ");
free(entry_id); if(stale)
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)) {
infof(data, "Hostname in DNS cache was stale, zapped\n"); infof(data, "Hostname in DNS cache was stale, zapped\n");
dns = NULL; /* the memory deallocation is being handled by the hash */
}
if(dns) { if(dns) {
dns->inuse++; /* we use it! */ dns->inuse++; /* we use it! */

View File

@@ -171,6 +171,17 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
const char *Curl_printable_address(const Curl_addrinfo *ip, const char *Curl_printable_address(const Curl_addrinfo *ip,
char *buf, size_t bufsize); char *buf, size_t bufsize);
/*
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
*
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
*/
struct Curl_dns_entry *
Curl_fetch_addr(struct connectdata *conn,
const char *hostname,
int port,
int *stale);
/* /*
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
* *

View File

@@ -328,8 +328,8 @@ static bool pickoneauth(struct auth *pick)
/* The order of these checks is highly relevant, as this will be the order /* The order of these checks is highly relevant, as this will be the order
of preference in case of the existence of multiple accepted types. */ of preference in case of the existence of multiple accepted types. */
if(avail & CURLAUTH_GSSNEGOTIATE) if(avail & CURLAUTH_NEGOTIATE)
pick->picked = CURLAUTH_GSSNEGOTIATE; pick->picked = CURLAUTH_NEGOTIATE;
else if(avail & CURLAUTH_DIGEST) else if(avail & CURLAUTH_DIGEST)
pick->picked = CURLAUTH_DIGEST; pick->picked = CURLAUTH_DIGEST;
else if(avail & CURLAUTH_NTLM) else if(avail & CURLAUTH_NTLM)
@@ -557,7 +557,7 @@ output_auth_headers(struct connectdata *conn,
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
const char *auth=NULL; const char *auth=NULL;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
#ifdef USE_HTTP_NEGOTIATE #ifdef USE_SPNEGO
struct negotiatedata *negdata = proxy? struct negotiatedata *negdata = proxy?
&data->state.proxyneg:&data->state.negotiate; &data->state.proxyneg:&data->state.negotiate;
#endif #endif
@@ -567,11 +567,11 @@ output_auth_headers(struct connectdata *conn,
(void)path; (void)path;
#endif #endif
#ifdef USE_HTTP_NEGOTIATE #ifdef USE_SPNEGO
negdata->state = GSS_AUTHNONE; negdata->state = GSS_AUTHNONE;
if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) && if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
negdata->context && !GSS_ERROR(negdata->status)) { negdata->context && !GSS_ERROR(negdata->status)) {
auth="GSS-Negotiate"; auth="Negotiate";
result = Curl_output_negotiate(conn, proxy); result = Curl_output_negotiate(conn, proxy);
if(result) if(result)
return result; return result;
@@ -737,6 +737,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
*/ */
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
#ifdef USE_SPNEGO
struct negotiatedata *negdata = proxy?
&data->state.proxyneg:&data->state.negotiate;
#endif
unsigned long *availp; unsigned long *availp;
struct auth *authp; struct auth *authp;
@@ -767,21 +771,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
*/ */
while(*auth) { while(*auth) {
#ifdef USE_HTTP_NEGOTIATE #ifdef USE_SPNEGO
if(checkprefix("GSS-Negotiate", auth) || if(checkprefix("Negotiate", auth)) {
checkprefix("Negotiate", auth)) {
int neg; int neg;
*availp |= CURLAUTH_GSSNEGOTIATE; *availp |= CURLAUTH_NEGOTIATE;
authp->avail |= CURLAUTH_GSSNEGOTIATE; authp->avail |= CURLAUTH_NEGOTIATE;
if(authp->picked == CURLAUTH_GSSNEGOTIATE) { if(authp->picked == CURLAUTH_NEGOTIATE) {
if(data->state.negotiate.state == GSS_AUTHSENT) { if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
/* if we sent GSS authentication in the outgoing request and we get
this back, we're in trouble */
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
else if(data->state.negotiate.state == GSS_AUTHNONE) {
neg = Curl_input_negotiate(conn, proxy, auth); neg = Curl_input_negotiate(conn, proxy, auth);
if(neg == 0) { if(neg == 0) {
DEBUGASSERT(!data->req.newurl); DEBUGASSERT(!data->req.newurl);
@@ -789,8 +786,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
if(!data->req.newurl) if(!data->req.newurl)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE; data->state.authproblem = FALSE;
/* we received GSS auth info and we dealt with it fine */ /* we received a GSS auth token and we dealt with it fine */
data->state.negotiate.state = GSS_AUTHRECV; negdata->state = GSS_AUTHRECV;
} }
else else
data->state.authproblem = TRUE; data->state.authproblem = TRUE;
@@ -923,14 +920,6 @@ static int http_should_fail(struct connectdata *conn)
if(httpcode < 400) if(httpcode < 400)
return 0; return 0;
if(data->state.resume_from &&
(data->set.httpreq==HTTPREQ_GET) &&
(httpcode == 416)) {
/* "Requested Range Not Satisfiable", just proceed and
pretend this is no error */
return 0;
}
/* /*
** Any code >= 400 that's not 401 or 407 is always ** Any code >= 400 that's not 401 or 407 is always
** a terminal error ** a terminal error
@@ -1443,6 +1432,12 @@ CURLcode Curl_http_done(struct connectdata *conn,
Curl_unencode_cleanup(conn); Curl_unencode_cleanup(conn);
#ifdef USE_SPNEGO
if(data->state.proxyneg.state == GSS_AUTHSENT ||
data->state.negotiate.state == GSS_AUTHSENT)
Curl_cleanup_negotiate(data);
#endif
/* set the proper values (possibly modified on POST) */ /* set the proper values (possibly modified on POST) */
conn->fread_func = data->set.fread_func; /* restore */ conn->fread_func = data->set.fread_func; /* restore */
conn->fread_in = data->set.in; /* restore */ conn->fread_in = data->set.in; /* restore */
@@ -1522,10 +1517,6 @@ static CURLcode expect100(struct SessionHandle *data,
const char *ptr; const char *ptr;
data->state.expect100header = FALSE; /* default to false unless it is set data->state.expect100header = FALSE; /* default to false unless it is set
to TRUE below */ to TRUE below */
if(conn->httpversion == 20) {
/* We don't use Expect in HTTP2 */
return CURLE_OK;
}
if(use_http_1_1plus(data, conn)) { if(use_http_1_1plus(data, conn)) {
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect: /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
100-continue to the headers which actually speeds up post operations 100-continue to the headers which actually speeds up post operations
@@ -1757,8 +1748,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result) if(result)
return result; return result;
/* TODO: add error checking here */ result = Curl_http2_switched(conn);
Curl_http2_switched(conn); if(result)
return result;
break; break;
case NPN_HTTP1_1: case NPN_HTTP1_1:
/* continue with HTTP/1.1 when explicitly requested */ /* continue with HTTP/1.1 when explicitly requested */
@@ -1770,7 +1762,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
} }
else { else {
/* prepare for a http2 request */ /* prepare for a http2 request */
Curl_http2_setup(conn); result = Curl_http2_setup(conn);
if(result)
return result;
} }
http = data->req.protop; http = data->req.protop;
@@ -2357,7 +2351,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result; return result;
http->postdata = NULL; /* nothing to post at this point */ http->postdata = NULL; /* nothing to post at this point */
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */ Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
/* If 'authdone' is FALSE, we must not set the write socket index to the /* If 'authdone' is FALSE, we must not set the write socket index to the
Curl_transfer() call below, as we're not ready to actually upload any Curl_transfer() call below, as we're not ready to actually upload any
@@ -3004,8 +2998,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
k->upgr101 = UPGR101_RECEIVED; k->upgr101 = UPGR101_RECEIVED;
/* switch to http2 now */ /* switch to http2 now */
/* TODO: add error checking */ result = Curl_http2_switched(conn);
Curl_http2_switched(conn); if(result)
return result;
} }
break; break;
default: default:
@@ -3536,24 +3531,31 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
/* Content-Range: bytes [num]- /* Content-Range: bytes [num]-
Content-Range: bytes: [num]- Content-Range: bytes: [num]-
Content-Range: [num]- Content-Range: [num]-
Content-Range: [asterisk]/[total]
The second format was added since Sun's webserver The second format was added since Sun's webserver
JavaWebServer/1.1.1 obviously sends the header this way! JavaWebServer/1.1.1 obviously sends the header this way!
The third added since some servers use that! The third added since some servers use that!
The forth means the requested range was unsatisfied.
*/ */
char *ptr = k->p + 14; char *ptr = k->p + 14;
/* Move forward until first digit */ /* Move forward until first digit or asterisk */
while(*ptr && !ISDIGIT(*ptr)) while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
ptr++; ptr++;
/* if it truly stopped on a digit */
if(ISDIGIT(*ptr)) {
k->offset = curlx_strtoofft(ptr, NULL, 10); k->offset = curlx_strtoofft(ptr, NULL, 10);
if(data->state.resume_from == k->offset) if(data->state.resume_from == k->offset)
/* we asked for a resume and we got it */ /* we asked for a resume and we got it */
k->content_range = TRUE; k->content_range = TRUE;
} }
else
data->state.resume_from = 0; /* get everything */
}
#if !defined(CURL_DISABLE_COOKIES) #if !defined(CURL_DISABLE_COOKIES)
else if(data->cookies && else if(data->cookies &&
checkprefix("Set-Cookie:", k->p)) { checkprefix("Set-Cookie:", k->p)) {

View File

@@ -169,7 +169,9 @@ struct http_conn {
sending send_underlying; /* underlying send Curl_send callback */ sending send_underlying; /* underlying send Curl_send callback */
recving recv_underlying; /* underlying recv Curl_recv callback */ recving recv_underlying; /* underlying recv Curl_recv callback */
bool closed; /* TRUE on HTTP2 stream close */ bool closed; /* TRUE on HTTP2 stream close */
Curl_send_buffer *header_recvbuf; /* store response headers */ Curl_send_buffer *header_recvbuf; /* store response headers. We
store non-final and final
response headers into it. */
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf size_t nread_header_recvbuf; /* number of bytes in header_recvbuf
fed into upper layer */ fed into upper layer */
int32_t stream_id; /* stream we are interested in */ int32_t stream_id; /* stream we are interested in */
@@ -185,6 +187,7 @@ struct http_conn {
const uint8_t *upload_mem; /* points to a buffer to read from */ const uint8_t *upload_mem; /* points to a buffer to read from */
size_t upload_len; /* size of the buffer 'upload_mem' points to */ size_t upload_len; /* size of the buffer 'upload_mem' points to */
size_t upload_left; /* number of bytes left to upload */ size_t upload_left; /* number of bytes left to upload */
int status_code; /* HTTP status code */
#else #else
int unused; /* prevent a compiler warning */ int unused; /* prevent a compiler warning */
#endif #endif

View File

@@ -39,7 +39,7 @@
/* include memdebug.h last */ /* include memdebug.h last */
#include "memdebug.h" #include "memdebug.h"
#if (NGHTTP2_VERSION_NUM < 0x000300) #if (NGHTTP2_VERSION_NUM < 0x000600)
#error too old nghttp2 version, upgrade! #error too old nghttp2 version, upgrade!
#endif #endif
@@ -191,27 +191,80 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
struct connectdata *conn = (struct connectdata *)userp; struct connectdata *conn = (struct connectdata *)userp;
struct http_conn *c = &conn->proto.httpc; struct http_conn *c = &conn->proto.httpc;
int rv; int rv;
size_t left, ncopy;
(void)session; (void)session;
(void)frame; (void)frame;
infof(conn->data, "on_frame_recv() was called with header %x\n", infof(conn->data, "on_frame_recv() was called with header %x\n",
frame->hd.type); frame->hd.type);
switch(frame->hd.type) { switch(frame->hd.type) {
case NGHTTP2_HEADERS: case NGHTTP2_DATA:
if(frame->headers.cat != NGHTTP2_HCAT_RESPONSE) /* If body started, then receiving DATA is illegal. */
if(!c->bodystarted) {
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
}
break; break;
case NGHTTP2_HEADERS:
if(frame->headers.cat == NGHTTP2_HCAT_REQUEST)
break;
if(c->bodystarted) {
/* Only valid HEADERS after body started is trailer header,
which is not fully supported in this code. If HEADERS is not
trailer, then it is a PROTOCOL_ERROR. */
if((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
}
break;
}
if(c->status_code == -1) {
/* No :status header field means PROTOCOL_ERROR. */
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
break;
}
/* Only final status code signals the end of header */
if(c->status_code / 100 != 1) {
c->bodystarted = TRUE; c->bodystarted = TRUE;
}
c->status_code = -1;
Curl_add_buffer(c->header_recvbuf, "\r\n", 2); Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
c->nread_header_recvbuf = c->len < c->header_recvbuf->size_used ?
c->len : c->header_recvbuf->size_used;
memcpy(c->mem, c->header_recvbuf->buffer, c->nread_header_recvbuf); left = c->header_recvbuf->size_used - c->nread_header_recvbuf;
ncopy = c->len < left ? c->len : left;
c->mem += c->nread_header_recvbuf; memcpy(c->mem, c->header_recvbuf->buffer + c->nread_header_recvbuf, ncopy);
c->len -= c->nread_header_recvbuf; c->nread_header_recvbuf += ncopy;
c->mem += ncopy;
c->len -= ncopy;
break; break;
case NGHTTP2_PUSH_PROMISE: case NGHTTP2_PUSH_PROMISE:
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id, NGHTTP2_CANCEL); frame->push_promise.promised_stream_id,
NGHTTP2_CANCEL);
if(nghttp2_is_fatal(rv)) { if(nghttp2_is_fatal(rv)) {
return rv; return rv;
} }
@@ -222,7 +275,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
static int on_invalid_frame_recv(nghttp2_session *session, static int on_invalid_frame_recv(nghttp2_session *session,
const nghttp2_frame *frame, const nghttp2_frame *frame,
nghttp2_error_code error_code, void *userp) uint32_t error_code, void *userp)
{ {
struct connectdata *conn = (struct connectdata *)userp; struct connectdata *conn = (struct connectdata *)userp;
(void)session; (void)session;
@@ -297,7 +350,7 @@ static int on_frame_not_send(nghttp2_session *session,
return 0; return 0;
} }
static int on_stream_close(nghttp2_session *session, int32_t stream_id, static int on_stream_close(nghttp2_session *session, int32_t stream_id,
nghttp2_error_code error_code, void *userp) uint32_t error_code, void *userp)
{ {
struct connectdata *conn = (struct connectdata *)userp; struct connectdata *conn = (struct connectdata *)userp;
struct http_conn *c = &conn->proto.httpc; struct http_conn *c = &conn->proto.httpc;
@@ -315,20 +368,6 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
return 0; return 0;
} }
static int on_unknown_frame_recv(nghttp2_session *session,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
void *userp)
{
struct connectdata *conn = (struct connectdata *)userp;
(void)session;
(void)head;
(void)headlen;
(void)payload;
(void)payloadlen;
infof(conn->data, "on_unknown_frame_recv() was called\n");
return 0;
}
static int on_begin_headers(nghttp2_session *session, static int on_begin_headers(nghttp2_session *session,
const nghttp2_frame *frame, void *userp) const nghttp2_frame *frame, void *userp)
{ {
@@ -339,6 +378,33 @@ static int on_begin_headers(nghttp2_session *session,
return 0; return 0;
} }
/* Decode HTTP status code. Returns -1 if no valid status code was
decoded. */
static int decode_status_code(const uint8_t *value, size_t len)
{
int i;
int res;
if(len != 3) {
return -1;
}
res = 0;
for(i = 0; i < 3; ++i) {
char c = value[i];
if(c < '0' || c > '9') {
return -1;
}
res *= 10;
res += c - '0';
}
return res;
}
static const char STATUS[] = ":status"; static const char STATUS[] = ":status";
/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */ /* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
@@ -350,6 +416,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
{ {
struct connectdata *conn = (struct connectdata *)userp; struct connectdata *conn = (struct connectdata *)userp;
struct http_conn *c = &conn->proto.httpc; struct http_conn *c = &conn->proto.httpc;
int rv;
int goodname;
int goodheader;
(void)session; (void)session;
(void)frame; (void)frame;
(void)flags; (void)flags;
@@ -358,45 +428,83 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
return 0; return 0;
} }
if(c->bodystarted) {
/* Ignore trailer or HEADERS not mapped to HTTP semantics. The
consequence is handled in on_frame_recv(). */
return 0;
}
goodname = nghttp2_check_header_name(name, namelen);
goodheader = nghttp2_check_header_value(value, valuelen);
if(!goodname || !goodheader) {
infof(conn->data, "Detected bad incoming header %s%s, reset stream!\n",
goodname?"":"name",
goodheader?"":"value");
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
if(namelen == sizeof(":status") - 1 && if(namelen == sizeof(":status") - 1 &&
memcmp(STATUS, name, namelen) == 0) { memcmp(STATUS, name, namelen) == 0) {
snprintf(c->header_recvbuf->buffer, 13, "HTTP/2.0 %s", value);
c->header_recvbuf->buffer[12] = '\r'; /* :status must appear exactly once. */
if(c->status_code != -1 ||
(c->status_code = decode_status_code(value, valuelen)) == -1) {
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
Curl_add_buffer(c->header_recvbuf, "HTTP/2.0 ", 9);
Curl_add_buffer(c->header_recvbuf, value, valuelen);
Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
return 0; return 0;
} }
else { else {
/* Here we are sure that namelen > 0 because of
nghttp2_check_header_name(). Pseudo header other than :status
is illegal. */
if(c->status_code == -1 || name[0] == ':') {
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
frame->hd.stream_id,
NGHTTP2_PROTOCOL_ERROR);
if(nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
/* convert to a HTTP1-style header */ /* convert to a HTTP1-style header */
infof(conn->data, "got header\n");
Curl_add_buffer(c->header_recvbuf, name, namelen); Curl_add_buffer(c->header_recvbuf, name, namelen);
Curl_add_buffer(c->header_recvbuf, ":", 1); Curl_add_buffer(c->header_recvbuf, ":", 1);
Curl_add_buffer(c->header_recvbuf, value, valuelen); Curl_add_buffer(c->header_recvbuf, value, valuelen);
Curl_add_buffer(c->header_recvbuf, "\r\n", 2); Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
infof(conn->data, "got http2 header: %.*s: %.*s\n",
namelen, name, valuelen, value);
} }
return 0; /* 0 is successful */ return 0; /* 0 is successful */
} }
/*
* This is all callbacks nghttp2 calls
*/
static const nghttp2_session_callbacks callbacks = {
send_callback, /* nghttp2_send_callback */
NULL, /* nghttp2_recv_callback */
on_frame_recv, /* nghttp2_on_frame_recv_callback */
on_invalid_frame_recv, /* nghttp2_on_invalid_frame_recv_callback */
on_data_chunk_recv, /* nghttp2_on_data_chunk_recv_callback */
before_frame_send, /* nghttp2_before_frame_send_callback */
on_frame_send, /* nghttp2_on_frame_send_callback */
on_frame_not_send, /* nghttp2_on_frame_not_send_callback */
on_stream_close, /* nghttp2_on_stream_close_callback */
on_unknown_frame_recv, /* nghttp2_on_unknown_frame_recv_callback */
on_begin_headers, /* nghttp2_on_begin_headers_callback */
on_header /* nghttp2_on_header_callback */
#if NGHTTP2_VERSION_NUM >= 0x000400
, NULL /* nghttp2_select_padding_callback */
#endif
};
static ssize_t data_source_read_callback(nghttp2_session *session, static ssize_t data_source_read_callback(nghttp2_session *session,
int32_t stream_id, int32_t stream_id,
uint8_t *buf, size_t length, uint8_t *buf, size_t length,
@@ -444,13 +552,54 @@ CURLcode Curl_http2_init(struct connectdata *conn)
{ {
if(!conn->proto.httpc.h2) { if(!conn->proto.httpc.h2) {
int rc; int rc;
nghttp2_session_callbacks *callbacks;
conn->proto.httpc.inbuf = malloc(H2_BUFSIZE); conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
if(conn->proto.httpc.inbuf == NULL) if(conn->proto.httpc.inbuf == NULL)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
rc = nghttp2_session_callbacks_new(&callbacks);
if(rc) {
failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
return CURLE_OUT_OF_MEMORY; /* most likely at least */
}
/* nghttp2_send_callback */
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
/* nghttp2_on_frame_recv_callback */
nghttp2_session_callbacks_set_on_frame_recv_callback
(callbacks, on_frame_recv);
/* nghttp2_on_invalid_frame_recv_callback */
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
(callbacks, on_invalid_frame_recv);
/* nghttp2_on_data_chunk_recv_callback */
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
(callbacks, on_data_chunk_recv);
/* nghttp2_before_frame_send_callback */
nghttp2_session_callbacks_set_before_frame_send_callback
(callbacks, before_frame_send);
/* nghttp2_on_frame_send_callback */
nghttp2_session_callbacks_set_on_frame_send_callback
(callbacks, on_frame_send);
/* nghttp2_on_frame_not_send_callback */
nghttp2_session_callbacks_set_on_frame_not_send_callback
(callbacks, on_frame_not_send);
/* nghttp2_on_stream_close_callback */
nghttp2_session_callbacks_set_on_stream_close_callback
(callbacks, on_stream_close);
/* nghttp2_on_begin_headers_callback */
nghttp2_session_callbacks_set_on_begin_headers_callback
(callbacks, on_begin_headers);
/* nghttp2_on_header_callback */
nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
/* The nghttp2 session is not yet setup, do it */ /* The nghttp2 session is not yet setup, do it */
rc = nghttp2_session_client_new(&conn->proto.httpc.h2, rc = nghttp2_session_client_new(&conn->proto.httpc.h2,
&callbacks, conn); callbacks, conn);
nghttp2_session_callbacks_del(callbacks);
if(rc) { if(rc) {
failf(conn->data, "Couldn't initialize nghttp2!"); failf(conn->data, "Couldn't initialize nghttp2!");
return CURLE_OUT_OF_MEMORY; /* most likely at least */ return CURLE_OUT_OF_MEMORY; /* most likely at least */
@@ -504,7 +653,7 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
} }
conn->proto.httpc.binlen = binlen; conn->proto.httpc.binlen = binlen;
result = Curl_base64_encode(conn->data, (const char *)binsettings, binlen, result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
&base64, &blen); &base64, &blen);
if(result) if(result)
return result; return result;
@@ -536,6 +685,9 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
(void)sockindex; /* we always do HTTP2 on sockindex 0 */ (void)sockindex; /* we always do HTTP2 on sockindex 0 */
if(httpc->closed) { if(httpc->closed) {
/* Reset to FALSE to prevent infinite loop in readwrite_data
function. */
httpc->closed = FALSE;
return 0; return 0;
} }
@@ -615,12 +767,19 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
/* If stream is closed, return 0 to signal the http routine to close /* If stream is closed, return 0 to signal the http routine to close
the connection */ the connection */
if(httpc->closed) { if(httpc->closed) {
/* Reset to FALSE to prevent infinite loop in readwrite_data
function. */
httpc->closed = FALSE;
return 0; return 0;
} }
*err = CURLE_AGAIN; *err = CURLE_AGAIN;
return -1; return -1;
} }
/* Index where :authority header field will appear in request header
field list. */
#define AUTHORITY_DST_IDX 3
/* return number of received (decrypted) bytes */ /* return number of received (decrypted) bytes */
static ssize_t http2_send(struct connectdata *conn, int sockindex, static ssize_t http2_send(struct connectdata *conn, int sockindex,
const void *mem, size_t len, CURLcode *err) const void *mem, size_t len, CURLcode *err)
@@ -635,6 +794,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
nghttp2_nv *nva; nghttp2_nv *nva;
size_t nheader; size_t nheader;
size_t i; size_t i;
size_t authority_idx;
char *hdbuf = (char*)mem; char *hdbuf = (char*)mem;
char *end; char *end;
nghttp2_data_provider data_prd; nghttp2_data_provider data_prd;
@@ -705,10 +865,13 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
hdbuf = strchr(hdbuf, 0x0a); hdbuf = strchr(hdbuf, 0x0a);
++hdbuf; ++hdbuf;
authority_idx = 0;
for(i = 3; i < nheader; ++i) { for(i = 3; i < nheader; ++i) {
end = strchr(hdbuf, ':'); end = strchr(hdbuf, ':');
assert(end); assert(end);
if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) { if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
authority_idx = i;
nva[i].name = (unsigned char *)":authority"; nva[i].name = (unsigned char *)":authority";
nva[i].namelen = (uint16_t)strlen((char *)nva[i].name); nva[i].namelen = (uint16_t)strlen((char *)nva[i].name);
} }
@@ -739,6 +902,15 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
} }
} }
/* :authority must come before non-pseudo header fields */
if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
nghttp2_nv authority = nva[authority_idx];
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
nva[i] = nva[i - 1];
}
nva[i] = authority;
}
switch(conn->data->set.httpreq) { switch(conn->data->set.httpreq) {
case HTTPREQ_POST: case HTTPREQ_POST:
case HTTPREQ_POST_FORM: case HTTPREQ_POST_FORM:
@@ -803,19 +975,19 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
httpc->upload_mem = NULL; httpc->upload_mem = NULL;
httpc->upload_len = 0; httpc->upload_len = 0;
httpc->stream_id = -1; httpc->stream_id = -1;
httpc->status_code = -1;
conn->httpversion = 20; conn->httpversion = 20;
/* Put place holder for status line */ return 0;
return Curl_add_buffer(httpc->header_recvbuf, "HTTP/2.0 200\r\n", 14);
} }
int Curl_http2_switched(struct connectdata *conn) CURLcode Curl_http2_switched(struct connectdata *conn)
{ {
/* TODO: May get CURLE_AGAIN */
CURLcode rc; CURLcode rc;
struct http_conn *httpc = &conn->proto.httpc; struct http_conn *httpc = &conn->proto.httpc;
int rv; int rv;
struct SessionHandle *data = conn->data;
httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET]; httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
httpc->send_underlying = (sending)conn->send[FIRSTSOCKET]; httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
@@ -827,7 +999,15 @@ int Curl_http2_switched(struct connectdata *conn)
NGHTTP2_CLIENT_CONNECTION_PREFACE, NGHTTP2_CLIENT_CONNECTION_PREFACE,
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN, NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN,
&rc); &rc);
assert(rv == 24); if(rc)
/* TODO: This may get CURLE_AGAIN */
return rc;
if(rv != 24) {
failf(data, "Only sent partial HTTP2 packet");
return CURLE_SEND_ERROR;
}
if(conn->data->req.upgr101 == UPGR101_RECEIVED) { if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
/* stream 1 is opened implicitly on upgrade */ /* stream 1 is opened implicitly on upgrade */
httpc->stream_id = 1; httpc->stream_id = 1;
@@ -835,9 +1015,9 @@ int Curl_http2_switched(struct connectdata *conn)
rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings, rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
httpc->binlen, NULL); httpc->binlen, NULL);
if(rv != 0) { if(rv != 0) {
failf(conn->data, "nghttp2_session_upgrade() failed: %s(%d)", failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
nghttp2_strerror(rv), rv); nghttp2_strerror(rv), rv);
return -1; return CURLE_HTTP2;
} }
} }
else { else {
@@ -845,12 +1025,12 @@ int Curl_http2_switched(struct connectdata *conn)
httpc->stream_id = -1; httpc->stream_id = -1;
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0); rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
if(rv != 0) { if(rv != 0) {
failf(conn->data, "nghttp2_submit_settings() failed: %s(%d)", failf(data, "nghttp2_submit_settings() failed: %s(%d)",
nghttp2_strerror(rv), rv); nghttp2_strerror(rv), rv);
return -1; return CURLE_HTTP2;
} }
} }
return 0; return CURLE_OK;
} }
#endif #endif

View File

@@ -37,13 +37,13 @@ CURLcode Curl_http2_send_request(struct connectdata *conn);
CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
struct connectdata *conn); struct connectdata *conn);
CURLcode Curl_http2_setup(struct connectdata *conn); CURLcode Curl_http2_setup(struct connectdata *conn);
int Curl_http2_switched(struct connectdata *conn); CURLcode Curl_http2_switched(struct connectdata *conn);
#else /* USE_NGHTTP2 */ #else /* USE_NGHTTP2 */
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
#define Curl_http2_switched(x) (-1) #define Curl_http2_switched(x) CURLE_UNSUPPORTED_PROTOCOL
#endif #endif
#endif /* HEADER_CURL_HTTP2_H */ #endif /* HEADER_CURL_HTTP2_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -39,19 +39,6 @@
#include "curl_memory.h" #include "curl_memory.h"
#include "url.h" #include "url.h"
#ifdef HAVE_SPNEGO
# include <spnegohelp.h>
# ifdef USE_SSLEAY
# ifdef USE_OPENSSL
# include <openssl/objects.h>
# else
# include <objects.h>
# endif
# else
# error "Can't compile SPNEGO support without OpenSSL."
# endif
#endif
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@@ -61,24 +48,10 @@
static int static int
get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server) get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
{ {
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
&conn->data->state.negotiate;
OM_uint32 major_status, minor_status; OM_uint32 major_status, minor_status;
gss_buffer_desc token = GSS_C_EMPTY_BUFFER; gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
char name[2048]; char name[2048];
const char* service; const char* service = "HTTP";
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
Change following lines if you want to use GSI */
/* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
if(neg_ctx->gss)
service = "KHTTP";
else
service = "HTTP";
token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name : token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
conn->host.name) + 1; conn->host.name) + 1;
@@ -141,31 +114,8 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
int ret; int ret;
size_t len; size_t len;
size_t rawlen = 0; size_t rawlen = 0;
bool gss;
const char* protocol;
CURLcode error; CURLcode error;
if(checkprefix("GSS-Negotiate", header)) {
protocol = "GSS-Negotiate";
gss = TRUE;
}
else if(checkprefix("Negotiate", header)) {
protocol = "Negotiate";
gss = FALSE;
}
else
return -1;
if(neg_ctx->context) {
if(neg_ctx->gss != gss) {
return -1;
}
}
else {
neg_ctx->protocol = protocol;
neg_ctx->gss = gss;
}
if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) { if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
/* We finished successfully our part of authentication, but server /* We finished successfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we * rejected it (since we're again here). Exit with an error since we
@@ -178,7 +128,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
(ret = get_gss_name(conn, proxy, &neg_ctx->server_name))) (ret = get_gss_name(conn, proxy, &neg_ctx->server_name)))
return ret; return ret;
header += strlen(neg_ctx->protocol); header += strlen("Negotiate");
while(*header && ISSPACE(*header)) while(*header && ISSPACE(*header))
header++; header++;
@@ -191,59 +141,13 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
input_token.length = rawlen; input_token.length = rawlen;
DEBUGASSERT(input_token.value != NULL); DEBUGASSERT(input_token.value != NULL);
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
if(checkprefix("Negotiate", header)) {
unsigned char *spnegoToken = NULL;
size_t spnegoTokenLength = 0;
gss_buffer_desc mechToken = GSS_C_EMPTY_BUFFER;
spnegoToken = malloc(input_token.length);
if(spnegoToken == NULL) {
Curl_safefree(input_token.value);
return CURLE_OUT_OF_MEMORY;
}
memcpy(spnegoToken, input_token.value, input_token.length);
spnegoTokenLength = input_token.length;
if(!parseSpnegoTargetToken(spnegoToken,
spnegoTokenLength,
NULL,
NULL,
(unsigned char**)&mechToken.value,
&mechToken.length,
NULL,
NULL)) {
Curl_safefree(spnegoToken);
infof(data, "Parse SPNEGO Target Token failed\n");
}
else if(!mechToken.value || !mechToken.length) {
Curl_safefree(spnegoToken);
if(mechToken.value)
gss_release_buffer(&discard_st, &mechToken);
infof(data, "Parse SPNEGO Target Token succeeded (NULL token)\n");
}
else {
Curl_safefree(spnegoToken);
Curl_safefree(input_token.value);
input_token.value = malloc(mechToken.length);
if(input_token.value == NULL) {
gss_release_buffer(&discard_st, &mechToken);
return CURLE_OUT_OF_MEMORY;
}
memcpy(input_token.value, mechToken.value, mechToken.length);
input_token.length = mechToken.length;
gss_release_buffer(&discard_st, &mechToken);
infof(data, "Parse SPNEGO Target Token succeeded\n");
}
}
#endif
} }
major_status = Curl_gss_init_sec_context(data, major_status = Curl_gss_init_sec_context(data,
&minor_status, &minor_status,
&neg_ctx->context, &neg_ctx->context,
neg_ctx->server_name, neg_ctx->server_name,
&Curl_spnego_mech_oid,
GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_CHANNEL_BINDINGS,
&input_token, &input_token,
&output_token, &output_token,
@@ -279,52 +183,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
CURLcode error; CURLcode error;
OM_uint32 discard_st; OM_uint32 discard_st;
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
if(checkprefix("Negotiate", neg_ctx->protocol)) {
ASN1_OBJECT *object = NULL;
unsigned char *responseToken = NULL;
size_t responseTokenLength = 0;
gss_buffer_desc spnegoToken = GSS_C_EMPTY_BUFFER;
responseToken = malloc(neg_ctx->output_token.length);
if(responseToken == NULL)
return CURLE_OUT_OF_MEMORY;
memcpy(responseToken, neg_ctx->output_token.value,
neg_ctx->output_token.length);
responseTokenLength = neg_ctx->output_token.length;
object = OBJ_txt2obj("1.2.840.113554.1.2.2", 1);
if(!object) {
Curl_safefree(responseToken);
return CURLE_OUT_OF_MEMORY;
}
if(!makeSpnegoInitialToken(object,
responseToken,
responseTokenLength,
(unsigned char**)&spnegoToken.value,
&spnegoToken.length)) {
Curl_safefree(responseToken);
ASN1_OBJECT_free(object);
infof(conn->data, "Make SPNEGO Initial Token failed\n");
}
else if(!spnegoToken.value || !spnegoToken.length) {
Curl_safefree(responseToken);
ASN1_OBJECT_free(object);
if(spnegoToken.value)
gss_release_buffer(&discard_st, &spnegoToken);
infof(conn->data, "Make SPNEGO Initial Token succeeded (NULL token)\n");
}
else {
Curl_safefree(responseToken);
ASN1_OBJECT_free(object);
gss_release_buffer(&discard_st, &neg_ctx->output_token);
neg_ctx->output_token.value = spnegoToken.value;
neg_ctx->output_token.length = spnegoToken.length;
infof(conn->data, "Make SPNEGO Initial Token succeeded\n");
}
}
#endif
error = Curl_base64_encode(conn->data, error = Curl_base64_encode(conn->data,
neg_ctx->output_token.value, neg_ctx->output_token.value,
neg_ctx->output_token.length, neg_ctx->output_token.length,
@@ -343,8 +201,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
return CURLE_REMOTE_ACCESS_DENIED; return CURLE_REMOTE_ACCESS_DENIED;
} }
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
neg_ctx->protocol, encoded); encoded);
if(proxy) { if(proxy) {
Curl_safefree(conn->allocptr.proxyuserpwd); Curl_safefree(conn->allocptr.proxyuserpwd);
conn->allocptr.proxyuserpwd = userp; conn->allocptr.proxyuserpwd = userp;
@@ -355,7 +213,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
} }
Curl_safefree(encoded); Curl_safefree(encoded);
Curl_cleanup_negotiate(conn->data);
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
} }

View File

@@ -22,7 +22,7 @@
* *
***************************************************************************/ ***************************************************************************/
#ifdef USE_HTTP_NEGOTIATE #ifdef USE_SPNEGO
/* this is for Negotiate header input */ /* this is for Negotiate header input */
int Curl_input_negotiate(struct connectdata *conn, bool proxy, int Curl_input_negotiate(struct connectdata *conn, bool proxy,
@@ -37,6 +37,6 @@ void Curl_cleanup_negotiate(struct SessionHandle *data);
#define GSS_ERROR(status) (status & 0x80000000) #define GSS_ERROR(status) (status & 0x80000000)
#endif #endif
#endif /* USE_HTTP_NEGOTIATE */ #endif /* USE_SPNEGO */
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */ #endif /* HEADER_CURL_HTTP_NEGOTIATE_H */

View File

@@ -24,13 +24,14 @@
#ifdef USE_WINDOWS_SSPI #ifdef USE_WINDOWS_SSPI
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP_NEGOTIATE) #if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
#include "urldata.h" #include "urldata.h"
#include "sendf.h" #include "sendf.h"
#include "rawstr.h" #include "rawstr.h"
#include "warnless.h" #include "warnless.h"
#include "curl_base64.h" #include "curl_base64.h"
#include "curl_sasl.h"
#include "http_negotiate.h" #include "http_negotiate.h"
#include "curl_memory.h" #include "curl_memory.h"
#include "curl_multibyte.h" #include "curl_multibyte.h"
@@ -41,84 +42,47 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
static int
get_gss_name(struct connectdata *conn, bool proxy,
struct negotiatedata *neg_ctx)
{
const char* service;
size_t length;
if(proxy && !conn->proxy.name)
/* proxy auth requested but no given proxy name, error out! */
return -1;
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
Change following lines if you want to use GSI */
/* IIS uses the <service>@<fqdn> form but uses 'http' as the service name,
and SSPI then generates an NTLM token. When using <service>/<fqdn> a
Kerberos token is generated. */
if(neg_ctx->gss)
service = "KHTTP";
else
service = "HTTP";
length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
conn->host.name) + 1;
if(length + 1 > sizeof(neg_ctx->server_name))
return EMSGSIZE;
snprintf(neg_ctx->server_name, sizeof(neg_ctx->server_name), "%s/%s",
service, proxy ? conn->proxy.name : conn->host.name);
return 0;
}
/* returning zero (0) means success, everything else is treated as "failure" /* returning zero (0) means success, everything else is treated as "failure"
with no care exactly what the failure was */ with no care exactly what the failure was */
int Curl_input_negotiate(struct connectdata *conn, bool proxy, int Curl_input_negotiate(struct connectdata *conn, bool proxy,
const char *header) const char *header)
{ {
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg: BYTE *input_token = NULL;
&conn->data->state.negotiate;
BYTE *input_token = 0;
SecBufferDesc out_buff_desc; SecBufferDesc out_buff_desc;
SecBuffer out_sec_buff; SecBuffer out_sec_buff;
SecBufferDesc in_buff_desc; SecBufferDesc in_buff_desc;
SecBuffer in_sec_buff; SecBuffer in_sec_buff;
unsigned long context_attributes; unsigned long context_attributes;
TimeStamp lifetime; TimeStamp lifetime;
TCHAR *sname;
int ret; int ret;
size_t len = 0, input_token_len = 0; size_t len = 0, input_token_len = 0;
bool gss = FALSE;
const char* protocol;
CURLcode error; CURLcode error;
if(checkprefix("GSS-Negotiate", header)) { /* Point to the username and password */
protocol = "GSS-Negotiate"; const char *userp;
gss = TRUE; const char *passwdp;
}
else if(checkprefix("Negotiate", header)) {
protocol = "Negotiate";
gss = FALSE;
}
else
return -1;
if(neg_ctx->context) { /* Point to the correct struct with this */
if(neg_ctx->gss != gss) { struct negotiatedata *neg_ctx;
return -1;
} if(proxy) {
userp = conn->proxyuser;
passwdp = conn->proxypasswd;
neg_ctx = &conn->data->state.proxyneg;
} }
else { else {
neg_ctx->protocol = protocol; userp = conn->user;
neg_ctx->gss = gss; passwdp = conn->passwd;
neg_ctx = &conn->data->state.negotiate;
} }
/* Not set means empty */
if(!userp)
userp = "";
if(!passwdp)
passwdp = "";
if(neg_ctx->context && neg_ctx->status == SEC_E_OK) { if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
/* We finished successfully our part of authentication, but server /* We finished successfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we * rejected it (since we're again here). Exit with an error since we
@@ -127,10 +91,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
return -1; return -1;
} }
if(0 == strlen(neg_ctx->server_name)) { if(!neg_ctx->server_name) {
ret = get_gss_name(conn, proxy, neg_ctx); /* Check proxy auth requested but no given proxy name */
if(ret) if(proxy && !conn->proxy.name)
return ret; return -1;
/* Generate our SPN */
neg_ctx->server_name = Curl_sasl_build_spn("HTTP",
proxy ? conn->proxy.name :
conn->host.name);
if(!neg_ctx->server_name)
return -1;
} }
if(!neg_ctx->output_token) { if(!neg_ctx->output_token) {
@@ -148,81 +119,91 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
} }
/* Obtain the input token, if any */ /* Obtain the input token, if any */
header += strlen(neg_ctx->protocol); header += strlen("Negotiate");
while(*header && ISSPACE(*header)) while(*header && ISSPACE(*header))
header++; header++;
len = strlen(header); len = strlen(header);
if(!len) { if(!len) {
/* first call in a new negotation, we have to acquire credentials, /* Is this the first call in a new negotiation? */
and allocate memory for the context */ if(neg_ctx->context) {
/* The server rejected our authentication and hasn't suppled any more
negotiation mechanisms */
return -1;
}
/* We have to acquire credentials and allocate memory for the context */
neg_ctx->credentials = malloc(sizeof(CredHandle)); neg_ctx->credentials = malloc(sizeof(CredHandle));
neg_ctx->context = malloc(sizeof(CtxtHandle)); neg_ctx->context = malloc(sizeof(CtxtHandle));
if(!neg_ctx->credentials || !neg_ctx->context) if(!neg_ctx->credentials || !neg_ctx->context)
return -1; return -1;
if(userp && *userp) {
/* Populate our identity structure */
error = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
if(error)
return -1;
/* Allow proper cleanup of the identity structure */
neg_ctx->p_identity = &neg_ctx->identity;
}
else
/* Use the current Windows user */
neg_ctx->p_identity = NULL;
/* Acquire our credientials handle */
neg_ctx->status = neg_ctx->status =
s_pSecFn->AcquireCredentialsHandle(NULL, s_pSecFn->AcquireCredentialsHandle(NULL,
(TCHAR *) TEXT("Negotiate"), (TCHAR *) TEXT("Negotiate"),
SECPKG_CRED_OUTBOUND, NULL, NULL, SECPKG_CRED_OUTBOUND, NULL,
NULL, NULL, neg_ctx->credentials, neg_ctx->p_identity, NULL, NULL,
&lifetime); neg_ctx->credentials, &lifetime);
if(neg_ctx->status != SEC_E_OK) if(neg_ctx->status != SEC_E_OK)
return -1; return -1;
} }
else { else {
input_token = malloc(neg_ctx->max_token_length);
if(!input_token)
return -1;
error = Curl_base64_decode(header, error = Curl_base64_decode(header,
(unsigned char **)&input_token, (unsigned char **)&input_token,
&input_token_len); &input_token_len);
if(error || input_token_len == 0) if(error || !input_token_len)
return -1; return -1;
} }
/* prepare the output buffers, and input buffers if present */ /* Setup the "output" security buffer */
out_buff_desc.ulVersion = 0; out_buff_desc.ulVersion = SECBUFFER_VERSION;
out_buff_desc.cBuffers = 1; out_buff_desc.cBuffers = 1;
out_buff_desc.pBuffers = &out_sec_buff; out_buff_desc.pBuffers = &out_sec_buff;
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
out_sec_buff.BufferType = SECBUFFER_TOKEN; out_sec_buff.BufferType = SECBUFFER_TOKEN;
out_sec_buff.pvBuffer = neg_ctx->output_token; out_sec_buff.pvBuffer = neg_ctx->output_token;
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
/* Setup the "input" security buffer if present */
if(input_token) { if(input_token) {
in_buff_desc.ulVersion = 0; in_buff_desc.ulVersion = SECBUFFER_VERSION;
in_buff_desc.cBuffers = 1; in_buff_desc.cBuffers = 1;
in_buff_desc.pBuffers = &in_sec_buff; in_buff_desc.pBuffers = &in_sec_buff;
in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
in_sec_buff.BufferType = SECBUFFER_TOKEN; in_sec_buff.BufferType = SECBUFFER_TOKEN;
in_sec_buff.pvBuffer = input_token; in_sec_buff.pvBuffer = input_token;
in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
} }
sname = Curl_convert_UTF8_to_tchar(neg_ctx->server_name); /* Generate our message */
if(!sname)
return CURLE_OUT_OF_MEMORY;
neg_ctx->status = s_pSecFn->InitializeSecurityContext( neg_ctx->status = s_pSecFn->InitializeSecurityContext(
neg_ctx->credentials, neg_ctx->credentials,
input_token ? neg_ctx->context : 0, input_token ? neg_ctx->context : NULL,
sname, neg_ctx->server_name,
ISC_REQ_CONFIDENTIALITY, ISC_REQ_CONFIDENTIALITY,
0, 0,
SECURITY_NATIVE_DREP, SECURITY_NATIVE_DREP,
input_token ? &in_buff_desc : 0, input_token ? &in_buff_desc : NULL,
0, 0,
neg_ctx->context, neg_ctx->context,
&out_buff_desc, &out_buff_desc,
&context_attributes, &context_attributes,
&lifetime); &lifetime);
Curl_unicodefree(sname); Curl_safefree(input_token);
if(GSS_ERROR(neg_ctx->status)) if(GSS_ERROR(neg_ctx->status))
return -1; return -1;
@@ -257,18 +238,21 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
if(error) if(error)
return error; return error;
if(len == 0) if(!len)
return CURLE_REMOTE_ACCESS_DENIED; return CURLE_REMOTE_ACCESS_DENIED;
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
neg_ctx->protocol, encoded); encoded);
if(proxy) if(proxy) {
Curl_safefree(conn->allocptr.proxyuserpwd);
conn->allocptr.proxyuserpwd = userp; conn->allocptr.proxyuserpwd = userp;
else }
else {
Curl_safefree(conn->allocptr.userpwd);
conn->allocptr.userpwd = userp; conn->allocptr.userpwd = userp;
}
free(encoded); free(encoded);
Curl_cleanup_negotiate (conn->data);
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
} }
@@ -277,21 +261,22 @@ static void cleanup(struct negotiatedata *neg_ctx)
if(neg_ctx->context) { if(neg_ctx->context) {
s_pSecFn->DeleteSecurityContext(neg_ctx->context); s_pSecFn->DeleteSecurityContext(neg_ctx->context);
free(neg_ctx->context); free(neg_ctx->context);
neg_ctx->context = 0; neg_ctx->context = NULL;
} }
if(neg_ctx->credentials) { if(neg_ctx->credentials) {
s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials); s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
free(neg_ctx->credentials); free(neg_ctx->credentials);
neg_ctx->credentials = 0; neg_ctx->credentials = NULL;
}
if(neg_ctx->output_token) {
free(neg_ctx->output_token);
neg_ctx->output_token = 0;
} }
neg_ctx->max_token_length = 0; neg_ctx->max_token_length = 0;
Curl_safefree(neg_ctx->output_token);
Curl_safefree(neg_ctx->server_name);
Curl_sspi_free_identity(neg_ctx->p_identity);
neg_ctx->p_identity = NULL;
} }
void Curl_cleanup_negotiate(struct SessionHandle *data) void Curl_cleanup_negotiate(struct SessionHandle *data)
@@ -300,6 +285,6 @@ void Curl_cleanup_negotiate(struct SessionHandle *data)
cleanup(&data->state.proxyneg); cleanup(&data->state.proxyneg);
} }
#endif /* !CURL_DISABLE_HTTP && USE_HTTP_NEGOTIATE */ #endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
#endif /* USE_WINDOWS_SSPI */ #endif /* USE_WINDOWS_SSPI */

View File

@@ -98,8 +98,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
struct SingleRequest *k = &data->req; struct SingleRequest *k = &data->req;
CURLcode result; CURLcode result;
long timeout =
data->set.timeout?data->set.timeout:PROXY_TIMEOUT; /* in milliseconds */
curl_socket_t tunnelsocket = conn->sock[sockindex]; curl_socket_t tunnelsocket = conn->sock[sockindex];
curl_off_t cl=0; curl_off_t cl=0;
bool closeConnection = FALSE; bool closeConnection = FALSE;
@@ -223,14 +221,25 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
return result; return result;
conn->tunnel_state[sockindex] = TUNNEL_CONNECT; conn->tunnel_state[sockindex] = TUNNEL_CONNECT;
/* now we've issued the CONNECT and we're waiting to hear back, return
and get called again polling-style */
return CURLE_OK;
} /* END CONNECT PHASE */ } /* END CONNECT PHASE */
{ /* BEGIN NEGOTIATION PHASE */ check = Curl_timeleft(data, NULL, TRUE);
if(check <= 0) {
failf(data, "Proxy CONNECT aborted due to timeout");
return CURLE_RECV_ERROR;
}
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
/* return so we'll be called again polling-style */
return CURLE_OK;
else {
DEBUGF(infof(data,
"Read response immediately from proxy CONNECT\n"));
}
/* at this point, the tunnel_connecting phase is over. */
{ /* READING RESPONSE PHASE */
size_t nread; /* total size read */ size_t nread; /* total size read */
int perline; /* count bytes per line */ int perline; /* count bytes per line */
int keepon=TRUE; int keepon=TRUE;
@@ -247,9 +256,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
while((nread<BUFSIZE) && (keepon && !error)) { while((nread<BUFSIZE) && (keepon && !error)) {
/* if timeout is requested, find out how much remaining time we have */ check = Curl_timeleft(data, NULL, TRUE);
check = timeout - /* timeout time */
Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
if(check <= 0) { if(check <= 0) {
failf(data, "Proxy CONNECT aborted due to timeout"); failf(data, "Proxy CONNECT aborted due to timeout");
error = SELECT_TIMEOUT; /* already too little time */ error = SELECT_TIMEOUT; /* already too little time */
@@ -279,6 +286,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
/* proxy auth was requested and there was proxy auth available, /* proxy auth was requested and there was proxy auth available,
then deem this as "mere" proxy disconnect */ then deem this as "mere" proxy disconnect */
conn->bits.proxy_connect_closed = TRUE; conn->bits.proxy_connect_closed = TRUE;
infof(data, "Proxy CONNECT connection closed");
} }
else { else {
error = SELECT_ERROR; error = SELECT_ERROR;
@@ -527,7 +535,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
conn->sock[sockindex] = CURL_SOCKET_BAD; conn->sock[sockindex] = CURL_SOCKET_BAD;
break; break;
} }
} /* END NEGOTIATION PHASE */ } /* END READING RESPONSE PHASE */
/* If we are supposed to continue and request a new URL, which basically /* If we are supposed to continue and request a new URL, which basically
* means the HTTP authentication is still going on so if the tunnel * means the HTTP authentication is still going on so if the tunnel
@@ -542,23 +550,34 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
} while(data->req.newurl); } while(data->req.newurl);
if(200 != data->req.httpcode) { if(200 != data->req.httpcode) {
failf(data, "Received HTTP code %d from proxy after CONNECT", if(closeConnection && data->req.newurl) {
data->req.httpcode);
if(closeConnection && data->req.newurl)
conn->bits.proxy_connect_closed = TRUE; conn->bits.proxy_connect_closed = TRUE;
infof(data, "Connect me again please\n");
}
else {
if(data->req.newurl) { if(data->req.newurl) {
/* this won't be used anymore for the CONNECT so free it now */ /* this won't be used anymore for the CONNECT so free it now */
free(data->req.newurl); free(data->req.newurl);
data->req.newurl = NULL; data->req.newurl = NULL;
} }
/* failure, close this connection to avoid re-use */
connclose(conn, "proxy CONNECT failure");
Curl_closesocket(conn, conn->sock[sockindex]);
conn->sock[sockindex] = CURL_SOCKET_BAD;
}
/* to back to init state */ /* to back to init state */
conn->tunnel_state[sockindex] = TUNNEL_INIT; conn->tunnel_state[sockindex] = TUNNEL_INIT;
if(conn->bits.proxy_connect_closed)
/* this is not an error, just part of the connection negotiation */
return CURLE_OK;
else {
failf(data, "Received HTTP code %d from proxy after CONNECT",
data->req.httpcode);
return CURLE_RECV_ERROR; return CURLE_RECV_ERROR;
} }
}
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE; conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;

View File

@@ -24,6 +24,7 @@
* RFC3501 IMAPv4 protocol * RFC3501 IMAPv4 protocol
* RFC4422 Simple Authentication and Security Layer (SASL) * RFC4422 Simple Authentication and Security Layer (SASL)
* RFC4616 PLAIN authentication * RFC4616 PLAIN authentication
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
* RFC4959 IMAP Extension for SASL Initial Client Response * RFC4959 IMAP Extension for SASL Initial Client Response
* RFC5092 IMAP URL Scheme * RFC5092 IMAP URL Scheme
* RFC6749 OAuth 2.0 Authorization Framework * RFC6749 OAuth 2.0 Authorization Framework
@@ -433,6 +434,9 @@ static void state(struct connectdata *conn, imapstate newstate)
"AUTHENTICATE_DIGESTMD5_RESP", "AUTHENTICATE_DIGESTMD5_RESP",
"AUTHENTICATE_NTLM", "AUTHENTICATE_NTLM",
"AUTHENTICATE_NTLM_TYPE2MSG", "AUTHENTICATE_NTLM_TYPE2MSG",
"AUTHENTICATE_GSSAPI",
"AUTHENTICATE_GSSAPI_TOKEN",
"AUTHENTICATE_GSSAPI_NO_DATA",
"AUTHENTICATE_XOAUTH2", "AUTHENTICATE_XOAUTH2",
"AUTHENTICATE_CANCEL", "AUTHENTICATE_CANCEL",
"AUTHENTICATE_FINAL", "AUTHENTICATE_FINAL",
@@ -1296,6 +1300,158 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
} }
#endif #endif
#if defined(USE_WINDOWS_SSPI)
/* For AUTHENTICATE GSSAPI (without initial response) responses */
static CURLcode imap_state_auth_gssapi_resp(struct connectdata *conn,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
size_t len = 0;
char *respmsg = NULL;
(void)instate; /* no use for this yet */
if(imapcode != '+') {
failf(data, "Access denied: %d", imapcode);
result = CURLE_LOGIN_DENIED;
}
else {
/* Create the initial response message */
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
conn->passwd, "imap",
imapc->mutual_auth,
NULL, &conn->krb5,
&respmsg, &len);
if(!result && respmsg) {
/* Send the message */
result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
if(!result)
state(conn, IMAP_AUTHENTICATE_GSSAPI_TOKEN);
}
}
Curl_safefree(respmsg);
return result;
}
/* For AUTHENTICATE GSSAPI user token responses */
static CURLcode imap_state_auth_gssapi_token_resp(struct connectdata *conn,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
char *chlgmsg = NULL;
char *respmsg = NULL;
size_t len = 0;
(void)instate; /* no use for this yet */
if(imapcode != '+') {
failf(data, "Access denied: %d", imapcode);
result = CURLE_LOGIN_DENIED;
}
else {
/* Get the challenge message */
imap_get_message(data->state.buffer, &chlgmsg);
if(imapc->mutual_auth)
/* Decode the user token challenge and create the optional response
message */
result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
imapc->mutual_auth,
chlgmsg, &conn->krb5,
&respmsg, &len);
else
/* Decode the security challenge and create the response message */
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
&conn->krb5,
&respmsg, &len);
if(result) {
if(result == CURLE_BAD_CONTENT_ENCODING) {
/* Send the cancellation */
result = Curl_pp_sendf(&imapc->pp, "%s", "*");
if(!result)
state(conn, IMAP_AUTHENTICATE_CANCEL);
}
}
else {
/* Send the response */
if(respmsg)
result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
else
result = Curl_pp_sendf(&imapc->pp, "%s", "");
if(!result)
state(conn, (imapc->mutual_auth ? IMAP_AUTHENTICATE_GSSAPI_NO_DATA :
IMAP_AUTHENTICATE_FINAL));
}
}
Curl_safefree(respmsg);
return result;
}
/* For AUTHENTICATE GSSAPI no data responses */
static CURLcode imap_state_auth_gssapi_no_data_resp(struct connectdata *conn,
int imapcode,
imapstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlgmsg = NULL;
char *respmsg = NULL;
size_t len = 0;
(void)instate; /* no use for this yet */
if(imapcode != '+') {
failf(data, "Access denied: %d", imapcode);
result = CURLE_LOGIN_DENIED;
}
else {
/* Get the challenge message */
imap_get_message(data->state.buffer, &chlgmsg);
/* Decode the security challenge and create the response message */
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
&conn->krb5,
&respmsg, &len);
if(result) {
if(result == CURLE_BAD_CONTENT_ENCODING) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
if(!result)
state(conn, IMAP_AUTHENTICATE_CANCEL);
}
}
else {
/* Send the response */
if(respmsg) {
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", respmsg);
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
}
}
}
Curl_safefree(respmsg);
return result;
}
#endif
/* For AUTHENTICATE XOAUTH2 (without initial response) responses */ /* For AUTHENTICATE XOAUTH2 (without initial response) responses */
static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn, static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
int imapcode, int imapcode,
@@ -1506,7 +1662,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
(void)instate; /* no use for this yet */ (void)instate; /* no use for this yet */
if(imapcode != '*') { if(imapcode != '*') {
Curl_pgrsSetDownloadSize(data, 0); Curl_pgrsSetDownloadSize(data, -1);
state(conn, IMAP_STOP); state(conn, IMAP_STOP);
return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */ return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
} }
@@ -1755,6 +1911,21 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
break; break;
#endif #endif
#if defined(USE_WINDOWS_SSPI)
case IMAP_AUTHENTICATE_GSSAPI:
result = imap_state_auth_gssapi_resp(conn, imapcode, imapc->state);
break;
case IMAP_AUTHENTICATE_GSSAPI_TOKEN:
result = imap_state_auth_gssapi_token_resp(conn, imapcode, imapc->state);
break;
case IMAP_AUTHENTICATE_GSSAPI_NO_DATA:
result = imap_state_auth_gssapi_no_data_resp(conn, imapcode,
imapc->state);
break;
#endif
case IMAP_AUTHENTICATE_XOAUTH2: case IMAP_AUTHENTICATE_XOAUTH2:
result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state); result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
break; break;
@@ -2165,8 +2336,8 @@ static CURLcode imap_regular_transfer(struct connectdata *conn,
/* Set the progress data */ /* Set the progress data */
Curl_pgrsSetUploadCounter(data, 0); Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0); Curl_pgrsSetDownloadCounter(data, 0);
Curl_pgrsSetUploadSize(data, 0); Curl_pgrsSetUploadSize(data, -1);
Curl_pgrsSetDownloadSize(data, 0); Curl_pgrsSetDownloadSize(data, -1);
/* Carry out the perform */ /* Carry out the perform */
result = imap_perform(conn, &connected, dophase_done); result = imap_perform(conn, &connected, dophase_done);
@@ -2632,6 +2803,25 @@ static CURLcode imap_calc_sasl_details(struct connectdata *conn,
/* Calculate the supported authentication mechanism, by decreasing order of /* Calculate the supported authentication mechanism, by decreasing order of
security, as well as the initial response where appropriate */ security, as well as the initial response where appropriate */
#if defined(USE_WINDOWS_SSPI)
if((imapc->authmechs & SASL_MECH_GSSAPI) &&
(imapc->prefmech & SASL_MECH_GSSAPI)) {
imapc->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
*mech = SASL_MECH_STRING_GSSAPI;
*state1 = IMAP_AUTHENTICATE_GSSAPI;
*state2 = IMAP_AUTHENTICATE_GSSAPI_TOKEN;
imapc->authused = SASL_MECH_GSSAPI;
if(imapc->ir_supported || data->set.sasl_ir)
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
conn->passwd, "imap",
imapc->mutual_auth,
NULL, &conn->krb5,
initresp, len);
}
else
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH #ifndef CURL_DISABLE_CRYPTO_AUTH
if((imapc->authmechs & SASL_MECH_DIGEST_MD5) && if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
(imapc->prefmech & SASL_MECH_DIGEST_MD5)) { (imapc->prefmech & SASL_MECH_DIGEST_MD5)) {

View File

@@ -43,6 +43,9 @@ typedef enum {
IMAP_AUTHENTICATE_DIGESTMD5_RESP, IMAP_AUTHENTICATE_DIGESTMD5_RESP,
IMAP_AUTHENTICATE_NTLM, IMAP_AUTHENTICATE_NTLM,
IMAP_AUTHENTICATE_NTLM_TYPE2MSG, IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
IMAP_AUTHENTICATE_GSSAPI,
IMAP_AUTHENTICATE_GSSAPI_TOKEN,
IMAP_AUTHENTICATE_GSSAPI_NO_DATA,
IMAP_AUTHENTICATE_XOAUTH2, IMAP_AUTHENTICATE_XOAUTH2,
IMAP_AUTHENTICATE_CANCEL, IMAP_AUTHENTICATE_CANCEL,
IMAP_AUTHENTICATE_FINAL, IMAP_AUTHENTICATE_FINAL,
@@ -89,6 +92,7 @@ struct imap_conn {
bool tls_supported; /* StartTLS capability supported by server */ bool tls_supported; /* StartTLS capability supported by server */
bool login_disabled; /* LOGIN command disabled by server */ bool login_disabled; /* LOGIN command disabled by server */
bool ir_supported; /* Initial response supported by server */ bool ir_supported; /* Initial response supported by server */
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
char *mailbox; /* The last selected mailbox */ char *mailbox; /* The last selected mailbox */
char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */ char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */
}; };

View File

@@ -236,6 +236,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
&min, &min,
context, context,
gssname, gssname,
&Curl_krb5_mech_oid,
&chan, &chan,
gssresp, gssresp,
&output_buffer, &output_buffer,

View File

@@ -40,17 +40,15 @@ use Text::Wrap;
my %urls = ( my %urls = (
'nss' => 'nss' =>
'http://mxr.mozilla.org/nss/source/lib/ckfw/builtins/certdata.txt?raw=1', 'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
'central' => 'central' =>
'http://mxr.mozilla.org/mozilla-central/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1', 'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'aurora' => 'aurora' =>
'http://mxr.mozilla.org/mozilla-aurora/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1', 'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'beta' => 'beta' =>
'http://mxr.mozilla.org/mozilla-beta/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1', 'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'release' => 'release' =>
'http://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1', 'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
'mozilla' =>
'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1'
); );
$opt_d = 'release'; $opt_d = 'release';
@@ -58,7 +56,7 @@ $opt_d = 'release';
# If the OpenSSL commandline is not in search path you can configure it here! # If the OpenSSL commandline is not in search path you can configure it here!
my $openssl = 'openssl'; my $openssl = 'openssl';
my $version = '1.21'; my $version = '1.22';
$opt_w = 76; # default base64 encoded lines length $opt_w = 76; # default base64 encoded lines length
@@ -209,6 +207,28 @@ sub PARSE_CSV_PARAM($$@) {
return @values; return @values;
} }
sub sha1 {
my ($txt)=@_;
my $sha1 = `$openssl dgst -sha1 $txt | cut '-d ' -f2`;
chomp $sha1;
return $sha1;
}
sub oldsha1 {
my ($crt)=@_;
my $sha1="";
open(C, "<$crt");
while(<C>) {
chomp;
if($_ =~ /^\#\# SHA1: (.*)/) {
$sha1 = $1;
last;
}
}
close(C);
return $sha1;
}
if ( $opt_p !~ m/:/ ) { if ( $opt_p !~ m/:/ ) {
print "Error: Mozilla trust identifier list must include both purposes and levels\n"; print "Error: Mozilla trust identifier list must include both purposes and levels\n";
HELP_MESSAGE(); HELP_MESSAGE();
@@ -238,6 +258,10 @@ my $stdout = $crt eq '-';
my $resp; my $resp;
my $fetched; my $fetched;
my $oldsha1= oldsha1($crt);
print STDERR "SHA1 of old file: $oldsha1\n";
unless ($opt_n and -e $txt) { unless ($opt_n and -e $txt) {
print STDERR "Downloading '$txt' ...\n" if (!$opt_q); print STDERR "Downloading '$txt' ...\n" if (!$opt_q);
my $ua = new LWP::UserAgent(agent => "$0/$version"); my $ua = new LWP::UserAgent(agent => "$0/$version");
@@ -257,7 +281,25 @@ unless ($opt_n and -e $txt) {
} }
} }
my $currentdate = scalar gmtime($fetched ? $resp->last_modified : (stat($txt))[9]); my $filedate = $fetched ? $resp->last_modified : (stat($txt))[9];
my $datesrc = "as of";
if(!$filedate) {
# mxr.mozilla.org gave us a time, hg.mozilla.org does not!
$filedate = time();
$datesrc="downloaded on";
}
# get the hash from the download file
my $newsha1= sha1($txt);
if($oldsha1 eq $newsha1) {
print STDERR "Downloaded file identical to previous run\'s source file. Exiting\n";
exit;
}
print STDERR "SHA1 of new file: $newsha1\n";
my $currentdate = scalar gmtime($filedate);
my $format = $opt_t ? "plain text and " : ""; my $format = $opt_t ? "plain text and " : "";
if( $stdout ) { if( $stdout ) {
@@ -267,9 +309,9 @@ if( $stdout ) {
} }
print CRT <<EOT; print CRT <<EOT;
## ##
## $crt -- Bundle of CA Root Certificates ## Bundle of CA Root Certificates
## ##
## Certificate data from Mozilla as of: ${currentdate} ## Certificate data from Mozilla ${datesrc}: ${currentdate}
## ##
## This is a bundle of X.509 certificates of public Certificate Authorities ## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates ## (CA). These were automatically extracted from Mozilla's root certificates
@@ -281,6 +323,9 @@ print CRT <<EOT;
## an Apache+mod_ssl webserver for SSL client authentication. ## an Apache+mod_ssl webserver for SSL client authentication.
## Just configure this file as the SSLCACertificateFile. ## Just configure this file as the SSLCACertificateFile.
## ##
## Conversion done with mk-ca-bundle.pl verison $version.
## SHA1: $newsha1
##
EOT EOT
@@ -415,7 +460,3 @@ unless( $stdout ) {
} }
unlink $txt if ($opt_u); unlink $txt if ($opt_u);
print STDERR "Done ($certnum CA certs processed, $skipnum skipped).\n" if (!$opt_q); print STDERR "Done ($certnum CA certs processed, $skipnum skipped).\n" if (!$opt_q);
exit;

View File

@@ -30,6 +30,7 @@
#include "connect.h" #include "connect.h"
#include "progress.h" #include "progress.h"
#include "easyif.h" #include "easyif.h"
#include "share.h"
#include "multiif.h" #include "multiif.h"
#include "sendf.h" #include "sendf.h"
#include "timeval.h" #include "timeval.h"
@@ -308,6 +309,10 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
if(!multi->msglist) if(!multi->msglist)
goto error; goto error;
multi->pending = Curl_llist_alloc(multi_freeamsg);
if(!multi->pending)
goto error;
/* allocate a new easy handle to use when closing cached connections */ /* allocate a new easy handle to use when closing cached connections */
multi->closure_handle = curl_easy_init(); multi->closure_handle = curl_easy_init();
if(!multi->closure_handle) if(!multi->closure_handle)
@@ -333,6 +338,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
Curl_close(multi->closure_handle); Curl_close(multi->closure_handle);
multi->closure_handle = NULL; multi->closure_handle = NULL;
Curl_llist_destroy(multi->msglist, NULL); Curl_llist_destroy(multi->msglist, NULL);
Curl_llist_destroy(multi->pending, NULL);
free(multi); free(multi);
return NULL; return NULL;
@@ -1045,6 +1051,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* There was no connection available. We will go to the pending /* There was no connection available. We will go to the pending
state and wait for an available connection. */ state and wait for an available connection. */
multistate(data, CURLM_STATE_CONNECT_PEND); multistate(data, CURLM_STATE_CONNECT_PEND);
/* add this handle to the list of connect-pending handles */
if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
data->result = CURLE_OUT_OF_MEMORY;
else
data->result = CURLE_OK; data->result = CURLE_OK;
break; break;
} }
@@ -1084,8 +1095,31 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* awaiting an asynch name resolve to complete */ /* awaiting an asynch name resolve to complete */
{ {
struct Curl_dns_entry *dns = NULL; struct Curl_dns_entry *dns = NULL;
struct connectdata *conn = data->easy_conn;
int stale;
/* check if we have the name resolved by now */ /* check if we have the name resolved by now */
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port, &stale);
if(dns) {
dns->inuse++; /* we use it! */
#ifdef CURLRES_ASYNCH
conn->async.dns = dns;
conn->async.done = TRUE;
#endif
data->result = CURLRESOLV_RESOLVED;
infof(data, "Hostname was found in DNS cache\n");
}
if(stale)
infof(data, "Hostname in DNS cache was stale, zapped\n");
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
if(!dns)
data->result = Curl_resolver_is_resolved(data->easy_conn, &dns); data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
/* Update sockets here, because the socket(s) may have been /* Update sockets here, because the socket(s) may have been
@@ -1137,11 +1171,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->result = Curl_http_connect(data->easy_conn, &protocol_connect); data->result = Curl_http_connect(data->easy_conn, &protocol_connect);
if(data->easy_conn->bits.proxy_connect_closed) { if(data->easy_conn->bits.proxy_connect_closed) {
/* reset the error buffer */ /* connect back to proxy again */
if(data->set.errorbuffer)
data->set.errorbuffer[0] = '\0';
data->state.errorbuf = FALSE;
data->result = CURLE_OK; data->result = CURLE_OK;
result = CURLM_CALL_MULTI_PERFORM; result = CURLM_CALL_MULTI_PERFORM;
multistate(data, CURLM_STATE_CONNECT); multistate(data, CURLM_STATE_CONNECT);
@@ -1167,7 +1197,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
&protocol_connect); &protocol_connect);
} }
if(CURLE_OK != data->result) { if(data->easy_conn->bits.proxy_connect_closed) {
/* connect back to proxy again since it was closed in a proxy CONNECT
setup */
data->result = CURLE_OK;
result = CURLM_CALL_MULTI_PERFORM;
multistate(data, CURLM_STATE_CONNECT);
break;
}
else if(CURLE_OK != data->result) {
/* failure detected */ /* failure detected */
/* Just break, the cleaning up is handled all in one place */ /* Just break, the cleaning up is handled all in one place */
disconnect_conn = TRUE; disconnect_conn = TRUE;
@@ -1463,7 +1501,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->set.buffer_size : BUFSIZE); data->set.buffer_size : BUFSIZE);
timeout_ms = Curl_sleep_time(data->set.max_send_speed, timeout_ms = Curl_sleep_time(data->set.max_send_speed,
data->progress.ulspeed, buffersize); data->progress.ulspeed, buffersize);
Curl_expire(data, timeout_ms); Curl_expire_latest(data, timeout_ms);
break; break;
} }
@@ -1479,7 +1517,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
data->set.buffer_size : BUFSIZE); data->set.buffer_size : BUFSIZE);
timeout_ms = Curl_sleep_time(data->set.max_recv_speed, timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
data->progress.dlspeed, buffersize); data->progress.dlspeed, buffersize);
Curl_expire(data, timeout_ms); Curl_expire_latest(data, timeout_ms);
break; break;
} }
@@ -1541,7 +1579,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* expire the new receiving pipeline head */ /* expire the new receiving pipeline head */
if(data->easy_conn->recv_pipe->head) if(data->easy_conn->recv_pipe->head)
Curl_expire(data->easy_conn->recv_pipe->head->ptr, 1); Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
/* Check if we can move pending requests to send pipe */ /* Check if we can move pending requests to send pipe */
Curl_multi_process_pending_handles(multi); Curl_multi_process_pending_handles(multi);
@@ -1843,18 +1881,12 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
multi->closure_handle->dns.hostcache); multi->closure_handle->dns.hostcache);
Curl_close(multi->closure_handle); Curl_close(multi->closure_handle);
multi->closure_handle = NULL;
} }
Curl_hash_destroy(multi->sockhash); Curl_hash_destroy(multi->sockhash);
multi->sockhash = NULL;
Curl_conncache_destroy(multi->conn_cache); Curl_conncache_destroy(multi->conn_cache);
multi->conn_cache = NULL;
/* remove the pending list of messages */
Curl_llist_destroy(multi->msglist, NULL); Curl_llist_destroy(multi->msglist, NULL);
multi->msglist = NULL; Curl_llist_destroy(multi->pending, NULL);
/* remove all easy handles */ /* remove all easy handles */
data = multi->easyp; data = multi->easyp;
@@ -1875,7 +1907,6 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
} }
Curl_hash_destroy(multi->hostcache); Curl_hash_destroy(multi->hostcache);
multi->hostcache = NULL;
/* Free the blacklists by setting them to NULL */ /* Free the blacklists by setting them to NULL */
Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl); Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
@@ -2654,6 +2685,46 @@ void Curl_expire(struct SessionHandle *data, long milli)
#endif #endif
} }
/*
* Curl_expire_latest()
*
* This is like Curl_expire() but will only add a timeout node to the list of
* timers if there is no timeout that will expire before the given time.
*
* Use this function if the code logic risks calling this function many times
* or if there's no particular conditional wait in the code for this specific
* time-out period to expire.
*
*/
void Curl_expire_latest(struct SessionHandle *data, long milli)
{
struct timeval *exp = &data->state.expiretime;
struct timeval set;
set = Curl_tvnow();
set.tv_sec += milli/1000;
set.tv_usec += (milli%1000)*1000;
if(set.tv_usec >= 1000000) {
set.tv_sec++;
set.tv_usec -= 1000000;
}
if(exp->tv_sec || exp->tv_usec) {
/* This means that the struct is added as a node in the splay tree.
Compare if the new time is earlier, and only remove-old/add-new if it
is. */
long diff = curlx_tvdiff(set, *exp);
if(diff > 0)
/* the new expire time was later than the top time, so just skip this */
return;
}
/* Just add the timeout like normal */
Curl_expire(data, milli);
}
CURLMcode curl_multi_assign(CURLM *multi_handle, CURLMcode curl_multi_assign(CURLM *multi_handle,
curl_socket_t s, void *hashp) curl_socket_t s, void *hashp)
{ {
@@ -2708,16 +2779,23 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
void Curl_multi_process_pending_handles(struct Curl_multi *multi) void Curl_multi_process_pending_handles(struct Curl_multi *multi)
{ {
struct SessionHandle *data; struct curl_llist_element *e = multi->pending->head;
while(e) {
struct SessionHandle *data = e->ptr;
struct curl_llist_element *next = e->next;
data=multi->easyp;
while(data) {
if(data->mstate == CURLM_STATE_CONNECT_PEND) { if(data->mstate == CURLM_STATE_CONNECT_PEND) {
multistate(data, CURLM_STATE_CONNECT); multistate(data, CURLM_STATE_CONNECT);
/* Remove this node from the list */
Curl_llist_remove(multi->pending, e, NULL);
/* Make sure that the handle will be processed soonish. */ /* Make sure that the handle will be processed soonish. */
Curl_expire(data, 1); Curl_expire_latest(data, 1);
} }
data = data->next; /* operate on next handle */
e = next; /* operate on next handle */
} }
} }

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -75,6 +75,9 @@ struct Curl_multi {
struct curl_llist *msglist; /* a list of messages from completed transfers */ struct curl_llist *msglist; /* a list of messages from completed transfers */
struct curl_llist *pending; /* SessionHandles that are in the
CURLM_STATE_CONNECT_PEND state */
/* callback function and user data pointer for the *socket() API */ /* callback function and user data pointer for the *socket() API */
curl_socket_callback socket_cb; curl_socket_callback socket_cb;
void *socket_userp; void *socket_userp;

View File

@@ -26,6 +26,7 @@
* Prototypes for library-wide functions provided by multi.c * Prototypes for library-wide functions provided by multi.c
*/ */
void Curl_expire(struct SessionHandle *data, long milli); void Curl_expire(struct SessionHandle *data, long milli);
void Curl_expire_latest(struct SessionHandle *data, long milli);
bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi); bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi);
void Curl_multi_handlePipeBreak(struct SessionHandle *data); void Curl_multi_handlePipeBreak(struct SessionHandle *data);

View File

@@ -530,8 +530,10 @@ static int parsedate(const char *date, time_t *output)
/* Add the time zone diff between local time zone and GMT. */ /* Add the time zone diff between local time zone and GMT. */
long delta = (long)(tzoff!=-1?tzoff:0); long delta = (long)(tzoff!=-1?tzoff:0);
if((delta>0) && (t > LONG_MAX - delta)) if((delta>0) && (t > LONG_MAX - delta)) {
return -1; /* time_t overflow */ *output = 0x7fffffff;
return PARSEDATE_LATER; /* time_t overflow */
}
t += delta; t += delta;
} }
@@ -561,9 +563,6 @@ time_t curl_getdate(const char *p, const time_t *now)
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
* gmtime_r() or gmtime() functions anywhere else but here. * gmtime_r() or gmtime() functions anywhere else but here.
* *
* To make sure no such function calls slip in, we define them to cause build
* errors, which is why we use the name within parentheses in this function.
*
*/ */
CURLcode Curl_gmtime(time_t intime, struct tm *store) CURLcode Curl_gmtime(time_t intime, struct tm *store)

View File

@@ -27,6 +27,7 @@
* RFC2831 DIGEST-MD5 authentication * RFC2831 DIGEST-MD5 authentication
* RFC4422 Simple Authentication and Security Layer (SASL) * RFC4422 Simple Authentication and Security Layer (SASL)
* RFC4616 PLAIN authentication * RFC4616 PLAIN authentication
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
* RFC5034 POP3 SASL Authentication Mechanism * RFC5034 POP3 SASL Authentication Mechanism
* RFC6749 OAuth 2.0 Authorization Framework * RFC6749 OAuth 2.0 Authorization Framework
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt> * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
@@ -320,6 +321,9 @@ static void state(struct connectdata *conn, pop3state newstate)
"AUTH_DIGESTMD5_RESP", "AUTH_DIGESTMD5_RESP",
"AUTH_NTLM", "AUTH_NTLM",
"AUTH_NTLM_TYPE2MSG", "AUTH_NTLM_TYPE2MSG",
"AUTH_GSSAPI",
"AUTH_GSSAPI_TOKEN",
"AUTH_GSSAPI_NO_DATA",
"AUTH_XOAUTH2", "AUTH_XOAUTH2",
"AUTH_CANCEL", "AUTH_CANCEL",
"AUTH_FINAL", "AUTH_FINAL",
@@ -1127,6 +1131,158 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
} }
#endif #endif
#if defined(USE_WINDOWS_SSPI)
/* For AUTH GSSAPI (without initial response) responses */
static CURLcode pop3_state_auth_gssapi_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct pop3_conn *pop3c = &conn->proto.pop3c;
size_t len = 0;
char *respmsg = NULL;
(void)instate; /* no use for this yet */
if(pop3code != '+') {
failf(data, "Access denied: %d", pop3code);
result = CURLE_LOGIN_DENIED;
}
else {
/* Create the initial response message */
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
conn->passwd, "pop",
pop3c->mutual_auth,
NULL, &conn->krb5,
&respmsg, &len);
if(!result && respmsg) {
/* Send the message */
result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
if(!result)
state(conn, POP3_AUTH_GSSAPI_TOKEN);
}
}
Curl_safefree(respmsg);
return result;
}
/* For AUTH GSSAPI user token responses */
static CURLcode pop3_state_auth_gssapi_token_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct pop3_conn *pop3c = &conn->proto.pop3c;
char *chlgmsg = NULL;
char *respmsg = NULL;
size_t len = 0;
(void)instate; /* no use for this yet */
if(pop3code != '+') {
failf(data, "Access denied: %d", pop3code);
result = CURLE_LOGIN_DENIED;
}
else {
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlgmsg);
if(pop3c->mutual_auth)
/* Decode the user token challenge and create the optional response
message */
result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
pop3c->mutual_auth,
chlgmsg, &conn->krb5,
&respmsg, &len);
else
/* Decode the security challenge and create the response message */
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
&conn->krb5,
&respmsg, &len);
if(result) {
if(result == CURLE_BAD_CONTENT_ENCODING) {
/* Send the cancellation */
result = Curl_pp_sendf(&pop3c->pp, "%s", "*");
if(!result)
state(conn, POP3_AUTH_CANCEL);
}
}
else {
/* Send the response */
if(respmsg)
result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
else
result = Curl_pp_sendf(&pop3c->pp, "%s", "");
if(!result)
state(conn, (pop3c->mutual_auth ? POP3_AUTH_GSSAPI_NO_DATA :
POP3_AUTH_FINAL));
}
}
Curl_safefree(respmsg);
return result;
}
/* For AUTH GSSAPI no data responses */
static CURLcode pop3_state_auth_gssapi_no_data_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
char *chlgmsg = NULL;
char *respmsg = NULL;
size_t len = 0;
(void)instate; /* no use for this yet */
if(pop3code != '+') {
failf(data, "Access denied: %d", pop3code);
result = CURLE_LOGIN_DENIED;
}
else {
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlgmsg);
/* Decode the security challenge and create the security message */
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
&conn->krb5,
&respmsg, &len);
if(result) {
if(result == CURLE_BAD_CONTENT_ENCODING) {
/* Send the cancellation */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
if(!result)
state(conn, POP3_AUTH_CANCEL);
}
}
else {
/* Send the response */
if(respmsg) {
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", respmsg);
if(!result)
state(conn, POP3_AUTH_FINAL);
}
}
}
Curl_safefree(respmsg);
return result;
}
#endif
/* For AUTH XOAUTH2 (without initial response) responses */ /* For AUTH XOAUTH2 (without initial response) responses */
static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn, static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn,
int pop3code, pop3state instate) int pop3code, pop3state instate)
@@ -1435,6 +1591,21 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
break; break;
#endif #endif
#if defined(USE_WINDOWS_SSPI)
case POP3_AUTH_GSSAPI:
result = pop3_state_auth_gssapi_resp(conn, pop3code, pop3c->state);
break;
case POP3_AUTH_GSSAPI_TOKEN:
result = pop3_state_auth_gssapi_token_resp(conn, pop3code, pop3c->state);
break;
case POP3_AUTH_GSSAPI_NO_DATA:
result = pop3_state_auth_gssapi_no_data_resp(conn, pop3code,
pop3c->state);
break;
#endif
case POP3_AUTH_XOAUTH2: case POP3_AUTH_XOAUTH2:
result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state); result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
break; break;
@@ -1764,8 +1935,8 @@ static CURLcode pop3_regular_transfer(struct connectdata *conn,
/* Set the progress data */ /* Set the progress data */
Curl_pgrsSetUploadCounter(data, 0); Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0); Curl_pgrsSetDownloadCounter(data, 0);
Curl_pgrsSetUploadSize(data, 0); Curl_pgrsSetUploadSize(data, -1);
Curl_pgrsSetDownloadSize(data, 0); Curl_pgrsSetDownloadSize(data, -1);
/* Carry out the perform */ /* Carry out the perform */
result = pop3_perform(conn, &connected, dophase_done); result = pop3_perform(conn, &connected, dophase_done);
@@ -1950,6 +2121,25 @@ static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
/* Calculate the supported authentication mechanism, by decreasing order of /* Calculate the supported authentication mechanism, by decreasing order of
security, as well as the initial response where appropriate */ security, as well as the initial response where appropriate */
#if defined(USE_WINDOWS_SSPI)
if((pop3c->authmechs & SASL_MECH_GSSAPI) &&
(pop3c->prefmech & SASL_MECH_GSSAPI)) {
pop3c->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
*mech = SASL_MECH_STRING_GSSAPI;
*state1 = POP3_AUTH_GSSAPI;
*state2 = POP3_AUTH_GSSAPI_TOKEN;
pop3c->authused = SASL_MECH_GSSAPI;
if(data->set.sasl_ir)
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
conn->passwd, "pop",
pop3c->mutual_auth,
NULL, &conn->krb5,
initresp, len);
}
else
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH #ifndef CURL_DISABLE_CRYPTO_AUTH
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) && if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
(pop3c->prefmech & SASL_MECH_DIGEST_MD5)) { (pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {

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