Compare commits

..

209 Commits

Author SHA1 Message Date
Daniel Stenberg
a8e063b087 RELEASE-NOTES: synced with 70f71bb99f
Synced and prepared for 7.24.0 release. Two security problems, one bug fix,
two more contributors.
2012-01-24 09:24:37 +01:00
Daniel Stenberg
70f71bb99f gnutls: enforced use of SSLv3
With advice from Nikos Mavrogiannopoulos, changed the priority string to
add "actual priorities" and favour ARCFOUR. This makes libcurl work
better when enforcing SSLv3 with GnuTLS. Both in the sense that the
libmicrohttpd test is now working again but also that it mitigates a
weakness in the older SSL/TLS protocols.

Bug: http://curl.haxx.se/mail/lib-2012-01/0225.html
Reported by: Christian Grothoff
2012-01-24 08:54:26 +01:00
Daniel Stenberg
c11c30a8c8 tests: test CRLF in URLs
Related to the security vulnerability: CVE-2012-0036

Bug: http://curl.haxx.se/docs/adv_20120124.html
2012-01-24 08:54:26 +01:00
Daniel Stenberg
75ca568fa1 URL sanitize: reject URLs containing bad data
Protocols (IMAP, POP3 and SMTP) that use the path part of a URL in a
decoded manner now use the new Curl_urldecode() function to reject URLs
with embedded control codes (anything that is or decodes to a byte value
less than 32).

URLs containing such codes could easily otherwise be used to do harm and
allow users to do unintended actions with otherwise innocent tools and
applications. Like for example using a URL like
pop3://pop3.example.com/1%0d%0aDELE%201 when the app wants a URL to get
a mail and instead this would delete one.

This flaw is considered a security vulnerability: CVE-2012-0036

Security advisory at: http://curl.haxx.se/docs/adv_20120124.html

Reported by: Dan Fandrich
2012-01-24 08:54:26 +01:00
Daniel Stenberg
db1a856b4f OpenSSL: don't disable security work-around
OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
(http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit
to SSL_OP_ALL that _disables_ that work-around despite the fact that
SSL_OP_ALL is documented to do "rather harmless" workarounds.

The libcurl code uses the SSL_OP_ALL define and thus logically always
disables the OpenSSL fix.

In order to keep the secure work-around workding, the
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit must not be set and this change
makes sure of this.

Reported by: product-security at Apple
2012-01-24 08:54:26 +01:00
Daniel Stenberg
ee57e9dea6 RELEASE-NOTES: synced with 6e2fd2c9ea
3 more bugfixes, 3 more contributors
2012-01-22 23:44:51 +01:00
Daniel Stenberg
6e2fd2c9ea CURLOPT_ACCEPTTIMEOUT_MS: spellfix 2012-01-22 00:00:55 +01:00
Dan Fandrich
5d7a319a55 examples: updated README with two new example programs 2012-01-20 22:44:59 -08:00
Daniel Stenberg
7883cd5af3 URL parse: user name with ipv6 numerical address
Using a URL with embedded user name and password didn't work if the host
was given as a numerical IPv6 string, like ftp://user:password@[::1]/

Reported by: Brandon Wang
Bug: http://curl.haxx.se/mail/archive-2012-01/0047.html
2012-01-20 23:32:43 +01:00
Yang Tse
d7af7de5b2 telnet.c: fix OOM triggered segfault 2012-01-20 00:11:15 +01:00
Yang Tse
a7e8f4aabc testtrace.c: fix compiler warning 2012-01-19 22:54:57 +01:00
Yang Tse
e64d332e79 OpenSSL: follow-up for commit a20daf90e3
avoid checking preprocessor definition official value
2012-01-19 22:29:00 +01:00
Pierre Joye
00e615de7e - s, use, enable, for options name, avoiding conflicts with the names used in the makefile 2012-01-19 14:08:24 +01:00
Daniel Stenberg
b2aaf3c2ad curl.1: improve --stderr wording
As is pointed out in this bug report, there can indeed be situation
where --stderr has a point even when the "real" stderr can be
redirected. Remove the superfluous and wrong comment.

bug: http://curl.haxx.se/bug/view.cgi?id=3476020
2012-01-19 13:42:56 +01:00
Daniel Stenberg
c41f304c43 KNOWN_BUGS: can't receive zero bytes file properly
http://curl.haxx.se/bug/view.cgi?id=3438362
2012-01-18 23:45:09 +01:00
Yang Tse
d56b4c3f89 ssl session caching: fix compiler warnings 2012-01-18 23:42:39 +01:00
Daniel Stenberg
d1becc3231 polarssl: show cipher suite name correctly with 1.1.0
Apparently ssl_get_ciphersuite() is needed to get the name of the used
cipher suite.
2012-01-18 23:19:37 +01:00
Daniel Stenberg
f55f95d49c polarssl: show error code correctly
The value was turned negative when it shouldn't have been
2012-01-18 23:19:01 +01:00
Daniel Stenberg
61d31a3caf polarssl: havege_rand is not present in version 1.1.0
... it is now named havege_random!

Reported by: Robert Schumann
Bug: http://curl.haxx.se/mail/lib-2012-01/0178.html
2012-01-18 23:17:54 +01:00
Daniel Stenberg
4b9af77d54 RELEASE-NOTES: synced with 5d70a61b94
5 more bug fixes, 1 more contributor
2012-01-18 22:33:45 +01:00
Colin Hogben
5d70a61b94 Add two tests for telnet: URLs
Add simple telnet tests which (ab)use the http server.
The second test checks for an input file handling bug.
2012-01-18 22:20:33 +01:00
Colin Hogben
51c485342b Remove bogus optimisation of telnet upload.
Remove wrongly implemented optimisation of telnet upload, apparently
intended to allow the library to avoid manually polling for input.
2012-01-18 22:17:46 +01:00
Colin Hogben
4563eeb9f4 Use correct file descriptor for telnet upload.
Fix a bug where input was read from stdin even when a different FILE *
had been configured via CURLOPT_READDATA
2012-01-18 22:17:10 +01:00
Yang Tse
2cafb0e97c OpenLDAP: fix LDAP connection phase memory leak
bug: http://curl.haxx.se/bug/view.cgi?id=3474308
2012-01-18 16:06:29 +01:00
Johannes Bauer
6ea7acf5a9 OpenSSL: fix PKCS#12 certificate parsing related memory leak
Leak triggered when CURLOPT_SSLCERTTYPE and CURLOPT_SSLKEYTYPE set to P12
and both CURLOPT_SSLCERT and CURLOPT_SSLKEY point to the same PKCS#12 file.
2012-01-18 13:39:12 +01:00
Yang Tse
a20daf90e3 OpenSSL: SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option is no longer enabled
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed successfull
interoperability with web server Netscape Enterprise Server 2.0.1 released
back in 1996 more than 15 years ago.

Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
CVE-2010-4180 when using previous OpenSSL versions we no longer enable
this option regardless of OpenSSL version and SSL_OP_ALL definition.
2012-01-18 11:59:20 +01:00
Yang Tse
24526d0c0f tests: enable time tracing on tests 500, 573 and 585 2012-01-17 21:33:17 +01:00
Yang Tse
a752850acc tests: testtrace.[ch] provides debug callback for libtest usage
Allows tests from the libtest subdir to generate log traces
similar to those of curl with --tracetime and --trace-ascii
options but with output going to stderr.
2012-01-17 21:32:05 +01:00
Yang Tse
2b9fafd622 sws.c: fix proxy mode secondary connection monitoring condition 2012-01-17 12:28:28 +01:00
Yang Tse
0ce2bca741 add LF termination to infof() trace string 2012-01-16 21:14:05 +01:00
Yang Tse
b15024be4d sws.c: improve proxy mode torture testing support - followup to 18c6c8a5 2012-01-16 19:01:35 +01:00
Daniel Stenberg
21401840fa url2file: new simple example
Just showing how to download the contents of a given URL into a local
file.

Based on a suggestion and example code by Georg Potthast
2012-01-16 14:47:00 +01:00
Daniel Stenberg
e3e24e5b36 imap.c: a dead simple imap example
Just to show that IMAP is used just like other protocols
2012-01-16 14:47:00 +01:00
Yang Tse
18c6c8a5e7 sws.c: improve proxy mode torture testing support - followup to c731fc58 2012-01-16 12:30:03 +01:00
Yang Tse
c731fc58ea sws.c: improve proxy mode torture testing support - followup to d4bf87dc 2012-01-15 20:13:32 +01:00
Yang Tse
6d62c5a6fc Curl_proxyCONNECT() trace known bug #39 2012-01-15 19:21:55 +01:00
Daniel Stenberg
f1092b387e test: verify HTTP response code 308
This newly speced HTTP status code already works as intended in the new
spec:
http://greenbytes.de/tech/webdav/draft-reschke-http-status-308-02.html

Test 1325 is added to verify that the method is kept after the redirect
2012-01-14 16:34:59 +01:00
Yang Tse
8e82ef9c32 http_negotiate_sspi.c: fix compiler warning 2012-01-13 13:34:43 +01:00
Yang Tse
d016f5f5f5 ssh.c: fix compiler warning 2012-01-13 12:57:09 +01:00
Yang Tse
d4bf87dc0e sws.c: improve proxy mode torture testing support 2012-01-13 05:13:48 +01:00
Daniel Stenberg
54dede4166 RELEASE-NOTES: synced with 9f20379fe4
5 bug fixes, 3 more contributors
2012-01-12 23:30:19 +01:00
Daniel Stenberg
9f20379fe4 hostip: avoid getaddrinfo when c-ares is used
Some functions using getaddrinfo and gethostbyname were still
mistakingly being used/linked even if c-ares was selected as resolver
backend.

Reported by: Arthur Murray
Bug: http://curl.haxx.se/mail/lib-2012-01/0160.html
2012-01-12 23:13:19 +01:00
Yang Tse
123c92c904 sws.c: replace sleep() usage with wait_ms() 2012-01-09 22:50:47 +01:00
gsengun
d28411c3cc FTP: CURLE_PARTIAL_FILE should not cause control connection to be closed
Test 161 updated accordingly
2012-01-09 22:50:20 +01:00
Yang Tse
2705af6267 sws.c: some compiler warning fixes 2012-01-08 19:28:46 +01:00
Yang Tse
f34ddb90e6 lib/setup.h: portable symbolic names for Winsock shutdown() mode flags 2012-01-08 02:32:51 +01:00
Yang Tse
dd69a3e868 sws.c: 812fa73057 follow-up 2012-01-06 01:52:45 +01:00
Yang Tse
812fa73057 sws.c: some IPv6 proxy mode peparatory adjustments 2012-01-05 20:52:48 +01:00
Daniel Stenberg
52824ed1ab curl.h: provide backwards compatible symbols
In commit c834213ad5 we re-used some obsolete error codes, and here are
two defines that makes sure existing source codes that happen to use any
of these deprecated ones will still compile.

As usual, define CURL_NO_OLDIES to avoid getting these "precaution
defines".
2012-01-05 19:57:39 +01:00
Daniel Stenberg
4897f4e517 win32-threaded-resolver: stop using a dummy socket
Previously the code would create a dummy socket while resolving just to
have curl_multi_fdset() return something but the non-win32 version
doesn't do it this way and the creation and use of a socket that isn't
made with the common create-socket callback can be confusing to apps
using the multi_socket API etc.

This change removes the dummy socket and thus will cause
curl_multi_fdset() to return with maxfd == -1 more often.
2012-01-04 23:16:30 +01:00
Peter Sylvester
81524cbfa0 OpenSSL: remove reference to openssl internal struct
With this change, curl compiles with the new OPENSSL_NO_SSL_INTERN
cflag. This flag might become the default in some distant future.
2012-01-04 23:02:36 +01:00
Yang Tse
8ef7a5706e test1320 test1321: avoid User-Agent comparison 2012-01-04 19:34:52 +01:00
Yang Tse
c358bab809 httpserver.pl: reorder sws command line options
make 'pidfile' and 'logfile' options appear first on command line in order
to ensure that processing of other options which write to logfile do this
to intended file and not the default one.
2012-01-04 19:28:22 +01:00
Yang Tse
4bc6c1a026 sws.c: fix proxy mode segfault 2012-01-04 19:14:19 +01:00
Yang Tse
3a55daee3d tool_formparse.c: fix compiler warning: enumerated type mixed with another type 2012-01-04 19:11:55 +01:00
Yang Tse
7bd2add06f krb5.c: fix compiler warning: variable set but not used 2012-01-04 19:11:54 +01:00
Daniel Stenberg
3b06f1fb36 KNOWN_BUGS: #77 CURLOPT_FORBID_REUSE kills NTLM 2012-01-04 16:33:33 +01:00
Steve Holme
db4f69ef06 Fixed use of CURLUSESSL_TRY for POP3 and IMAP based connections.
Fixed a problem in POP3 and IMAP where a connection would fail when
CURLUSESSL_TRY was specified for a server that didn't support
SSL/TLS connections rather than continuing.
2012-01-04 00:48:20 +01:00
Steve Holme
277022b2e4 Fixed incorrect error code being returned in STARTTLS
The STARTTLS response code in SMTP, POP3 and IMAP would return
CURLE_LOGIN_DENIED rather than CURLE_USE_SSL_FAILED when SSL/TLS
was not available on the server.

Reported by: Gokhan Sengun
Bug: http://curl.haxx.se/mail/lib-2012-01/0018.html
2012-01-04 00:47:58 +01:00
Daniel Stenberg
0f8239d5b4 curl_easy_setopt: refer to the most recent URI RFC 2012-01-03 23:39:22 +01:00
Daniel Stenberg
a4202be655 RELEASE-NOTES: synced with 2f4a487a68
Two bugfixes, two more contributors
2012-01-03 23:33:52 +01:00
Daniel Stenberg
2f4a487a68 tests: test IMAP, POP3 and SMTP over HTTP proxy tunnel 2012-01-03 16:12:58 +01:00
Daniel Stenberg
82180643f4 test proxy supports CONNECT
There's a new 'http-proxy' server for tests that runs on a separate port
and lets clients do HTTP CONNECT to other ports on the same host to
allow us to test HTTP "tunneling" properly.

Test cases now have a <proxy> section in <verify> to check that the
proxy protocol part matches correctly.

Test case 80, 83, 95, 275, 503 and 1078 have been converted. Test 1316
was added.
2012-01-03 15:01:22 +01:00
Daniel Stenberg
585b89a6c3 curl_easy_strerror.3: minor synopsis edit of the look 2012-01-02 16:00:46 +01:00
Yang Tse
cc69e56ce3 hostip.c: fix potential write past the end of string buffer 2012-01-02 13:44:56 +01:00
Yang Tse
8e25d1b93b hostip.c: fix Curl_loadhostpairs() OOM handling 2012-01-02 13:41:09 +01:00
Yang Tse
63e2718f8d runtests.pl: on test failure, don't show trace log files of other tests 2012-01-02 13:40:12 +01:00
Daniel Stenberg
7f472618de Curl_input_negotiate: use the correct buffer for input
Unfortunately we have no test cases for this and I have no SSPI build or
server to verify this with. The change seems simple enough though.

Bug: http://curl.haxx.se/bug/view.cgi?id=3466497
Reported by: Patrice Guerin
2012-01-01 22:36:32 +01:00
Daniel Stenberg
08107111ac runtests: put trace outputs in log/trace[num] for all tests 2012-01-01 19:48:24 +01:00
Daniel Stenberg
a3403db02f just a stupid typo 2011-12-31 23:53:52 +01:00
Daniel Stenberg
c9a3cab6c4 SFTP dir: increase buffer size counter
When the buffer gets realloced to hold the file name in the
SSH_SFTP_READDIR_LINK state, the counter was not bumped accordingly.

Reported by: Armel Asselin
Patch by: Armel Asselin
Bug: http://curl.haxx.se/mail/lib-2011-12/0249.html
2011-12-31 23:52:15 +01:00
Daniel Stenberg
f4949e56eb RELEASE-NOTES: synced with 81ebdd9e28
6 more bugfixes, 3 more contributors
2011-12-31 11:22:26 +01:00
Daniel Stenberg
81ebdd9e28 create_hostcache_id: use the key lower cased
... to make sure the DNS cache is properly case insensitive
2011-12-31 10:58:05 +01:00
Daniel Stenberg
207cf15032 changed case: use new host name for subsequent HTTP requests
When a HTTP connection is re-used for a subsequent request without
proxy, it would always re-use the Host: header of the first request. As
host names are case insensitive it would make curl send another host
name case that what the particular request used.

Now it will instead always use the most recent host name to always use
the desired casing.

Added test case 1318 to verify.

Bug: http://curl.haxx.se/mail/lib-2011-12/0314.html
Reported by: Alex Vinnik
2011-12-31 10:45:28 +01:00
Daniel Stenberg
5e0a44e4d5 CURLOPT_RESOLVE: avoid adding already present host names
The load host names to DNS cache function was moved to hostip.c and it
now makes sure to not add host names that already are present in the
cache. It would previously lead to memory leaks when for example using
the --resolve and multiple URLs on the command line.
2011-12-31 10:45:27 +01:00
Dan Fandrich
9e3f8c4850 runtests.pl: Use logmsg more consistently 2011-12-31 00:49:34 -08:00
Alessandro Ghedini
90343c76c6 examples: update README, Makefile.inc and gitignore with pop3s examples 2011-12-30 15:30:11 +01:00
Alessandro Ghedini
ecd75e8cb8 examples: add a couple of simple pop3s examples
These examples show how to fetch a single message (RETR command) and how to
list all the messages in a given mailbox (LIST command), with authentication
via SSL.

They were both based on the https.c example.
2011-12-30 15:30:11 +01:00
Yang Tse
e63c9f8ff3 removed execute file permission 2011-12-30 03:53:25 +01:00
Yang Tse
ed0364343d removed trailing whitespace 2011-12-30 03:36:18 +01:00
Yang Tse
5c0ad9581d ftpserver.pl: arbitrary application data splitting among TCP packets [II]
Take in account that 'pingpong' server commands may arrive splitted among
several sockfilt 'DATA' PDU's.
2011-12-29 23:40:06 +01:00
Yang Tse
e99128a5c9 ftpserver.pl: arbitrary application data splitting among TCP packets [I]
Initial step in order to allow our pingpong server to better support arbitrary
application data splitting among TCP packets. This first commit only addresses
reasembly of data that sockfilter processes reads from soockets and pingpong
server later reads from sockfilters stdout.
2011-12-28 23:04:23 +01:00
Yang Tse
33c2e1cafc testcurl.pl: 82c344a3 follow-up 2011-12-27 13:23:47 +01:00
Yang Tse
84f736981c testcurl.pl: log ACLOCAL_FLAGS 2011-12-26 17:09:44 +01:00
Yang Tse
82c344a347 testcurl.pl: third party m4 warnings filtering adjustment
Make testcurl.pl ignore messages pertaining to third party m4 files we don't
care nor use on a file basis policy while retaining all other warnings.

This closes temporary commit e71e226f
2011-12-26 17:01:04 +01:00
Kamil Dudka
9f7f6a62ff transfer: avoid unnecessary timeout event when waiting for 100-continue
The commit 9dd85bc unintentionally changed the way we compute the time
spent waiting for 100-continue.  In particular, when using a SSL client
certificate, the time spent by SSL handshake was included and could
cause the CURL_TIMEOUT_EXPECT_100 timeout to be mistakenly fired up.

Bug: https://bugzilla.redhat.com/767490
Reported by: Mamoru Tasaka
2011-12-25 22:37:24 +01:00
Yang Tse
98292bcdd0 transfer.c: move a logging statement placement 2011-12-25 12:11:51 +01:00
Yang Tse
996f2454ba hash.c: fix OOM triggered segfault 2011-12-25 11:35:45 +01:00
Daniel Stenberg
99a12baa34 ftp_do_more: don't return success until all is done
ftp_do_more() returns after accepting the server connect however it
needs to fall through and set "*complete" to TRUE before exit from the
function.

Bug: http://curl.haxx.se/mail/lib-2011-12/0250.html
Reported by: Gokhan Sengun
2011-12-24 00:12:00 +01:00
Daniel Stenberg
4f8db8bf95 Curl_do_more: fix typo logic
In the recent do_more fix the new logic was mistakenly checking the
pointer instead of what it points to.

Reported by: Gokhan Sengun
Bug: http://curl.haxx.se/mail/lib-2011-12/0250.html
2011-12-24 00:09:41 +01:00
Daniel Stenberg
5ac9ec7205 SFTP mkdir: use correct permission
When sending quote command to a SFTP server and 'mkdir' was used, it
would send fixed permissions and not use the CURLOPT_NEW_DIRECTORY_PERMS
as it should.

Reported by: Armel
Patch by: Armel
Bug: http://curl.haxx.se/mail/lib-2011-12/0249.html
2011-12-24 00:04:04 +01:00
Yang Tse
f8cd217f04 buildconf: minor tweaks commit 430527a1 follow-up 2011-12-23 17:45:42 +01:00
Colin Hogben
84e7ea2ffc Require a less ancient version of perl
The INTERNALS document suggested that compatibility should be
maintained with perl version 4, but this was untrue - scripts such as
chksource.pl and runtests.pl use perl5-isms.
2011-12-23 14:49:03 +01:00
Daniel Stenberg
2caa454dc1 resolve: don't leak pre-populated dns entries
CURLOPT_RESOLVE populates the DNS cache with entries that are marked as
eternally in use. Those entries need to be taken care of when the cache
is killed off.

Bug: http://curl.haxx.se/bug/view.cgi?id=3463121
Reported by: "tw84452852"
2011-12-23 14:46:20 +01:00
Daniel Stenberg
3e4181f88e new test: verify --resolve
Test 1317 verifies --resolve (leaked memory)

Bug: http://curl.haxx.se/bug/view.cgi?id=3463121
Reported by: "tw84452852"
2011-12-23 14:46:20 +01:00
Yang Tse
e71e226f6b testcurl.pl: temporary change
Allow autobuilds to run a couple of days without filtering out aclocal
underquoted definition warnings.
2011-12-23 11:13:39 +01:00
Daniel Stenberg
b0eb963bc7 operate: removed a single trailing space 2011-12-21 21:17:34 +01:00
Dan Fandrich
2cf9e78a22 --retry: Retry transfers on timeout and DNS errors 2011-12-21 11:09:09 -08:00
Yang Tse
430527a1d7 buildconf: minor tweaks 2011-12-21 16:21:37 +01:00
Yang Tse
1afbccc676 formdata.c: OOM handling fixes 2011-12-21 15:39:44 +01:00
Daniel Stenberg
1dd654644a TODO: 1.7 Happy Eyeball dual stack connect 2011-12-21 09:54:29 +01:00
Dan Fandrich
ba238e3a18 runtests.pl: Fixed perl warning when using the -l option 2011-12-20 18:31:53 -08:00
Daniel Stenberg
4bb140bfc9 RELEASE-NOTES: added two references 2011-12-20 23:57:39 +01:00
Daniel Stenberg
926916e28e Curl_socket_check: enlarge poll struct array to 3
This function was introduced in commit 5527417afa and as pointed out
by Gokhan Sengun, the array with poll structs must large enough to hold
3 sockets since that is what the function can accept. It could be noted
that he had this fixed in his patch as posted in
http://curl.haxx.se/mail/lib-2011-12/0179.html

Bug: http://curl.haxx.se/mail/lib-2011-12/0228.html
Reported by: Gokhan Sengun
2011-12-20 23:33:54 +01:00
Daniel Stenberg
3d6e2ec925 RELEASE-NOTES: synced with 380bade777
5 new bugfixes, 2 new changes and 4 new contributors
2011-12-20 23:27:41 +01:00
Daniel Stenberg
380bade777 TODO: remove active FTP from section 2.1
It is no longer done blocking in the multi interface
2011-12-20 23:26:47 +01:00
Daniel Stenberg
26ce3ac328 libcurl docs: add the new FTP accept option + errors 2011-12-20 23:14:18 +01:00
Daniel Stenberg
130fac6c16 timeleft_accept: ack global timeout, moved to ftp.c
First off the timeout for accepting a server connect back must of course
respect a global timeout. Then the timeleft function is only used by ftp
code so it was moved to ftp.c and made static.
2011-12-20 20:55:54 +01:00
Daniel Stenberg
6222ef8052 libcurl-tutorial.3: curl doesn't sent pragma no-cache
It did a long time ago
2011-12-20 20:32:47 +01:00
Daniel Stenberg
b06ed249d2 libcurl-multi.3: active FTP is no longer blocking! 2011-12-20 20:32:31 +01:00
Daniel Stenberg
377471f387 FTP: move FTP-specific struct field to ftpc_conn
"wait_data_conn" was added to the connectionbits in commit c834213ad5 for
handling active FTP connections but as it is purely FTP specific and now
only ever accessed by ftp.c I moved it into the FTP connection struct.
2011-12-20 20:30:38 +01:00
Daniel Stenberg
dfdac61522 non-blocking active FTP: cleanup multi state usage
Backpedaled out the funny double-change of state in the multi state
machine by adding a new argument to the do_more() function to signal
completion. This way it can remain in the DO_MORE state properly until
done. Long term, the entire DO_MORE logic should be moved into the FTP
code and be hidden from the multi code as the logic is only used for
FTP.
2011-12-20 20:30:02 +01:00
Gokhan Sengun
c834213ad5 FTP: perform active connections non-blocking
1- Two new error codes are introduced.

CURLE_FTP_ACCEPT_FAILED to be set whenever ACCEPTing fails because of
FTP server connected.

CURLE_FTP_ACCEPT_TIMEOUT to be set whenever ACCEPTing timeouts.

Neither of these errors are considered fatal and control connection
remains OK because it could just be a firewall blocking server to
connect to the client.

2- One new setopt option was introduced.

CURLOPT_ACCEPTTIMEOUT_MS

It sets the maximum amount of time FTP client is going to wait for a
server to connect. Internal default accept timeout is 60 seconds.
2011-12-20 20:30:02 +01:00
Daniel Stenberg
5527417afa sockets: new Curl_socket_check() can wait for 3 sockets
This offers an alternative to the existing Curl_socket_ready() API which
only checks one socket for read and one for write.
2011-12-20 20:30:02 +01:00
Cédric Deltheil
bedfafe38e curl.h: add __ANDROID__ macro check
When working with the Android Standalone Toolchain the compiler defines
this macro:

  /path/to/arm-linux-androideabi-gcc -E -dM - < /dev/null \
  | grep -i android
  #define __ANDROID__ 1

We really need to check both ANDROID and __ANDROID__ since I've observed
that:

* if you use Android.mk file(s) and the 'ndk-build' script (aka vanilla
way), ANDROID is predefined (see -DANDROID extra C flag),

* if you use the Android Standalone Toolchain, then __ANDROID__ is
predefined as stated by the compiler
2011-12-20 20:18:14 +01:00
Daniel Stenberg
e9040f2954 lib500: verify timers relative each other
As commit ce896875f8 fixed a timer that accidentally had been moved in
code and then returned a bad timer, the lib500.c code (used in test 500
and some others) now verifies 5 timers against each other to verify that
they have the correct relative values. We cannot compare against
absolute values as the timings will vary a lot.
2011-12-20 15:41:43 +01:00
Daniel Stenberg
51d4885ca0 Curl_pgrsTime: store now in an auto variable
It makes it easier to introduce debug outputs in this function, and
everything in the function is using the value anyway so it might even be
more efficient.
2011-12-20 15:05:50 +01:00
Daniel Stenberg
ce896875f8 timer: restore PRETRANSFER timing
Regression introduced in 7.23.0 with commit 9dd85bce. The function in
which the PRETRANSFER time stamp was recorded was moved in time causing
it be stored very quickly after the start timestamp. On most systems
shorter than 1 millisecond and thus it wouldn't even show with -w
"%{time_pretransfer}" using the command line tool.

Bug: http://curl.haxx.se/mail/archive-2011-12/0022.html
Reported by: Toni Moreno
2011-12-20 14:59:46 +01:00
Bernhard Reutner-Fischer
eb6e9593c4 libcurl.m4: Fix quoting arguments of AC_LANG_PROGRAM
Parameters were underquoted, resulting in
warning: AC_LANG_CONFTEST: no AC_LANG_SOURCE call detected in body

Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
2011-12-20 13:35:27 +01:00
Daniel Stenberg
5c71544fc6 gitignore: ignore the symbol versioning file 2011-12-20 11:07:23 +01:00
Daniel Stenberg
7799ac434e tutorial: remove CURLM_CALL_MULTI_PERFORM add sharing
The CURLM_CALL_MULTI_PERFORM reference is an old leftover I had to
remove.

I also added some blurb to the previously blank "sharing" section.
2011-12-20 09:48:32 +01:00
Alessandro Ghedini
7cc2e8b349 configure: add symbols versioning option
Allow, at configure time, the production of versioned symbols. The
symbols will look like "CURL_<FLAVOUR>_<VERSION> <SYMBOL>", where
<FLAVOUR> represents the SSL flavour (e.g. OPENSSL, GNUTLS, NSS, ...),
<VERSION> is the major SONAME version and <SYMBOL> is the actual symbol
name. If no SSL library is enabled the symbols will be just
"CURL_<VERSION> <SYMBOL>".
2011-12-19 23:25:36 +01:00
Sven Wegener
3c18b38dcc Use Curl_ssl_connect for non-blocking connect fallback
This gets the appconnect time right for ssl backends, which don't
support non-blocking connects.

Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
2011-12-19 22:37:37 +01:00
Daniel Stenberg
1fc5cd6a1a RELEASE-NOTES: synced with af9bc1604c
One new feature, one bug fix. Introduced references in this file for
mentioned issues after this discussion:
http://curl.haxx.se/mail/lib-2011-12/0187.html

The plan is to let the references get moved over to the changes.html
file at release-time
2011-12-19 20:08:59 +01:00
Daniel Stenberg
af9bc1604c curl.1: minor white space cleanup 2011-12-19 14:23:23 +01:00
Alessandro Ghedini
b235d5ade8 docs: improve description of the --capath option
Document the possibility of providing multiple values using the ":"
separator, and the fact that the default value will be ignored if the
option is used.
2011-12-19 11:10:47 +01:00
Steve Holme
ee3d3adc6f DOCS: Added SMTP information to CURLOPT_INFILESIZE 2011-12-19 11:08:01 +01:00
Daniel Stenberg
583a902789 Curl_proxyCONNECT: use newlines in debug output 2011-12-19 09:32:54 +01:00
Daniel Stenberg
7b8590d1f5 curl -F: fix multiple file upload with custom type
Test case 1315 was added to verify this functionality. When passing in
multiple files to a single -F, the parser would get all confused if one
of the specified files had a custom type= assigned.

Reported by: Colin Hogben
2011-12-16 11:43:25 +01:00
Colin Hogben
9b185aac43 New test for multiple file upload
test 1315 checks correct behaviour when uploading multiple files.
Buggy behaviour has been seen where only two attachments are sent.
2011-12-16 11:39:53 +01:00
Yang Tse
34f9ec0c54 configure: libtool 1.5 tweaks 2011-12-15 18:01:00 +01:00
Colin Hogben
7111ca6f5f Correct substitution var names
Two variable names were wrong in the documentation.
2011-12-15 17:27:51 +01:00
Colin Hogben
612a61b267 Correct default upload mimetype in manual
The default content-type for file uploads is application/octet-stream,
not text/plain as stated in the MANUAL.
2011-12-15 17:27:38 +01:00
Alessandro Ghedini
cd4cd66839 docs: fix typo in curl_easy_setopt manpage 2011-12-15 17:25:07 +01:00
Yang Tse
4c4e8ba1f0 if2ip.[ch]: fix compilation with MinGW
Avoid 'interface' literal that some MinGW versions define as a macro
2011-12-13 18:37:33 +01:00
Yang Tse
de6f4f356e connect.c: fix compiler warning 'enumerated type is mixed with another type' 2011-12-13 16:18:08 +01:00
Yang Tse
66c5076252 if2ip.c: fix compiler warning 'unused parameter' 2011-12-13 16:08:42 +01:00
Yang Tse
b9b772fefe pop3.c: fix compiler warning variable may be used uninitialized 2011-12-13 15:58:02 +01:00
Yang Tse
07efe110cc if2ip.c: fix compiler warning 'enumerated type is mixed with another type' 2011-12-13 15:47:26 +01:00
Jason Glasgow
6e4835c795 CURLOPT_INTERFACE: avoid resolving interfaces names
Do not try to resolve interfaces names via DNS by recognizing interface
names in a few ways.  If the interface option argument has a prefix of
"if!" then treat the argument as only an interface.  Similarly, if the
interface argument is the name of an interface (even if it does not have
an IP address assigned), treat it as an interface name.  Finally, if the
interface argument is prefixed by "host!" treat it as a hostname that
must be resolved by /etc/hosts or DNS.

These changes allow a client using the multi interfaces to avoid
blocking on name resolution if the interface loses its IP address or
disappears.
2011-12-12 23:12:37 +01:00
Daniel Stenberg
ba057c2e19 RELEASE-NOTES: synced with 1259ccf747
5 more bugfixes, 5 more contributors
2011-12-12 20:06:50 +01:00
Steve Holme
1259ccf747 ConnectionExists: Fix reuse for TLS upgraded connections
Fixed the connection reuse detection in ConnectionExists() when
comparing a new connection that is non-SSL based against that of a SSL
based connection that has become so by being upgraded via TLS.
2011-12-12 00:32:47 +01:00
Daniel Stenberg
07e3b7512c create_conn: don't switch to HTTP protocol if tunneling is enabled
This is a regression since who knows when. When spotting that a HTTP
proxy is used we must not uncondititionally enable the HTTP protocol
since if we do tunneling through the proxy we're still using the target
protocol.

Reported by: Naveen Chandran
2011-12-09 22:51:08 +01:00
Daniel Stenberg
50d88bf4b5 FAQ: add --resolve details to question 3.19 2011-12-07 23:08:15 +01:00
Gokhan Sengun
1cacf853da Curl_closesocket: clear sock_accepted on close
As a follow-up from commit d5b5f64bce, clear the sock_accepted status
when such a socket is closed to avoid a re-used connection to retain the
state wrongly.

Bug: http://curl.haxx.se/mail/lib-2011-12/0079.html
2011-12-07 16:03:00 +01:00
Daniel Stenberg
9dbe6565d4 static SSL windows builds: add more libs to the link
Starting with some recent OpenSSL versions (1.0.0e was mentioned)
linking with a static openssl requires a set of more libs to be linked
on Windows.

Thanks also to Steve Holme and Martin Storsj for additional feedback.

Bug: http://curl.haxx.se/mail/lib-2011-12/0063.html
Reported by: Ward Willats
2011-12-07 15:52:25 +01:00
Gokhan Sengun
2b24dd870e multi interface: fix block when CONNECT_ONLY option is used 2011-12-07 15:37:05 +01:00
Dan Fandrich
46724b87b7 Added some include files in a couple of example programs
This improves portability of the examples.  This patch was
submitted to the OpenBSD ports collection by naddy.
2011-12-06 19:54:48 -08:00
Daniel Stenberg
82a4d26e7f MakefileBuild: fix the static build
This is a left-over fix from commit b7e242de0e that Tom Wright
suggested.

Reported by: Ward Willats
2011-12-06 20:02:57 +01:00
Daniel Stenberg
2b0e09b0f9 OpenSSL: check for the SSLv2 function in configure
If no SSLv2 was detected in OpenSSL by configure, then we enforce the
OPENSSL_NO_SSL2 define as it seems some people report it not being
defined properly in the OpenSSL headers.
2011-12-06 14:22:45 +01:00
Daniel Stenberg
361cd03d58 CURLOPT_CONNECTTIMEOUT: default is 300 seconds
If the option is set to 0, the default timeout will be used - which in
modern libcurl versions equals 300 seconds (== 5 minutes).

Bug: http://curl.haxx.se/mail/lib-2011-12/0051.html
Reported by: Vladimir Grishchenko
2011-12-05 23:19:50 +01:00
Rob Ward
7e4daaf908 progress function example: include timed interval
Adds a timer based off of CURLINFO_TOTAL_TIME that is used to perform
certain actions after a minimum amount of time has passed using the
progress function. As a consequence the curl handle is now also passed
into the progress function. Progress example now also includes an
example of how to retreive the TOTAL_TIME and print it out.
2011-12-05 23:13:34 +01:00
Daniel Stenberg
3bbe219be2 RELEASE-NOTES: synced with 347f951c39
8 more bugs, 5 more contributors
2011-12-05 22:58:30 +01:00
Daniel Stenberg
347f951c39 SSH: fix CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
When a 32 digit hex key is given as a hostkey md5 checksum, the code
would still run it against the knownhost check and not properly
acknowledge that the md5 should then be the sole guide for.

The verbose output now includes the evaluated MD5 hostkey checksum.

Some related source code comments were also updated.

Bug: http://curl.haxx.se/bug/view.cgi?id=3451592
Reported by: Reza Arbab
2011-12-05 22:24:28 +01:00
Daniel Stenberg
c50dbf670f Curl_resolver_is_resolved: differentiate between host/proxy errors
As there are different return codes for host vs proxy errors, this function
now properly returns the code properly depending on what was attempted to get
resolved.

Bug: http://curl.haxx.se/mail/archive-2011-12/0010.html
Reported by: Jason Liu
2011-12-05 12:44:55 +01:00
Daniel Stenberg
0cf05af744 c-ares: return proxy failure for all proxy types
When making a distinction which return code to return, the code previously
only regarded HTTP proxies to be proxies and thus return host-related errors
for failures on other proxy types than HTTP. Now all proxy types will be
considered proxies...
2011-12-05 12:41:38 +01:00
Daniel Stenberg
d5b5f64bce FTP: close callback fix
Keep track of which sockets that are the result of accept() calls and
refuse to call the closesocket callback for those sockets. Test case 596
now verifies that the open socket callback is called the same number of
times as the closed socket callback for active FTP connections.

Bug: http://curl.haxx.se/mail/lib-2011-12/0018.html
Reported by: Gokhan Sengun
2011-12-05 12:34:27 +01:00
Daniel Stenberg
088ba97a24 FTP: call opensocket callback properly
When the new socket is created for an active connection, it is now done
using the open socket callback.

Test case 596 was modified to run fine, although it hides the fact that
the close callback is still called too many times, as it also gets
called for closing sockets that were created with accept().
2011-12-05 11:42:10 +01:00
Daniel Stenberg
9109cdec11 Curl_socket: internal replacement for socket()
Moved out into a separate function to work as a "generic" socket()
replacement.
2011-12-05 10:58:38 +01:00
Daniel Stenberg
5971d401d4 test: verify the opensocket callback for FTP
test 595: for passive FTP
test 596: for active FTP
2011-12-04 23:10:12 +01:00
Jason Glasgow
62d3652b43 CURLOPT_DNS_SERVERS: set name servers if possible (fix)
Ensure that CURLE_OK is returned if setting the name servers is successfull.
2011-12-02 21:54:15 +01:00
Daniel Stenberg
d81f5ea3e0 multi interface: only use non-NULL function pointer!
If the socket callback function pointer hasn't been set, we must not
attempt to use it. Commit adc88ca20 made it more likely to occur.
2011-12-02 21:10:28 +01:00
Jason Glasgow
adc88ca203 multi: handle timeouts on DNS servers by checking for new sockets
If the first name server is not available, the multi interface does
not invoke the socket_cb when the DNS request to the first name server
timesout.  Ensure that the list of sockets are always updated after
calling Curl_resolver_is_resolved.

This bug can be reproduced if Curl is complied with --enable_ares and
your code uses the multi socket interfaces and the
CURLMOPT_SOCKETFUNCTION option.  To test try:
  iptables -I INPUT \
           -s $(sed -n -e '/name/{s/.* //p;q}' /etc/resolv.conf)/32 \
           -j REJECT
and then run a program which uses the multi-interface.
2011-12-02 10:18:52 +01:00
Daniel Stenberg
83350c9cc4 test 815: verify POP3 dot-first-on-line unescaping 2011-12-01 10:20:42 +01:00
Steve Holme
bdb647814e POP3: fixed escaped dot not being striped out
Changed the eob detection to work across the whole of the buffer so that
lines that begin with a dot (which the server will have escaped) are
passed to the client application correctly.
2011-12-01 00:06:47 +01:00
Yang Tse
c92234c3bc buildconf: follow-up for commit 7e02f7fd 2011-11-30 21:53:21 +01:00
Yang Tse
7e02f7fdee buildconf: fix libtool 1.5.x warnings triggered with autoconf 2.6x or later
Using libtool 1.5.x (x < 26) with autoconf 2.6x or later generates warnings
due to some libtool variables not following naming convention for variables
that will be cached.

This is addressed renaming a couple of variables to make these follow expected
naming convention.
2011-11-30 19:33:38 +01:00
Daniel Stenberg
bd94807003 RELEASE-NOTES: synced with 1038d0aa1
5 bugfixes and 1 new contributor
2011-11-30 16:38:58 +01:00
Yang Tse
1038d0aa16 pop3.c: fix compiler warning 2011-11-29 20:28:49 +01:00
Yang Tse
f80a508297 configure: avoid usage of macro PKG_CHECK_MODULES
libidn option adjusted in order to use pkg-config info when available
in a similar way as we already do for other libraries.
2011-11-29 19:11:34 +01:00
Daniel Stenberg
af64666434 POP3: detect when LIST returns no mails
By making sure the function can detect an "end of body" sequence
immediately on the first line, test 811 is now enabled.
2011-11-29 13:43:46 +01:00
Daniel Stenberg
2d72489f0f ftpserver: output CRLF in logs
Previously the log function would just filter out all CR and LF
occurances from the log to make it more readable. This had the downside
that it made it very hard to see CR LFs when they actually matters.

Now, they're instead converted to "[CR]" and "[LR]" in the log to become
apparent to readers.
2011-11-29 13:43:12 +01:00
Daniel Stenberg
dda815b776 POP3: fix end of body detection
Curl_pop3_write() now has a state machine that scans for the end of a
POP3 body so that the CR LF '.' CR LF sequence can come in everything
from one up to five subsequent packets.

Test case 810 is modified to use SLOWDOWN which makes the server pause
between each single byte and thus makes the POP3 body get sent to curl
basically one byte at a time.
2011-11-29 00:25:21 +01:00
Daniel Stenberg
8d3efb6be0 test: added POP3 test with dot-prefixed line
Test 815 is disabled for now since libcurl currently doesn't unescape
such lines the way it should. See mail:

http://curl.haxx.se/mail/lib-2011-11/0324.html
2011-11-28 23:34:16 +01:00
Daniel Stenberg
11e52ef0a1 configure: fix to make older pkg-config play well
configure.ac:1349: error: possibly undefined macro: PKG_CONFIG_LIBDIR

Obviously this is not a problem with pkg-config 0.26 but older versions
seem to show this.

Fix suggested by: Kamil Dudka
Reported by: Guenter
Bug: http://curl.haxx.se/mail/lib-2011-11/0298.html
2011-11-27 20:00:30 +01:00
Daniel Stenberg
71ce2470dc test 1211: FTP test to repeat bug #3429299
"Active FTP hangs if server does not open data connection"

The server first sends a 150 and then when libcurl waits for the data
transfer, the server sends a 425.
2011-11-25 23:15:58 +01:00
Mark Brand
874855b743 configure: add support for pkg-config detection of libidn 2011-11-25 23:05:37 +01:00
Daniel Stenberg
ac54d27d4b FTP tests 1206 - 1209: don't expect QUIT
The protocol parts for these tests do not include QUIT simply because
the error is CURLE_OPERATION_TIMEDOUT (28) which is a generic timeout
error without specificly saying for which connection it concerns, and
for timeouts libcurl marks the control channel as "invalid". As this
test case times out for the data connection it could still use the
control channel.
2011-11-25 22:49:49 +01:00
Yang Tse
2d833852f6 CyaSSL 2.0+ library initialization adjustment 2011-11-25 17:23:36 +01:00
Jonas Schnelli
0604b2fb90 rectify comment 2011-11-25 15:02:43 +01:00
Daniel Stenberg
8f50a5c7e5 SSLSESSION_SHARED: new macro to check if session is shared
Added convenience macro to use to check if a handle is using a shared
SSL session, and fixed so that Curl_ssl_close_all() doesn't lock when
the session isn't shared.
2011-11-25 15:00:37 +01:00
Yang Tse
703fa0a6a8 telnet.c: fix MSVC compiler warning 2011-11-25 14:30:53 +01:00
Yang Tse
97d7a9260e tvdiff_secs(): sub-zero time difference adjustment
Skip a floating point addition operation when integral part of time difference
is zero. This avoids potential floating point addition rounding problems while
preserving decimal part value.
2011-11-25 13:51:55 +01:00
Daniel Stenberg
4a4d04446d telnet: fix macros to allow proper semicolon use
Macros that look like function calls need to be made so that we can use
semicolons properly for indentation and for reducing the risk for
mistakes when using them.
2011-11-25 10:56:18 +01:00
Laurent Rabret
b9223a17b8 TELNET: improved treatment of options
1) enables the Window Size option
2) allows the server to enable the echo mode
3) allows an app using libcurl to disable the default binary mode

Signed-off-by: Laurent Rabret
2011-11-25 10:46:49 +01:00
Daniel Stenberg
f712ace9d7 RELEASE-NOTES: synced with 2c905fd1f8 2011-11-25 00:09:43 +01:00
Jonas Schnelli
2c905fd1f8 query-part: ignore the URI part for given protocols
By setting PROTOPT_NOURLQUERY in the protocol handler struct, the
protocol will get the "query part" of the URL cut off before the data is
handled by the protocol-specific code. This makes libcurl adhere to
RFC3986 section 2.2.

Test 1220 is added to verify a file:// URL with query-part.
2011-11-24 23:31:19 +01:00
Daniel Stenberg
4403e82f32 symbols.pl: provide LIBCURL_HAS macro for apps
Experience has shown that the symbols-in-versions file is very useful to
applications that want to build with a wide range of libcurl versions.
It is however easy to get it wrong and the source gets a bit messy with
all the fixed numerical comparisions.

The point of this script is to provide an easy-to-use macro for libcurl-
using applications to do preprocessor checks for specific libcurl
defines, and yet make the code clearly show what the macro is used for.
2011-11-24 22:56:39 +01:00
Yang Tse
c482e946f7 lib573.c: fix double data type variable comparison with zero 2011-11-24 18:18:42 +01:00
Yang Tse
46bd8b330a getinfo.c: reset app connect time when clearing session-info time variables 2011-11-24 18:13:09 +01:00
Yang Tse
78feaff9d8 Fix unreleased regression when using windows gnutls versions older than 2.8 2011-11-24 12:11:52 +01:00
Mark Brand
28bac99674 gnutls: only translate winsock errors for old versions
Bugfix: https handshake fails using gnutls 3 on windows
http://sourceforge.net/tracker/index.php?func=detail&aid=3441084&group_id=976&atid=100976

New gnutls versions have an error handler that knows about Winsock
errors, which is why gnutls_transport_set_global_errno() was deprecated
and then removed.

This is a correction of commit f5bb370 (blame me) which meant to
reimplement gnutls_transport_set_global_errno(), which is not necessary.
2011-11-23 22:38:11 +01:00
Daniel Stenberg
7248439fec protocol_connect: show verbose connect and set connect time
Regression: commit b998d95b (shipped first in release 7.22.0) made the
condition always equal false that should reset the TIMER_CONNECT timer
and call the Curl_verboseconnect() function.

Reported by: "Captain Basil"
Bug: http://curl.haxx.se/mail/archive-2011-11/0035.html
2011-11-21 23:36:21 +01:00
Daniel Stenberg
c532604b13 -J -O: use -O name if no Content-Disposition header comes!
A regression between 7.22.0 and 7.23.0 -- downloading a file with the
flags -O and -J results in the content being written to stdout if and
only if there was no Content-Disposition header in the http response. If
there is a C-D header with a filename attribute, the output is correctly
written.

Reported by: Dave Reisner
Bug: http://curl.haxx.se/mail/archive-2011-11/0030.html
2011-11-20 23:35:49 +01:00
Martin Storsjo
64f328c787 Add support for using nettle instead of gcrypt as gnutls backend 2011-11-19 22:23:14 +01:00
Jonas Schnelli
c0db5ff678 test: SFTP quote commands with * prefix
Related to the f64812ca63 commit
2011-11-18 20:30:46 +01:00
Daniel Stenberg
66617b79d7 CURLOPT_QUOTE: SFTP supports the '*'-prefix now 2011-11-18 20:27:07 +01:00
Jonas Schnelli
f64812ca63 SFTP: support '*' prefix for quote operations
prefixing a command with '*' means it is allowed to fail without
aborting the chain actions
2011-11-18 16:04:52 +01:00
Daniel Stenberg
10ecdf5078 getsessionid: don't ever return while locked
Also, check for the session sharing bit instead of comparing pointers
2011-11-17 23:57:21 +01:00
Daniel Stenberg
bb4eb58996 Curl_ssl_getsessionid: increase the value, not the pointer 2011-11-17 23:46:29 +01:00
Daniel Stenberg
fc8809f993 THANKS: one new contributor in 7.23.1 2011-11-17 23:43:38 +01:00
Alejandro Alvarez Ayllon
35f61c404d SSL session share: move the age counter to the share object
Previously the age counter would be counted individually in each easy
handle that shared SSL sessions!
2011-11-17 23:34:38 +01:00
Alejandro Alvarez Ayllon
97b73fec7a libtest build: add the missing lib586 2011-11-17 23:33:42 +01:00
Jason Glasgow
8d0a504f0d CURLOPT_DNS_SERVERS: set name servers if possible 2011-11-17 22:52:33 +01:00
Daniel Stenberg
967b2f87a8 RELEASE-NOTES: correct the release and contributor numbers 2011-11-17 18:29:15 +01:00
Daniel Stenberg
b9660dc4b2 FindWin32CACert: return OK even if CA cert isn't found
Bug: http://curl.haxx.se/mail/lib-2011-11/0180.html
Reported by: Mark Brand
2011-11-17 18:05:27 +01:00
Dan Fandrich
591c29aa49 curl has been built on many Android versions 2011-11-16 17:11:31 -08:00
Daniel Stenberg
5e0aa3aac9 7.24.0: start the work 2011-11-15 20:44:49 +01:00
Daniel Stenberg
7cfd10e255 THANKS: added 18 new contributors from 7.23.0 2011-11-15 20:44:24 +01:00
183 changed files with 5696 additions and 1272 deletions

View File

@@ -2,7 +2,7 @@
#
# Place the curl source (including this makefile) into external/curl/ in the
# Android source tree. Then build them with 'make curl' or just 'make libcurl'
# from the Android root. Tested with Android 1.5 and 2.1
# from the Android root. Tested with Android versions 1.5, 2.1-2.3
#
# Note: you must first create a curl_config.h file by running configure in the
# Android environment. The only way I've found to do this is tricky. Perform a
@@ -42,7 +42,7 @@
# into the right place (but see the note about this below).
#
# Dan Fandrich
# August 2010
# November 2011
LOCAL_PATH:= $(call my-dir)

View File

@@ -146,7 +146,7 @@ Daniel Stenberg (14 May 2010)
compressed Content-Encoding!
(http://curl.haxx.se/bug/view.cgi?id=3000056)
Daniel Stenberg (12 May 2010)
- Howard Chu brought support for RTMP. This is powered by the underlying
librtmp library. It supports a range of variations and "sub-protocols"
@@ -181,14 +181,14 @@ Daniel Stenberg (7 May 2010)
That situation is subject for some closer inspection in the future.
- Howard Chu split the I/O handling functions into private handlers.
Howard Chu brought the bulk work of this patch that properly moves out the
sending and recving of data to the parts of the code that are properly
responsible for the various ways of doing so.
Daniel Stenberg assisted with polishing a few bits and fixed some minor
flaws in the original patch.
Another upside of this patch is that we now abuse CURLcodes less with the
"magic" -1 return codes and instead use CURLE_AGAIN more consistently.
@@ -296,7 +296,7 @@ Daniel Stenberg (28 Mar 2010)
- Ben Greear: If you pass a URL to pop3 that does not contain a message ID as
part of the URL, it would previously ask for 'INBOX' which just causes the
pop3 server to return an error.
Now libcurl treats en empty message ID as a request for LIST (list of pop3
message IDs). User's code could then parse this and download individual
messages as desired.
@@ -318,7 +318,7 @@ Daniel Stenberg (24 Mar 2010)
the last packet received constitutes the end of the response body, libcurl
still treats it as a timeout condition and reports a message like:
"Operation timed out after 3000 milliseconds with 876 out of 876 bytes
"Operation timed out after 3000 milliseconds with 876 out of 876 bytes
received"
It should only a timeout if the timer lapsed and we DIDN'T receive the end
@@ -368,7 +368,7 @@ Daniel Stenberg (22 Mar 2010)
case of a timeout, the signal handler for SIGALRM never gets removed. I
think that in my case it gets executed at some point later on when execution
has long left Curl_resolv_timeout() or even the cURL library.
The code that is jumped to with siglongjmp() simply sets the error message
to "name lookup timed out" and then returns with CURLRESOLV_ERROR. I guess
that instead of simply returning without cleaning up, the code should have a
@@ -17288,7 +17288,7 @@ Version 5.1 (not publicly released)
They should be set for protocol-specific proxies. General proxy should be
set with
ALL_PROXY
And a comma-separated list of host names that shouldn't go through any

2
CMake/FindCARES.cmake Executable file → Normal file
View File

@@ -11,7 +11,7 @@ FIND_PATH(CARES_INCLUDE_DIR ares.h
/usr/local/include
/usr/include
)
SET(CARES_NAMES ${CARES_NAMES} cares)
FIND_LIBRARY(CARES_LIBRARY
NAMES ${CARES_NAMES}

View File

@@ -382,7 +382,7 @@ if(CMAKE_USE_OPENSSL)
check_include_file_concat("openssl/rand.h" HAVE_OPENSSL_RAND_H)
endif(CMAKE_USE_OPENSSL)
if(NOT HAVE_LDAP_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()
@@ -784,7 +784,7 @@ if(HAVE_SOCKLEN_T)
check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T)
set(CMAKE_EXTRA_INCLUDE_FILES)
if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T)
message(FATAL_ERROR
message(FATAL_ERROR
"Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log")
endif()
else()

View File

@@ -36,7 +36,7 @@ winbuild/MakefileBuild.vc winbuild/Makefile.vc
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
curl-style.el sample.emacs RELEASE-NOTES buildconf \
libcurl.pc.in vc6curl.dsw MacOSX-Framework Android.mk $(CMAKE_DIST) \
Makefile.msvc.names $(WINBUILD_DIST)
Makefile.msvc.names $(WINBUILD_DIST) lib/libcurl.vers.in
bin_SCRIPTS = curl-config

View File

@@ -1,55 +1,84 @@
Curl and libcurl 7.23.0
Curl and libcurl 7.24.0
Public curl releases: 125
Public curl releases: 127
Command line options: 149
curl_easy_setopt() options: 192
Public functions in libcurl: 58
Known libcurl bindings: 39
Contributors: 873
Contributors: 907
This release includes the following security fixes:
o curl was vulnerable to a data injection attack for certain protocols
http://curl.haxx.se/docs/adv_20120124.html
o curl was vulnerable to a SSL CBC IV vulnerability when built to use OpenSSL
http://curl.haxx.se/docs/adv_20120124B.html
This release includes the following changes:
o Empty headers can be sent in HTTP requests by terminating with a semicolon
o SSL session sharing support added to curl_share_setopt()
o Added support to MAIL FROM for the optional SIZE parameter
o smtp: Added support for NTLM authentication
o curl tool: code split into tool_*.[ch] files
o CURLOPT_QUOTE: SFTP supports the '*'-prefix now [24]
o CURLOPT_DNS_SERVERS: set name servers if possible [23]
o Add support for using nettle instead of gcrypt as gnutls backend [22]
o CURLOPT_INTERFACE: avoid resolving interfaces names with magic prefixes [21]
o Added CURLOPT_ACCEPTTIMEOUT_MS [30]
o configure: add symbols versioning option --enable-versioned-symbols [31]
This release includes the following bugfixes:
o handle HTTP redirects to "//hostname/path"
o SMTP without --mail-from caused segfault
o prevent extra progress meter headers between multiple files
o allow Content-Length to be replaced when sending HTTP requests
o curl now always sets postfieldsize to allow --data-binary and --data
to be mixed in the same command line
o curl_multi_fdset: avoid FD_SET out of bounds
o lots of MinGW build tweaks
o Curl_gethostname: return un-qualified machine name
o fixed the openssl version number configure check
o nss: certificates from files are no longer looked up by file base names
o returning abort from the progress function when using the multi interface
would not properly cancel the transfer and close the connection
o fix libcurl.m4 to not fail with modern gcc versions
o ftp: improved the failed PORT host name resolved error message
o TFTP timeout and unexpected block adjustments
o HTTP and GOPHER test server-side connection closing adjustments
o fix endless loop upon transport connection timeout
o don't clobber errno on failed connect
o typecheck: allow NULL to unset CURLOPT_ERRORBUFFER
o formdata: ack read callback abort
o make --show-error properly position independent
o set the ipv6-connection boolean correctly on connect
o SMTP: fix end-of-body string escaping
o gtls: only call gnutls_transport_set_lowat with <gnutls-2.12.0
o HTTP: handle multiple auths in a single WWW-Authenticate line
o curl_multi_fdset: correct fdset with FTP PORT use
o windbuild: fix the static build
o fix builds with GnuTLS version 3
o fix calling of OpenSSL's ERR_remove_state(0)
o HTTP auth: fix proxy Negotiate bug when Negotiate not requested
o ftp PORT: don't hang if bind() fails
o -# would crash on terminals wider than 256 columns
o SSL session share: move the age counter to the share object [1]
o -J -O: use -O name if no Content-Disposition header comes! [2]
o protocol_connect: show verbose connect and set connect time [3]
o query-part: ignore the URI part for given protocols [4]
o gnutls: only translate winsock errors for old versions [5]
o POP3: fix end of body detection [6]
o POP3: detect when LIST returns no mails
o TELNET: improved treatment of options [7]
o configure: add support for pkg-config detection of libidn [8]
o CyaSSL 2.0+ library initialization adjustment [9]
o multi interface: only use non-NULL socker function pointer
o call opensocket callback properly for active FTP
o don't call close socket callback for sockets created with accept() [10]
o differentiate better between host/proxy errors [11]
o SSH: fix CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and --hostpubmd5 [12]
o multi: handle timeouts on DNS servers by checking for new sockets [13]
o CURLOPT_DNS_SERVERS: fix return code
o POP3: fixed escaped dot not being stripped out [14]
o OpenSSL: check for the SSLv2 function in configure [15]
o MakefileBuild: fix the static build [16]
o create_conn: don't switch to HTTP protocol if tunneling is enabled [17]
o multi interface: fix block when CONNECT_ONLY option is used [18]
o Fix connection reuse for TLS upgraded connections [19]
o multiple file upload with -F and custom type [20]
o multi interface: active FTP connections are no longer blocking [25]
o Android build fix [26]
o timer: restore PRETRANSFER timing [27]
o libcurl.m4: Fix quoting arguments of AC_LANG_PROGRAM [28]
o appconnect time fixed for non-blocking connect ssl backends [29]
o do not include SSL handshake into time spent waiting for 100-continue [32]
o handle dns cache case insensitive
o use new host name casing for subsequent HTTP requests [33]
o CURLOPT_RESOLVE: avoid adding already present host names
o SFTP mkdir: use correct permission [34]
o resolve: don't leak pre-populated dns entries [35]
o --retry: Retry transfers on timeout and DNS errors
o negotiate with SSPI backend: use the correct buffer for input [36]
o SFTP dir: increase buffer size counter to avoid cut off file names [37]
o TFTP: fix resending (again) [38]
o c-ares: don't include getaddrinfo-using code [39]
o FTP: CURLE_PARTIAL_FILE will not close the control channel [40]
o win32-threaded-resolver: stop using a dummy socket
o OpenSSL: remove reference to openssl internal struct [41]
o OpenSSL: SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option no longer enabled
o OpenSSL: fix PKCS#12 certificate parsing related memory leak
o OpenLDAP: fix LDAP connection phase memory leak [42]
o Telnet: Use correct file descriptor for telnet upload
o Telnet: Remove bogus optimisation of telnet upload
o URL parse: user name with ipv6 numerical address
o polarssl: show cipher suite name correctly with 1.1.0
o polarssl: havege_rand is not present in version 1.1.0 WARNING, we still
use the old API which is said to be insecure. See
http://polarssl.org/trac/wiki/SecurityAdvisory201102
o gnutls: enforced use of SSLv3 [43]
This release includes the following known bugs:
@@ -58,13 +87,60 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Yukihiro Kawada, Dave Reisner, Gisle Vanem, Guenter Knauf, Steve Holme,
Yang Tse, Christopher Stone, Taneli Vahakangas, Albert Chin,
Alejandro Alvarez, Dan Fandrich, Julien Royer, Georg Lippitsch,
Vladimir Grishchenko, Dominique Leuenberger, Marcin Adamski,
Jerry Wu, Michal Marek, Frank Van Uffelen, Fabian Hiernaux, Anton Bychkov,
Andreas Olsson, Kamil Dudka, Thomas L. Shinnick, Tim Harder, Nick Zitzmann,
Gokhan Sengun, Tom Wright, Patrick Monnerat, Rene Bernhardt,
Alexey Zakhlestin
Alejandro Alvarez Ayllon, Jason Glasgow, Jonas Schnelli, Mark Brand,
Martin Storsjo, Yang Tse, Laurent Rabret, Jason Glasgow, Steve Holme,
Reza Arbab, Jason Liu, Gokhan Sengun, Rob Ward, Dan Fandrich,
Naveen Chandran, Ward Willats, Vladimir Grishchenko, Colin Hogben,
Alessandro Ghedini, Cedric Deltheil, Toni Moreno, Bernhard Reutner-Fischer,
Sven Wegener, Alex Vinnik, Kamil Dudka, Mamoru Tasaka, Patrice Guerin,
Armel Asselin, Arthur Murray, Steve H Truong, Peter Sylvester,
Johannes Bauer, Brandon Wang, Pierre Joye, Robert Schumann,
Christian Grothoff, Nikos Mavrogiannopoulos
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/mail/lib-2011-11/0116.html
[2] = http://curl.haxx.se/mail/archive-2011-11/0030.htm
[3] = http://curl.haxx.se/mail/archive-2011-11/0035.html
[4] = http://curl.haxx.se/mail/lib-2011-11/0218.html
[5] = http://curl.haxx.se/mail/lib-2011-11/0267.html
[6] = http://curl.haxx.se/mail/lib-2011-11/0279.html
[7] = http://curl.haxx.se/mail/lib-2011-11/0247.html
[8] = http://curl.haxx.se/mail/lib-2011-11/0294.html
[9] = http://curl.haxx.se/bug/view.cgi?id=3442068
[10] = http://curl.haxx.se/mail/lib-2011-12/0018.html
[11] = http://curl.haxx.se/mail/archive-2011-12/0010.html
[12] = http://curl.haxx.se/bug/view.cgi?id=3451592
[13] = http://curl.haxx.se/mail/lib-2011-11/0371.html
[14] = http://curl.haxx.se/mail/lib-2011-11/0368.html
[15] = http://curl.haxx.se/mail/archive-2011-12/0012.html
[16] = http://curl.haxx.se/mail/lib-2011-12/0063.html
[17] = http://curl.haxx.se/mail/lib-2011-12/0010.html
[18] = http://curl.haxx.se/mail/lib-2011-12/0070.html
[19] = http://curl.haxx.se/mail/lib-2011-11/0022.html
[20] = http://curl.haxx.se/mail/lib-2011-12/0121.html
[21] = http://curl.haxx.se/mail/lib-2011-12/0107.html
[22] = http://curl.haxx.se/mail/lib-2011-11/0164.html
[23] = http://curl.haxx.se/mail/lib-2011-11/0067.html
[24] = http://curl.haxx.se/mail/lib-2011-11/0205.html
[25] = http://curl.haxx.se/mail/lib-2011-12/0179.html
[26] = http://curl.haxx.se/mail/lib-2011-12/0215.html
[27] = http://curl.haxx.se/mail/archive-2011-12/0022.html
[28] = http://curl.haxx.se/mail/lib-2011-12/0218.html
[29] = http://curl.haxx.se/mail/lib-2011-12/0211.html
[30] = http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTACCEPTTIMOUTMS
[31] = http://curl.haxx.se/mail/lib-2011-12/0133.html
[32] = https://bugzilla.redhat.com/767490
[33] = http://curl.haxx.se/mail/lib-2011-12/0314.html
[34] = http://curl.haxx.se/mail/lib-2011-12/0249.html
[35] = http://curl.haxx.se/bug/view.cgi?id=3463121
[36] = http://curl.haxx.se/bug/view.cgi?id=3466497
[37] = http://curl.haxx.se/mail/lib-2011-12/0249.html
[38] = http://curl.haxx.se/mail/lib-2012-01/0146.html
[39] = http://curl.haxx.se/mail/lib-2012-01/0160.html
[40] = http://curl.haxx.se/mail/lib-2012-01/0096.html
[41] = http://curl.haxx.se/mail/lib-2012-01/0049.html
[42] = http://curl.haxx.se/bug/view.cgi?id=3474308
[43] = http://curl.haxx.se/mail/lib-2012-01/0225.html

162
buildconf
View File

@@ -6,7 +6,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -21,9 +21,12 @@
#
###########################################################################
#--------------------------------------------------------------------------
# die prints argument string to stdout and exits this shell script.
#
die(){
echo "$@"
exit
echo "buildconf: $@"
exit 1
}
#--------------------------------------------------------------------------
@@ -33,11 +36,8 @@ die(){
findtool(){
file="$1"
if { echo $file | grep "/" >/dev/null 2>&1; } then
# we only check for the explicit file name if the file is given
# including a slash. Use ./ for current dir. Previously this would
# otherwise always cause findtool to search the local dir first, which
# is wrong.
if { echo "$file" | grep "/" >/dev/null 2>&1; } then
# when file is given with a path check it first
if test -f "$file"; then
echo "$file"
return
@@ -82,7 +82,8 @@ removethis(){
if test ! -f configure.ac ||
test ! -f src/tool_main.c ||
test ! -f lib/urldata.h ||
test ! -f include/curl/curl.h; then
test ! -f include/curl/curl.h ||
test ! -f m4/curl-functions.m4; then
echo "Can not run buildconf from outside of curl's source subdirectory!"
echo "Change to the subdirectory where buildconf is found, and try again."
exit 1
@@ -188,27 +189,24 @@ else
fi
#--------------------------------------------------------------------------
# libtool check
# GNU libtool preliminary check
#
LIBTOOL_WANTED_MAJOR=1
LIBTOOL_WANTED_MINOR=4
LIBTOOL_WANTED_PATCH=2
LIBTOOL_WANTED_VERSION=1.4.2
want_lt_major=1
want_lt_minor=4
want_lt_patch=2
want_lt_version=1.4.2
# This approach that tries 'glibtool' first is intended for systems that
# have GNU libtool named as 'glibtool' and libtool not being GNU's.
# this approach that tries 'glibtool' first is some kind of work-around for
# some BSD-systems I believe that use to provide the GNU libtool named
# glibtool, with 'libtool' being something completely different.
libtool=`findtool glibtool 2>/dev/null`
if test ! -x "$libtool"; then
libtool=`findtool ${LIBTOOL:-libtool}`
fi
if test -z "$LIBTOOLIZE"; then
# set the LIBTOOLIZE here so that glibtoolize is used if glibtool was found
# $libtool is already the full path
libtoolize="${libtool}ize"
else
libtoolize=`findtool $LIBTOOLIZE`
if test -z "$libtool"; then
echo "buildconf: libtool not found."
echo " You need GNU libtool $want_lt_version or newer installed."
exit 1
fi
lt_pver=`$libtool --version 2>/dev/null|head -n 1`
@@ -216,42 +214,55 @@ lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"`
lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"`
if test -z "$lt_version"; then
echo "buildconf: libtool not found."
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"
echo " You need GNU libtool $want_lt_version or newer installed."
exit 1
fi
old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS
lt_major=$1
lt_minor=$2
lt_patch=$3
lt_status="good"
if test "$lt_major" = "$LIBTOOL_WANTED_MAJOR"; then
if test "$lt_minor" -lt "$LIBTOOL_WANTED_MINOR"; then
lt_status="bad"
elif test -n "$LIBTOOL_WANTED_PATCH"; then
if test "$lt_minor" -gt "$LIBTOOL_WANTED_MINOR"; then
lt_status="good"
elif test -n "$lt_patch"; then
if test "$lt_patch" -lt "$LIBTOOL_WANTED_PATCH"; then
lt_status="bad"
fi
else
lt_status="bad"
fi
fi
if test -z "$lt_major"; then
lt_status="bad"
elif test "$lt_major" -gt "$want_lt_major"; then
lt_status="good"
elif test "$lt_major" -lt "$want_lt_major"; then
lt_status="bad"
elif test -z "$lt_minor"; then
lt_status="bad"
elif test "$lt_minor" -gt "$want_lt_minor"; then
lt_status="good"
elif test "$lt_minor" -lt "$want_lt_minor"; then
lt_status="bad"
elif test -z "$lt_patch"; then
lt_status="bad"
elif test "$lt_patch" -gt "$want_lt_patch"; then
lt_status="good"
elif test "$lt_patch" -lt "$want_lt_patch"; then
lt_status="bad"
else
lt_status="good"
fi
if test $lt_status != "good"; then
if test "$lt_status" != "good"; then
echo "buildconf: libtool version $lt_version found."
echo " You need libtool version $LIBTOOL_WANTED_VERSION or newer installed"
echo " You need GNU libtool $want_lt_version or newer installed."
exit 1
fi
echo "buildconf: libtool version $lt_version (ok)"
if test -f "$libtoolize"; then
echo "buildconf: libtoolize found"
#--------------------------------------------------------------------------
# GNU libtoolize check
#
if test -z "$LIBTOOLIZE"; then
# use (g)libtoolize from same location as (g)libtool
libtoolize="${libtool}ize"
else
echo "buildconf: libtoolize not found. Weird libtool installation!"
libtoolize=`findtool $LIBTOOLIZE`
fi
if test ! -f "$libtoolize"; then
echo "buildconf: libtoolize not found."
echo " You need GNU libtoolize $want_lt_version or newer installed."
exit 1
fi
@@ -276,6 +287,10 @@ fi
# perl check
#
PERL=`findtool ${PERL:-perl}`
if test -z "$PERL"; then
echo "buildconf: perl not found"
exit 1
fi
#--------------------------------------------------------------------------
# Remove files generated on previous buildconf/configure run.
@@ -311,6 +326,7 @@ for fname in .deps \
libcurl.pc \
libtool \
libtool.m4 \
libtool.m4.tmp \
ltmain.sh \
ltoptions.m4 \
ltsugar.m4 \
@@ -327,32 +343,52 @@ done
#
echo "buildconf: running libtoolize"
$libtoolize --copy --automake --force || die "The libtoolize command failed"
${libtoolize} --copy --automake --force || die "libtoolize command failed"
if test ! -f m4/curl-functions.m4; then
echo "buildconf: cURL m4 macros not found"
exit 1
# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4
# subdirectory and this local copy is patched to fix some warnings that
# are triggered when running aclocal and using autoconf 2.62 or later.
if test "$lt_major" = "1" && test "$lt_minor" = "5"; then
if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then
echo "buildconf: copying libtool.m4 to local m4 subdir"
ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir`
if test -f $ac_dir/libtool.m4; then
cp -f $ac_dir/libtool.m4 m4/libtool.m4
else
echo "buildconf: $ac_dir/libtool.m4 not found"
fi
if test -f m4/libtool.m4; then
echo "buildconf: renaming some variables in local m4/libtool.m4"
$PERL -i.tmp -pe \
's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \
s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \
m4/libtool.m4
rm -f m4/libtool.m4.tmp
fi
fi
fi
if test -f m4/libtool.m4; then
echo "buildconf: converting all mv to mv -f in local m4/libtool.m4"
$PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4
rm -f m4/libtool.m4.tmp
fi
echo "buildconf: running aclocal"
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "The aclocal command line failed"
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed"
if test -n "$PERL"; then
echo "buildconf: running aclocal hack to convert all mv to mv -f"
$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
else
echo "buildconf: perl not found"
exit 1
fi
echo "buildconf: converting all mv to mv -f in local aclocal.m4"
$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
echo "buildconf: running autoheader"
${AUTOHEADER:-autoheader} || die "The autoheader command failed"
${AUTOHEADER:-autoheader} || die "autoheader command failed"
echo "buildconf: cp lib/curl_config.h.in src/curl_config.h.in"
cp lib/curl_config.h.in src/curl_config.h.in
echo "buildconf: running autoconf"
${AUTOCONF:-autoconf} || die "The autoconf command failed"
${AUTOCONF:-autoconf} || die "autoconf command failed"
if test -d ares; then
cd ares
@@ -362,14 +398,15 @@ if test -d ares; then
fi
echo "buildconf: running automake"
${AUTOMAKE:-automake} -a -c || die "The automake command failed"
${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed"
#--------------------------------------------------------------------------
# GNU libtool complementary check
#
# Depending on the libtool and automake versions being used, config.guess
# might not be installed in the subdirectory until automake has finished.
# So we can not attempt to use it until this very last buildconf stage.
#
if test ! -f ./config.guess; then
echo "buildconf: config.guess not found"
else
@@ -413,7 +450,7 @@ else
if test "$lt_status" != "good"; then
need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch"
echo "buildconf: libtool version $lt_version found."
echo " $buildhost requires libtool $need_lt_version or newer installed."
echo " $buildhost requires GNU libtool $need_lt_version or newer installed."
rm -f configure
exit 1
fi
@@ -423,6 +460,5 @@ fi
#--------------------------------------------------------------------------
# Finished successfully.
#
echo "buildconf: OK"
exit 0

View File

@@ -26,6 +26,7 @@ AC_PREREQ(2.57)
dnl We don't know the version number "statically" so we use a dash here
AC_INIT([curl], [-], [a suitable curl mailing list: http://curl.haxx.se/mail/])
XC_OVR_ZZ50
CURL_OVERRIDE_AUTOCONF
dnl configure script copyright
@@ -1514,7 +1515,8 @@ if test X"$OPT_SSL" != Xno; then
RAND_egd \
ENGINE_cleanup \
CRYPTO_cleanup_all_ex_data \
SSL_get_shutdown )
SSL_get_shutdown \
SSLv2_client_method )
dnl Make an attempt to detect if this is actually yassl's headers and
dnl OpenSSL emulation layer. We still leave everything else believing
@@ -1799,17 +1801,30 @@ if test "$OPENSSL_ENABLED" != "1"; then
fi dnl OPENSSL != 1
dnl ---
dnl If GnuTLS is enabled, we MUST verify that it uses libgcrypt since
dnl curl code relies on that but recent GnuTLS versions can in fact build
dnl with different crypto libraries which curl right now cannot handle
dnl Check which crypto backend GnuTLS uses
dnl ---
if test "$GNUTLS_ENABLED" = "1"; then
AC_CHECK_LIB(gcrypt,
gcry_control, ,
[
AC_MSG_ERROR([need GnuTLS built with gcrypt to function with GnuTLS])
])
USE_GNUTLS_NETTLE=
# First check if we can detect either crypto library via transitive linking
AC_CHECK_LIB(gnutls, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ])
if test "$USE_GNUTLS_NETTLE" = ""; then
AC_CHECK_LIB(gnutls, gcry_control, [ USE_GNUTLS_NETTLE=0 ])
fi
# If not, try linking directly to both of them to see if they are available
if test "$USE_GNUTLS_NETTLE" = ""; then
AC_CHECK_LIB(nettle, nettle_MD5Init, [ USE_GNUTLS_NETTLE=1 ])
fi
if test "$USE_GNUTLS_NETTLE" = ""; then
AC_CHECK_LIB(gcrypt, gcry_control, [ USE_GNUTLS_NETTLE=0 ])
fi
if test "$USE_GNUTLS_NETTLE" = ""; then
AC_MSG_ERROR([GnuTLS found, but neither gcrypt nor nettle found])
fi
if test "$USE_GNUTLS_NETTLE" = "1"; then
AC_DEFINE(USE_GNUTLS_NETTLE, 1, [if GnuTLS uses nettle as crypto backend])
AC_SUBST(USE_GNUTLS_NETTLE, [1])
fi
fi
dnl ---
@@ -2331,56 +2346,202 @@ if test X"$OPT_LIBRTMP" != Xno; then
fi
dnl **********************************************************************
dnl Check for linker switch for versioned symbols
dnl **********************************************************************
AC_MSG_CHECKING([if libraries can be versioned])
GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script`
if test -z "$GLD"; then
versioned_symbols_flavour=
AC_MSG_RESULT(no)
AC_MSG_WARN(***
*** You need an ld version supporting the --version-script option.
)
else
AC_MSG_RESULT(yes)
AC_MSG_CHECKING([whether versioned symbols are wanted])
versioned_symbols_flavour=
AC_ARG_ENABLE(versioned-symbols,
AC_HELP_STRING([--enable-versioned-symbols], [Enable versioned symbols in shared library])
AC_HELP_STRING([--disable-versioned-symbols], [Disable versioned symbols in shared library]),
[ case "$enableval" in
yes) AC_MSG_RESULT(yes)
if test "x$OPENSSL_ENABLED" = "x1"; then
versioned_symbols_flavour="OPENSSL_"
elif test "x$GNUTLS_ENABLED" == "x1"; then
versioned_symbols_flavour="GNUTLS_"
elif test "x$NSS_ENABLED" == "x1"; then
versioned_symbols_flavour="NSS_"
elif test "x$POLARSSL_ENABLED" == "x1"; then
versioned_symbols_flavour="POLARSSL_"
elif test "x$CYASSL_ENABLED" == "x1"; then
versioned_symbols_flavour="CYASSL_"
elif test "x$AXTLS_ENABLED" == "x1"; then
versioned_symbols_flavour="AXTLS_"
else
versioned_symbols_flavour=""
fi
versioned_symbols="yes"
;;
*) AC_MSG_RESULT(no)
;;
esac
], [
AC_MSG_RESULT(no)
]
)
fi
AC_SUBST(VERSIONED_FLAVOUR, ["$versioned_symbols_flavour"])
AM_CONDITIONAL(VERSIONED_SYMBOLS, test "x$versioned_symbols" = "xyes")
dnl **********************************************************************
dnl Check for the presence of IDN libraries and headers
dnl **********************************************************************
AC_MSG_CHECKING([whether to build with libidn])
OPT_IDN="default"
AC_ARG_WITH(libidn,
AC_HELP_STRING([--with-libidn=PATH],[Enable libidn usage])
AC_HELP_STRING([--without-libidn],[Disable libidn usage]),
[LIBIDN="$withval"])
case "$LIBIDN" in
[OPT_IDN=$withval])
case "$OPT_IDN" in
no)
AC_MSG_RESULT(no)
;;
*) AC_MSG_RESULT(yes)
idn=""
dnl if there is a given path, check that FIRST
if test -n "$LIBIDN"; then
if test "x$LIBIDN" != "xyes"; then
oldLDFLAGS=$LDFLAGS
oldCPPFLAGS=$CPPFLAGS
LDFLAGS="$LDFLAGS -L$LIBIDN/lib"
CPPFLAGS="$CPPFLAGS -I$LIBIDN/include"
idn="yes"
AC_CHECK_LIB(idn, idna_to_ascii_4i, ,
idn=""
LDFLAGS=$oldLDFLAGS
CPPFLAGS=$oldCPPFLAGS)
fi
fi
if test "x$idn" != "xyes"; then
dnl check with default paths
idn="yes"
AC_CHECK_LIB(idn, idna_to_ascii_lz, ,
idn="")
fi
if test "x$idn" = "xyes"; then
curl_idn_msg="enabled"
AC_SUBST(IDN_ENABLED, [1])
dnl different versions of libidn have different setups of these:
AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror)
AC_CHECK_HEADERS( idn-free.h tld.h )
fi
;;
dnl --without-libidn option used
want_idn="no"
AC_MSG_RESULT([no])
;;
default)
dnl configure option not specified
want_idn="yes"
want_idn_path="default"
AC_MSG_RESULT([(assumed) yes])
;;
yes)
dnl --with-libidn option used without path
want_idn="yes"
want_idn_path="default"
AC_MSG_RESULT([yes])
;;
*)
dnl --with-libidn option used with path
want_idn="yes"
want_idn_path="$withval"
AC_MSG_RESULT([yes ($withval)])
;;
esac
if test "$want_idn" = "yes"; then
dnl idn library support has been requested
clean_CPPFLAGS="$CPPFLAGS"
clean_LDFLAGS="$LDFLAGS"
clean_LIBS="$LIBS"
PKGCONFIG="no"
#
if test "$want_idn_path" != "default"; then
dnl path has been specified
IDN_PCDIR="$want_idn_path/lib$libsuff/pkgconfig"
CURL_CHECK_PKGCONFIG(libidn, [$IDN_PCDIR])
if test "$PKGCONFIG" != "no"; then
IDN_LIBS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
$PKGCONFIG --libs-only-l libidn 2>/dev/null`
IDN_LDFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
$PKGCONFIG --libs-only-L libidn 2>/dev/null`
IDN_CPPFLAGS=`CURL_EXPORT_PCDIR([$IDN_PCDIR]) dnl
$PKGCONFIG --cflags-only-I libidn 2>/dev/null`
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
else
dnl pkg-config not available or provides no info
IDN_LIBS="-lidn"
IDN_LDFLAGS="-L$want_idn_path/lib$libsuff"
IDN_CPPFLAGS="-I$want_idn_path/include"
IDN_DIR="$want_idn_path/lib$libsuff"
fi
else
dnl path not specified
CURL_CHECK_PKGCONFIG(libidn)
if test "$PKGCONFIG" != "no"; then
IDN_LIBS=`$PKGCONFIG --libs-only-l libidn 2>/dev/null`
IDN_LDFLAGS=`$PKGCONFIG --libs-only-L libidn 2>/dev/null`
IDN_CPPFLAGS=`$PKGCONFIG --cflags-only-I libidn 2>/dev/null`
IDN_DIR=`echo $IDN_LDFLAGS | $SED -e 's/-L//'`
else
dnl pkg-config not available or provides no info
IDN_LIBS="-lidn"
fi
fi
#
if test "$PKGCONFIG" != "no"; then
AC_MSG_NOTICE([pkg-config: IDN_LIBS: "$IDN_LIBS"])
AC_MSG_NOTICE([pkg-config: IDN_LDFLAGS: "$IDN_LDFLAGS"])
AC_MSG_NOTICE([pkg-config: IDN_CPPFLAGS: "$IDN_CPPFLAGS"])
AC_MSG_NOTICE([pkg-config: IDN_DIR: "$IDN_DIR"])
else
AC_MSG_NOTICE([IDN_LIBS: "$IDN_LIBS"])
AC_MSG_NOTICE([IDN_LDFLAGS: "$IDN_LDFLAGS"])
AC_MSG_NOTICE([IDN_CPPFLAGS: "$IDN_CPPFLAGS"])
AC_MSG_NOTICE([IDN_DIR: "$IDN_DIR"])
fi
#
CPPFLAGS="$IDN_CPPFLAGS $CPPFLAGS"
LDFLAGS="$IDN_LDFLAGS $LDFLAGS"
LIBS="$IDN_LIBS $LIBS"
#
AC_MSG_CHECKING([if idna_to_ascii_4i can be linked])
AC_LINK_IFELSE([
AC_LANG_FUNC_LINK_TRY([idna_to_ascii_4i])
],[
AC_MSG_RESULT([yes])
tst_links_libidn="yes"
],[
AC_MSG_RESULT([no])
tst_links_libidn="no"
])
if test "$tst_links_libidn" = "no"; then
AC_MSG_CHECKING([if idna_to_ascii_lz can be linked])
AC_LINK_IFELSE([
AC_LANG_FUNC_LINK_TRY([idna_to_ascii_lz])
],[
AC_MSG_RESULT([yes])
tst_links_libidn="yes"
],[
AC_MSG_RESULT([no])
tst_links_libidn="no"
])
fi
#
if test "$tst_links_libidn" = "yes"; then
AC_DEFINE(HAVE_LIBIDN, 1, [Define to 1 if you have the `idn' library (-lidn).])
dnl different versions of libidn have different setups of these:
AC_CHECK_FUNCS( idn_free idna_strerror tld_strerror )
AC_CHECK_HEADERS( idn-free.h tld.h )
if test "x$ac_cv_header_tld_h" = "xyes"; then
AC_SUBST([IDN_ENABLED], [1])
curl_idn_msg="enabled"
if test -n "$IDN_DIR"; then
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$IDN_DIR"
export LD_LIBRARY_PATH
AC_MSG_NOTICE([Added $IDN_DIR to LD_LIBRARY_PATH])
fi
else
AC_MSG_WARN([Libraries for IDN support too old: IDN disabled])
CPPFLAGS="$clean_CPPFLAGS"
LDFLAGS="$clean_LDFLAGS"
LIBS="$clean_LIBS"
fi
else
AC_MSG_WARN([Cannot find libraries for IDN support: IDN disabled])
CPPFLAGS="$clean_CPPFLAGS"
LDFLAGS="$clean_LDFLAGS"
LIBS="$clean_LIBS"
fi
fi
dnl Let's hope this split URL remains working:
dnl http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/ \
@@ -3108,6 +3269,7 @@ AC_CONFIG_FILES([Makefile \
include/curl/Makefile \
src/Makefile \
lib/Makefile \
lib/libcurl.vers \
tests/Makefile \
tests/data/Makefile \
tests/server/Makefile \

View File

@@ -1,4 +1,4 @@
Updated: March 8, 2011 (http://curl.haxx.se/docs/faq.html)
Updated: December 7, 2011 (http://curl.haxx.se/docs/faq.html)
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
@@ -726,6 +726,12 @@ FAQ
curl --header "Host: www.example.com" http://127.0.0.1/
You can also opt to add faked host name entries to curl with the --resolve
option. That has the added benefit that things like redirects will also work
properly. The above operation would instead be done as:
curl --resolve www.example.com:80:127.0.0.1 http://www.example.com/
3.20 How to SFTP from my user's home directory?
Contrary to how FTP works, SFTP and SCP URLs specify the exact directory to

View File

@@ -392,7 +392,7 @@ Win32
set BCCDIR=c:\Borland\BCC55
In order to build a plain vanilla version of curl and libcurl run the
In order to build a plain vanilla version of curl and libcurl run the
following command from curl's root directory:
make borland

0
docs/INSTALL.cmake Executable file → Normal file
View File

View File

@@ -68,7 +68,7 @@ Portability
GNU Autoconf 2.57
GNU Automake 1.7 (we currently avoid 1.10 due to Solaris-related bugs)
GNU M4 1.4
perl 4
perl 5.004
roffit 0.5
groff ? (any version that supports "groff -Tps -man [in] [out]")
ps2pdf (gs) ?

View File

@@ -3,6 +3,15 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
78. curl and libcurl don't always signal the client properly when "sending"
zero bytes files - it makes for example the command line client not creating
any file at all. Like when using FTP.
http://curl.haxx.se/bug/view.cgi?id=3438362
77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
"absuses" 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
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

View File

@@ -328,7 +328,7 @@ POST (HTTP)
If the content-type is not specified, curl will try to guess from the file
extension (it only knows a few), or use the previously specified type (from
an earlier file if several files are specified in a list) or else it will
using the default type 'text/plain'.
use the default type 'application/octet-stream'.
Emulate a fill-in form with -F. Let's say you fill in three fields in a
form. One field is a file name which to post, one field is your name and one

0
docs/README.cmake Executable file → Normal file
View File

View File

@@ -14,9 +14,11 @@ Adrian Schuur
Adriano Meirelles
Akos Pasztory
Alan Pinstein
Albert Chin
Albert Chin-A-Young
Albert Choy
Ale Vesely
Alejandro Alvarez
Aleksandar Milivojevic
Alessandro Vesely
Alex Bligh
@@ -32,6 +34,7 @@ Alexander Zhuravlev
Alexey Borzov
Alexey Pesternikov
Alexey Simak
Alexey Zakhlestin
Alexis Carvalho
Alfred Gebert
Allen Pulsifer
@@ -66,6 +69,7 @@ Andy Tsouladze
Angus Mackay
Anthony Bryan
Antoine Calando
Anton Bychkov
Anton Kalmykov
Arkadiusz Miskiewicz
Armel Asselin
@@ -140,6 +144,7 @@ Christophe Legry
Christopher Conroy
Christopher Palow
Christopher R. Palmer
Christopher Stone
Ciprian Badescu
Claes Jakobsson
Clarence Gardner
@@ -225,6 +230,7 @@ Dmitry Rechkin
Dolbneff A.V
Domenico Andreoli
Dominick Meglio
Dominique Leuenberger
Doug Kaufman
Doug Porter
Douglas E. Wegscheid
@@ -265,6 +271,7 @@ Erwin Authried
Eugene Kotlyarov
Evan Jordan
Eygene Ryabinkin
Fabian Hiernaux
Fabian Keil
Fabrizio Ammollo
Fedor Karpelevitch
@@ -277,6 +284,7 @@ Frank Keeney
Frank McGeough
Frank Meier
Frank Ticheler
Frank Van Uffelen
Fred Machado
Fred New
Fred Noz
@@ -306,6 +314,7 @@ Giuseppe Attardi
Giuseppe D'Ambrosio
Glen Nakamura
Glen Scott
Gokhan Sengun
Grant Erickson
Greg Hewgill
Greg Morse
@@ -393,6 +402,7 @@ Jeffrey Pohlmeyer
Jeremy Friesner
Jerome Muffat-Meridol
Jerome Vouillon
Jerry Wu
Jes Badwal
Jesper Jensen
Jesse Noller
@@ -442,6 +452,7 @@ Juergen Wilke
Jukka Pihl
Julian Noble
Julien Chaffraix
Julien Royer
Jun-ichiro itojun Hagino
Jurij Smakov
Justin Fletcher
@@ -520,12 +531,14 @@ Marc Boucher
Marc Kleine-Budde
Marcel Roelofs
Marcelo Juchem
Marcin Adamski
Marcin Konicki
Marco G. Salvagno
Marco Maggi
Marcus Sundberg
Marcus Webster
Mario Schroeder
Mark Brand
Mark Butler
Mark Davies
Mark Eichin
@@ -813,10 +826,12 @@ Sven Wegener
S<EFBFBD>bastien Willemijns
T. Bharath
T. Yamada
Taneli Vahakangas
Tanguy Fautre
Temprimus
Thomas J. Moore
Thomas Klausner
Thomas L. Shinnick
Thomas Lopatic
Thomas Schwinge
Thomas Tonino
@@ -825,6 +840,7 @@ Tim Baker
Tim Bartley
Tim Chen
Tim Costello
Tim Harder
Tim Newsome
Tim Sneddon
Tinus van den Berg
@@ -840,6 +856,7 @@ Tom Mattison
Tom Moers
Tom Mueller
Tom Regner
Tom Wright
Tom Zerucha
Tomas Pospisek
Tomas Szepe
@@ -869,6 +886,7 @@ Vincent Sanders
Vincent Torri
Vlad Grachov
Vlad Ureche
Vladimir Grishchenko
Vladimir Lazarenko
Vojtech Janota
Vojtech Minarik
@@ -886,6 +904,7 @@ Xavier Bouchoux
Yang Tse
Yarram Sunil
Yehoshua Hershberg
Yukihiro Kawada
Yuriy Sosov
Yves Lejeune
Zmey Petroff

View File

@@ -17,6 +17,7 @@
1.4 signal-based resolver timeouts
1.5 get rid of PATH_MAX
1.6 progress callback without doubles
1.7 Happy Eyeball dual stack connect
2. libcurl - multi interface
2.1 More non-blocking
@@ -147,6 +148,19 @@
have both co-exist for a forseeable time until we can remove the double-using
one.
1.7 Happy Eyeball dual stack connect
In order to make alternative technologies not suffer when transitioning, like
when introducing IPv6 as an alternative to IPv4 and there are more than one
option existing simultaneously there are reasons to reconsider internal
choices.
To make libcurl do blazing fast IPv6 in a dual-stack configuration, this needs
to be addressed:
http://tools.ietf.org/html/draft-ietf-v6ops-happy-eyeballs-07
2. libcurl - multi interface
2.1 More non-blocking
@@ -156,7 +170,6 @@
- Name resolves on non-windows unless c-ares is used
- NSS SSL connections
- Active FTP connections
- HTTP proxy CONNECT operations
- SOCKS proxy handshakes
- file:// transfers

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -434,13 +434,15 @@ may be loaded.
If this option is used several times, the last one will be used.
.IP "--capath <CA certificate directory>"
(SSL) Tells curl to use the specified certificate directory to verify the
peer. The certificates must be in PEM format, and if curl is built against
OpenSSL, the directory must have been processed using the c_rehash utility
supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to
make SSL-connections much more efficiently than using \fI--cacert\fP if the
\fI--cacert\fP file contains many CA certificates.
peer. Multiple paths can be provided by separating them with ":" (e.g.
\&"path1:path2:path3"). The certificates must be in PEM format, and if curl is
built against OpenSSL, the directory must have been processed using the
c_rehash utility supplied with OpenSSL. Using \fI--capath\fP can allow
OpenSSL-powered curl to make SSL-connections much more efficiently than using
\fI--cacert\fP if the \fI--cacert\fP file contains many CA certificates.
If this option is used several times, the last one will be used.
If this option is set, the default capath value will be ignored, and if it is
used several times, the last one will be used.
.IP "-f, --fail"
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
to better enable scripts etc to better deal with failed attempts. In
@@ -1322,8 +1324,7 @@ implementation does not. The option \fI--socks5-gssapi-nec\fP allows the
unprotected exchange of the protection mode negotiation. (Added in 7.19.4).
.IP "--stderr <file>"
Redirect all writes to stderr to the specified file instead. If the file name
is a plain '-', it is instead written to stdout. This option has no point when
you're using a shell with decent redirecting capabilities.
is a plain '-', it is instead written to stdout.
If this option is used several times, the last one will be used.
.IP "-t, --telnet-option <OPT=val>"

View File

@@ -18,12 +18,15 @@ http-post
httpcustomheader
httpput
https
imap
multi-app
multi-debugcallback
multi-double
multi-post
multi-single
persistant
pop3s
pop3slist
post-callback
postit2
progressfunc
@@ -37,3 +40,4 @@ simplesmtp
simplessl
smtp-multi
smtp-tls
url2file

View File

@@ -5,7 +5,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
persistant post-callback postit2 sepheaders simple simplepost simplessl \
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve \
progressfunc
progressfunc pop3s pop3slist imap url2file
# These examples require external dependencies that may not be commonly
# available on POSIX systems, so don't bother attempting to compile them here.

View File

@@ -58,7 +58,7 @@ endif
ifndef LIBIDN_PATH
LIBIDN_PATH = ../../../libidn-1.18
endif
# Edit the path below to point to the base of your MS idndlpackage.
# Edit the path below to point to the base of your MS IDN package.
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815
ifndef WINIDN_PATH

View File

@@ -55,6 +55,7 @@ htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
http-post.c - HTTP POST
httpput.c - HTTP PUT a local file
https.c - simple HTTPS transfer
imap.c - simple IMAP transfer
multi-app.c - a multi-interface app
multi-debugcallback.c - a multi-interface app using the debug callback
multi-double.c - a multi-interface app doing two simultaneous transfers
@@ -63,6 +64,8 @@ multi-single.c - a multi-interface app getting a single file
multithread.c - an example using multi-treading transferring multiple files
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
persistant.c - request two URLs with a persistent connection
pop3s.c - POP3S transfer
pop3slist.c - POP3S LIST
post-callback.c - send a HTTP POST using a callback
postit2.c - send a HTTP multipart formpost
sampleconv.c - showing how a program on a non-ASCII platform would invoke
@@ -73,4 +76,5 @@ simple.c - the most simple download a URL source
simplepost.c - HTTP POST
simplessl.c - HTTPS example with certificates many options set
synctime.c - Sync local time by extracting date from remote HTTP servers
url2file.c - download a document and store it in a file
10-at-a-time.c - Download many files simultaneously, 10 at a time.

View File

@@ -27,6 +27,7 @@
# ifdef __VMS
typedef int intptr_t;
# endif
# include <stdint.h>
# include <unistd.h>
#endif
#include <sys/types.h>

View File

@@ -239,8 +239,7 @@ static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) {
SSL_CTX_set_cipher_list(ctx,"RC4-MD5");
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
X509_STORE_add_cert(ctx->cert_store,sk_X509_value(p->ca,
sk_X509_num(p->ca)-1));
X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), sk_X509_value(p->ca, sk_X509_num(p->ca)-1));
SSL_CTX_set_verify_depth(ctx,2);

View File

@@ -36,6 +36,7 @@
#else
#include <sys/types.h> /* socket types */
#include <sys/socket.h> /* socket definitions */
#include <netinet/in.h>
#include <arpa/inet.h> /* inet (3) funtions */
#include <unistd.h> /* misc. UNIX functions */
#endif

44
docs/examples/imap.c Normal file
View File

@@ -0,0 +1,44 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
/* This will fetch the mailbox named "foobar" */
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/foobar");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return (int)res;
}

68
docs/examples/pop3s.c Normal file
View File

@@ -0,0 +1,68 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
/* This will only fetch the message with ID "1" of the given mailbox */
curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/1");
#ifdef SKIP_PEER_VERIFICATION
/*
* If you want to connect to a site who isn't using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the
* verification of the server's certificate. This makes the connection
* A LOT LESS SECURE.
*
* If you have a CA cert for the server stored someplace else than in the
* default bundle, then the CURLOPT_CAPATH option might come handy for
* you.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERFICATION
/*
* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

68
docs/examples/pop3slist.c Normal file
View File

@@ -0,0 +1,68 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
/* This will list every message of the given mailbox */
curl_easy_setopt(curl, CURLOPT_URL, "pop3s://user@pop.example.com/");
#ifdef SKIP_PEER_VERIFICATION
/*
* If you want to connect to a site who isn't using a certificate that is
* signed by one of the certs in the CA bundle you have, you can skip the
* verification of the server's certificate. This makes the connection
* A LOT LESS SECURE.
*
* If you have a CA cert for the server stored someplace else than in the
* default bundle, then the CURLOPT_CAPATH option might come handy for
* you.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
#ifdef SKIP_HOSTNAME_VERFICATION
/*
* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure.
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

View File

@@ -22,12 +22,32 @@
#include <stdio.h>
#include <curl/curl.h>
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
struct myprogress {
double lastruntime;
CURL *curl;
};
static int progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
double curtime = 0;
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
/* under certain circumstances it may be desirable for certain functionality
to only run every N seconds, in order to do this the transaction time can
be used */
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
myp->lastruntime = curtime;
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
ulnow, ultotal, dlnow, dltotal);
@@ -40,11 +60,17 @@ int main(void)
{
CURL *curl;
CURLcode res=0;
struct myprogress prog;
curl = curl_easy_init();
if(curl) {
prog.lastruntime = 0;
prog.curl = curl;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);

81
docs/examples/url2file.c Normal file
View File

@@ -0,0 +1,81 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curl/curl.h>
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
int main(int argc, char *argv[])
{
CURL *curl_handle;
static const char *pagefilename = "page.out";
FILE *pagefile;
if(argc < 2 ) {
printf("Usage: %s <URL>\n", argv[0]);
return 1;
}
curl_global_init(CURL_GLOBAL_ALL);
/* init the curl session */
curl_handle = curl_easy_init();
/* set URL to get here */
curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]);
/* Switch on full protocol/debug output while testing */
curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L);
/* disable progress meter, set to 0L to enable and disable debug output */
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
/* send all data to this function */
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
/* open the file */
pagefile = fopen(pagefilename, "wb");
if (pagefile) {
/* write the page body to this file handle. CURLOPT_FILE is also known as
CURLOPT_WRITEDATA*/
curl_easy_setopt(curl_handle, CURLOPT_FILE, pagefile);
/* get it! */
curl_easy_perform(curl_handle);
/* close the header file */
fclose(pagefile);
}
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);
return 0;
}

View File

@@ -90,7 +90,7 @@ my @recent = reverse sort sortversions keys %used;
# the most recent symbol
my $newsym = $recent[0];
# the most recent version
my $newver = $doc{$newsym};
my $newver = $doc{$newsym};
print "The scanned source uses these symbols introduced in $newver:\n";

View File

@@ -82,7 +82,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
EXTRA_DIST = $(man_MANS) $(HTMLPAGES) index.html $(PDFPAGES) libcurl.m4 ABI \
symbols-in-versions
symbols-in-versions symbols.pl
MAN2HTML= roffit --mandir=. < $< >$@
SUFFIXES = .3 .html

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -294,10 +294,9 @@ argument in the sockopt callback set with \fICURLOPT_SOCKOPTFUNCTION\fP.
Function pointer that should match the \fIcurl_opensocket_callback\fP
prototype found in \fI<curl/curl.h>\fP. This function gets called by libcurl
instead of the \fIsocket(2)\fP call. The callback's \fIpurpose\fP argument
identifies the exact purpose for this particular socket, and currently only
one value is supported: \fICURLSOCKTYPE_IPCXN\fP for the primary connection
(meaning the control connection in the FTP case). Future versions of libcurl
may support more purposes. It passes the resolved peer address as a
identifies the exact purpose for this particular socket:
\fICURLSOCKTYPE_IPCXN\fP is for IP based connections. Future versions of
libcurl may support more purposes. It passes the resolved peer address as a
\fIaddress\fP argument so the callback can modify the address or refuse to
connect at all. The callback function should return the socket or
\fICURL_SOCKET_BAD\fP in case no connection should be established or any error
@@ -595,8 +594,8 @@ terminated string which must be URL-encoded in the following format:
scheme://host:port/path
For a greater explanation of the format please see RFC 2396
(http://curl.haxx.se/rfc/rfc2396.txt).
For a greater explanation of the format please see RFC 3986
(http://curl.haxx.se/rfc/rfc3986.txt).
If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
etc), libcurl will attempt to resolve which protocol to use based on the
@@ -844,6 +843,15 @@ negotiation. (Added in 7.19.4).
Pass a char * as parameter. This sets the interface name to use as outgoing
network interface. The name can be an interface name, an IP address, or a host
name.
Starting with 7.24.0: If the parameter starts with "if!" then it is treated as
only as interface name and no attempt will ever be named to do treat it as an
IP address or to do name resolution on it. If the parameter starts with
\&"host!" it is treated as either an IP address or a hostname. Hostnames are
resolved synchronously. Using the if! format is highly recommended when using
the multi interfaces to avoid allowing the code to block. If "if!" is
specified but the parameter does not match an existing interface,
CURLE_INTERFACE_FAILED is returned.
.IP CURLOPT_LOCALPORT
Pass a long. This sets the local port number of the socket used for
connection. This can be used in combination with \fICURLOPT_INTERFACE\fP and
@@ -1337,7 +1345,7 @@ option and thus you need to concatenate them all in one single string. Set
multiple cookies in one string like this: "name1=content1; name2=content2;"
etc.
This option sets the cookie header explictly in the outgoing request(s). If
This option sets the cookie header explicitly in the outgoing request(s). If
multiple requests are done due to authentication, followed redirections or
similar, they will all get this cookie passed on.
@@ -1485,9 +1493,9 @@ fully valid list of 'struct curl_slist' structs properly filled in with text
strings. Use \fIcurl_slist_append(3)\fP to append strings (commands) to the
list, and clear the entire list afterwards with
\fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a NULL
to this option. When speaking to a FTP server, prefix the command with an
asterisk (*) to make libcurl continue even if the command fails as by default
libcurl will stop at first failure.
to this option. When speaking to a FTP (or SFTP since 7.24.0) server, prefix
the command with an asterisk (*) to make libcurl continue even if the command
fails as by default libcurl will stop at first failure.
The set of valid FTP commands depends on the server (see RFC959 for a list of
mandatory commands).
@@ -1842,6 +1850,9 @@ as a long. See also \fICURLOPT_INFILESIZE_LARGE\fP.
For uploading using SCP, this option or \fICURLOPT_INFILESIZE_LARGE\fP is
mandatory.
When sending emails using SMTP, this command can be used to specify the
optional SIZE parameter for the MAIL FROM command. (Added in 7.23.0)
This option does not limit how much data libcurl will actually send, as that
is controlled entirely by what the read callback returns.
.IP CURLOPT_INFILESIZE_LARGE
@@ -1971,9 +1982,9 @@ re-use (default behavior).
.IP CURLOPT_CONNECTTIMEOUT
Pass a long. It should contain the maximum time in seconds that you allow the
connection to the server to take. This only limits the connection phase, once
it has connected, this option is of no more use. Set to zero to disable
connection timeout (it will then only timeout on the system's internal
timeouts). See also the \fICURLOPT_TIMEOUT\fP option.
it has connected, this option is of no more use. Set to zero to switch to the
default built-in connection timeout - 300 seconds. See also the
\fICURLOPT_TIMEOUT\fP option.
In unix-like systems, this might cause signals to be used unless
\fICURLOPT_NOSIGNAL\fP is set.
@@ -2045,6 +2056,24 @@ resolves, by including a string in the linked list that uses the format
and port number must exactly match what was already added previously.
(Added in 7.21.3)
.IP CURLOPT_DNS_SERVERS
Set the list of DNS servers to be used instead of the system default.
The format of the dns servers option is:
host[:port][,host[:port]]...
For example:
192.168.1.100,192.168.1.101,3.4.5.6
This option requires that libcurl was built with a resolver backend that
supports this operation. The c-ares backend is the only such one.
(Added in 7.24.0)
.IP CURLOPT_ACCEPTTIMEOUT_MS
Pass a long telling libcurl the maximum number of milliseconds to wait for a
server to connect back to libcurl when an active FTP connection is used. If no
timeout is set, the internal default of 60000 will be used. (Added in 7.24.0)
.SH SSL and SECURITY OPTIONS
.IP CURLOPT_SSLCERT
Pass a pointer to a zero terminated string as parameter. The string should be

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
.\" *
.\" * This software is licensed as described in the file COPYING, which
.\" * you should have received as part of this distribution. The terms
@@ -23,9 +23,9 @@
.SH NAME
curl_easy_strerror - return string describing error code
.SH SYNOPSIS
.nf
.B #include <curl/curl.h>
.BI "const char *curl_easy_strerror(CURLcode " errornum ");"
#include <curl/curl.h>
const char *curl_easy_strerror(CURLcode errornum);
.SH DESCRIPTION
The curl_easy_strerror() function returns a string describing the CURLcode
error code passed in the argument \fIerrornum\fP.

View File

@@ -66,9 +66,15 @@ remote server is probably not an OK FTP server.
.IP "CURLE_REMOTE_ACCESS_DENIED (9)"
We were denied access to the resource given in the URL. For FTP, this occurs
while trying to change to the remote directory.
.IP "CURLE_FTP_ACCEPT_FAILED (10)"
While waiting for the server to connect back when an active FTP session is
used, an error code was sent over the control connection or similar.
.IP "CURLE_FTP_WEIRD_PASS_REPLY (11)"
After having sent the FTP password to the server, libcurl expects a proper
reply. This error code indicates that an unexpected code was returned.
.IP "CURLE_FTP_ACCEPT_TIMEOUT (12)"
During an active FTP session while waiting for the server to connect, the
\fICURLOPT_ACCEPTTIMOUT_MS\fP (or the internal default) timeout expired.
.IP "CURLE_FTP_WEIRD_PASV_REPLY (13)"
libcurl failed to get a sensible result back from the server as a response to
either a PASV or a EPSV command. The server is flawed.

View File

@@ -144,7 +144,6 @@ the future, you should be aware of the following current restrictions:
.nf
- Name resolves unless the c-ares or threaded-resolver backends are used
- NSS SSL connections
- Active FTP connections
- HTTP proxy CONNECT operations
- SOCKS proxy handshakes
- file:// transfers

View File

@@ -817,10 +817,6 @@ This header is required by HTTP 1.1 and even many 1.0 servers and should be
the name of the server we want to talk to. This includes the port number if
anything but default.
.IP "Pragma"
\&"no-cache". Tells a possible proxy to not grab a copy from the cache but to
fetch a fresh one.
.IP "Accept"
\&"*/*".
@@ -1303,9 +1299,7 @@ ones at any time), you start the transfers by calling
\fIcurl_multi_perform(3)\fP is asynchronous. It will only execute as little as
possible and then return back control to your program. It is designed to never
block. If it returns CURLM_CALL_MULTI_PERFORM you better call it again soon,
as that is a signal that it still has local data to send or remote data to
receive.
block.
The best usage of this interface is when you do a select() on all possible
file descriptors or sockets to know when to call libcurl again. This also
@@ -1341,9 +1335,21 @@ to figure out success on each individual transfer.
[ seeding, passwords, keys, certificates, ENGINE, ca certs ]
.SH "Sharing Data Between Easy Handles"
You can share some data between easy handles when the easy interface is used,
and some data is share automatically when you use the multi interface.
[ fill in ]
When you add easy handles to a multi handle, these easy handles will
automatically share a lot of the data that otherwise would be kept on a
per-easy handle basis when the easy interface is used.
The DNS cache is shared between handles within a multi handle, making
subsequent name resolvings faster and the connection pool that is kept to
better allow persistent connections and connection re-use is shared. If you're
using the easy interface, you can still share these between specific easy
handles by using the share interface, see \fIlibcurl-share(3)\fP.
Some things are never shared automatically, not within multi handles, like for
example cookies so the only way to share that is with the share interface.
.SH "Footnotes"
.IP "[1]"

View File

@@ -146,7 +146,7 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
_libcurl_save_libs=$LIBS
LIBS="$LIBCURL $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <curl/curl.h>],[
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <curl/curl.h>]],[[
/* Try and use a few common options to force a failure if we are
missing symbols or can't link. */
int x;
@@ -158,7 +158,7 @@ x=CURLOPT_ERRORBUFFER;
x=CURLOPT_STDERR;
x=CURLOPT_VERBOSE;
if (x) ;
])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
]])],libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no)
CPPFLAGS=$_libcurl_save_cppflags
LIBS=$_libcurl_save_libs

View File

@@ -45,6 +45,8 @@ CURLE_COULDNT_RESOLVE_PROXY 7.1
CURLE_FAILED_INIT 7.1
CURLE_FILESIZE_EXCEEDED 7.10.8
CURLE_FILE_COULDNT_READ_FILE 7.1
CURLE_FTP_ACCEPT_FAILED 7.24.0
CURLE_FTP_ACCEPT_TIMEOUT 7.24.0
CURLE_FTP_ACCESS_DENIED 7.1
CURLE_FTP_BAD_DOWNLOAD_RESUME 7.1 7.1
CURLE_FTP_BAD_FILE_LIST 7.21.0
@@ -286,6 +288,7 @@ CURLOPTTYPE_FUNCTIONPOINT 7.1
CURLOPTTYPE_LONG 7.1
CURLOPTTYPE_OBJECTPOINT 7.1
CURLOPTTYPE_OFF_T 7.11.0
CURLOPT_ACCEPTTIMEOUT_MS 7.24.0
CURLOPT_ACCEPT_ENCODING 7.21.6
CURLOPT_ADDRESS_SCOPE 7.19.0
CURLOPT_APPEND 7.17.0
@@ -320,6 +323,7 @@ CURLOPT_DEBUGDATA 7.9.6
CURLOPT_DEBUGFUNCTION 7.9.6
CURLOPT_DIRLISTONLY 7.17.0
CURLOPT_DNS_CACHE_TIMEOUT 7.9.3
CURLOPT_DNS_SERVERS 7.24.0
CURLOPT_DNS_USE_GLOBAL_CACHE 7.9.3 7.11.1
CURLOPT_EGDSOCKET 7.7
CURLOPT_ENCODING 7.10

100
docs/libcurl/symbols.pl Executable file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/perl
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
#
# Experience has shown that the symbols-in-versions file is very useful to
# applications that want to build with a wide range of libcurl versions.
# It is however easy to get it wrong and the source gets a bit messy with all
# the fixed numerical comparisions.
#
# The point of this script is to provide an easy-to-use macro for libcurl-
# using applications to do preprocessor checks for specific libcurl defines,
# and yet make the code clearly show what the macro is used for.
#
# Run this script and generate libcurl-symbols.h and then use that header in
# a fashion similar to:
#
# #include "libcurl-symbols.h"
#
# #if LIBCURL_HAS(CURLOPT_MUTE)
# has mute
# #else
# no mute
# #endif
#
#
open F, "<symbols-in-versions";
sub str2num {
my ($str)=@_;
if($str =~ /([0-9]*)\.([0-9]*)\.*([0-9]*)/) {
return sprintf("0x%06x", $1<<16 | $2 << 8 | $3);
}
}
print <<EOS
#include <curl/curl.h>
#define LIBCURL_HAS(x) \\
(defined(x ## _FIRST) && (x ## _FIRST <= LIBCURL_VERSION_NUM) && \\
(!defined(x ## _LAST) || ( x ## _LAST >= LIBCURL_VERSION_NUM)))
EOS
;
while(<F>) {
if(/^(CURL[^ ]*)[ \t]*(.*)/) {
my ($sym, $vers)=($1, $2);
my $intr;
my $rm;
my $dep;
# is there removed info?
if($vers =~ /([\d.]+)[ \t-]+([\d.]+)[ \t]+([\d.]+)/) {
($intr, $dep, $rm)=($1, $2, $3);
}
# is it a dep-only line?
elsif($vers =~ /([\d.]+)[ \t-]+([\d.]+)/) {
($intr, $dep)=($1, $2);
}
else {
$intr = $vers;
}
my $inum = str2num($intr);
print <<EOS
#define ${sym}_FIRST $inum /* Added in $intr */
EOS
;
my $irm = str2num($rm);
if($rm) {
print <<EOS
#define ${sym}_LAST $irm /* Last featured in $rm */
EOS
;
}
}
}

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -69,7 +69,7 @@
require it! */
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
defined(ANDROID) || \
defined(ANDROID) || defined(__ANDROID__) || \
(defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
#include <sys/select.h>
#endif
@@ -411,9 +411,12 @@ typedef enum {
CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server
due to lack of access - when login fails
this is not returned. */
CURLE_OBSOLETE10, /* 10 - NOT USED */
CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for
7.15.4, reused in Dec 2011 for 7.24.0]*/
CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */
CURLE_OBSOLETE12, /* 12 - NOT USED */
CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server
[was obsoleted in August 2007 for 7.17.0,
reused in Dec 2011 for 7.24.0]*/
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
CURLE_FTP_CANT_GET_HOST, /* 15 */
@@ -511,13 +514,16 @@ typedef enum {
CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */
CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
CURL_LAST /* never use! */
} CURLcode;
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
the obsolete stuff removed! */
/* Previously obsoletes error codes re-used in 7.24.0 */
#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
/* compatibility with older names */
#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
@@ -1486,6 +1492,13 @@ typedef enum {
/* allow GSSAPI credential delegation */
CINIT(GSSAPI_DELEGATION, LONG, 210),
/* Set the name servers to use for DNS resolution */
CINIT(DNS_SERVERS, OBJECTPOINT, 211),
/* Time-out accept operations (currently for FTP only) after this amount
of miliseconds. */
CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

View File

@@ -30,12 +30,12 @@
/* This is the version number of the libcurl package from which this header
file origins: */
#define LIBCURL_VERSION "7.23.0-DEV"
#define LIBCURL_VERSION "7.24.0-DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBCURL_VERSION_MAJOR 7
#define LIBCURL_VERSION_MINOR 23
#define LIBCURL_VERSION_MINOR 24
#define LIBCURL_VERSION_PATCH 0
/* This is the numeric version of the libcurl version number, meant for easier
@@ -53,7 +53,7 @@
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBCURL_VERSION_NUM 0x071700
#define LIBCURL_VERSION_NUM 0x071800
/*
* This is the date and time when the full source package was created. The

1
lib/.gitignore vendored
View File

@@ -10,3 +10,4 @@ libcurl.plist.dist
libcurl.vcproj
vc6libcurl.dsp
Makefile.vc10.dist
libcurl.vers

View File

@@ -116,7 +116,11 @@ if MIMPURE
MIMPURE = -mimpure-text
endif
libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(LIBCURL_LIBS)
if VERSIONED_SYMBOLS
VERSIONED_SYMBOLS = -Wl,--version-script=libcurl.vers
endif
libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(VERSIONED_SYMBOLS) $(LIBCURL_LIBS)
# unit testing static library built only along with unit tests
if BUILD_UNITTESTS

View File

@@ -41,7 +41,7 @@ endif
ifndef LIBIDN_PATH
LIBIDN_PATH = ../../libidn-1.18
endif
# Edit the path below to point to the base of your MS idndlpackage.
# Edit the path below to point to the base of your MS IDN package.
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
# http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ad6158d7-ddba-416a-9109-07607425a815
ifndef WINIDN_PATH

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -26,9 +26,11 @@
* Telnet option defines. Add more here if in need.
*/
#define CURL_TELOPT_BINARY 0 /* binary 8bit data */
#define CURL_TELOPT_ECHO 1 /* just echo! */
#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */
#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */
#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */
#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */
#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */

View File

@@ -227,18 +227,19 @@ int Curl_resolver_getsock(struct connectdata *conn,
struct timeval maxtime;
struct timeval timebuf;
struct timeval *timeout;
long milli;
int max = ares_getsock((ares_channel)conn->data->state.resolver,
(ares_socket_t *)socks, numsocks);
maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
maxtime.tv_usec = 0;
timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
&timebuf);
Curl_expire(conn->data,
(timeout->tv_sec * 1000) + (timeout->tv_usec/1000));
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
if(milli == 0)
milli += 10;
Curl_expire(conn->data, milli);
return max;
}
@@ -330,9 +331,12 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
res->temp_ai = NULL;
destroy_async_data(&conn->async);
if(!conn->async.dns) {
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
failf(data, "Could not resolve %s: %s (%s)",
conn->bits.proxy?"proxy":"host",
conn->host.dispname,
ares_strerror(conn->async.status));
return CURLE_COULDNT_RESOLVE_HOST;
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
*dns = conn->async.dns;
}
@@ -418,7 +422,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(!conn->async.dns) {
/* a name was not resolved */
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
if(conn->bits.httpproxy) {
if(conn->bits.proxy) {
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
@@ -428,7 +432,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
}
}
else if(conn->async.done) {
if(conn->bits.httpproxy) {
if(conn->bits.proxy) {
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_PROXY;
@@ -600,4 +604,31 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
}
return NULL; /* no struct yet */
}
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
CURLcode result = CURLE_NOT_BUILT_IN;
#if (ARES_VERSION >= 0x010704)
int ares_result = ares_set_servers_csv(data->state.resolver, servers);
switch(ares_result) {
case ARES_SUCCESS:
result = CURLE_OK;
break;
case ARES_ENOMEM:
result = CURLE_OUT_OF_MEMORY;
break;
case ARES_ENOTINITIALIZED:
case ARES_ENODATA:
case ARES_EBADSTR:
default:
result = CURLE_BAD_FUNCTION_ARGUMENT;
break;
}
#else /* too old c-ares version! */
(void)data;
(void)servers;
#endif
return result;
}
#endif /* CURLRES_ARES */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -175,7 +175,6 @@ struct thread_sync_data {
struct thread_data {
curl_thread_t thread_hnd;
curl_socket_t dummy_sock;
unsigned int poll_interval;
int interval_end;
struct thread_sync_data tsd;
@@ -329,9 +328,6 @@ static void destroy_async_data (struct Curl_async *async)
if(async->os_specific) {
struct thread_data *td = (struct thread_data*) async->os_specific;
if(td->dummy_sock != CURL_SOCKET_BAD)
sclose(td->dummy_sock);
if(td->thread_hnd != curl_thread_t_null)
Curl_thread_join(&td->thread_hnd);
@@ -364,7 +360,6 @@ static bool init_resolve_thread (struct connectdata *conn,
conn->async.done = FALSE;
conn->async.status = 0;
conn->async.dns = NULL;
td->dummy_sock = CURL_SOCKET_BAD;
td->thread_hnd = curl_thread_t_null;
if(!init_thread_sync_data(&td->tsd, hostname, port, hints))
@@ -375,16 +370,6 @@ static bool init_resolve_thread (struct connectdata *conn,
if(!conn->async.hostname)
goto err_exit;
#ifdef WIN32
/* This socket is only to keep Curl_resolver_fdset() and select() happy;
* should never become signalled for read since it's unbound but
* Windows needs at least 1 socket in select().
*/
td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0);
if(td->dummy_sock == CURL_SOCKET_BAD)
goto err_exit;
#endif
#ifdef HAVE_GETADDRINFO
td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
#else
@@ -574,17 +559,9 @@ int Curl_resolver_getsock(struct connectdata *conn,
curl_socket_t *socks,
int numsocks)
{
const struct thread_data *td =
(const struct thread_data *) conn->async.os_specific;
if(td && td->dummy_sock != CURL_SOCKET_BAD) {
if(numsocks) {
/* return one socket waiting for readable, even though this is just
a dummy */
socks[0] = td->dummy_sock;
return GETSOCK_READSOCK(0);
}
}
(void)conn;
(void)socks;
(void)numsocks;
return 0;
}
@@ -696,4 +673,13 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
#endif /* !HAVE_GETADDRINFO */
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
(void)data;
(void)servers;
return CURLE_NOT_BUILT_IN;
}
#endif /* CURLRES_THREADED */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -89,18 +89,6 @@
#undef SO_NOSIGPIPE
#endif
struct Curl_sockaddr_ex {
int family;
int socktype;
int protocol;
unsigned int addrlen;
union {
struct sockaddr addr;
struct Curl_sockaddr_storage buff;
} _sa_ex_u;
};
#define sa_addr _sa_ex_u.addr
static bool verifyconnect(curl_socket_t sockfd, int *error);
static CURLcode
@@ -252,6 +240,10 @@ static CURLcode bindlocal(struct connectdata *conn,
int error;
char myhost[256] = "";
int done = 0; /* -1 for error, 1 for address found */
bool is_interface = FALSE;
bool is_host = FALSE;
static const char *if_prefix = "if!";
static const char *host_prefix = "host!";
/*************************************************************
* Select device to bind socket to
@@ -263,9 +255,20 @@ static CURLcode bindlocal(struct connectdata *conn,
memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
if(dev && (strlen(dev)<255) ) {
if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
dev += strlen(if_prefix);
is_interface = TRUE;
}
else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
dev += strlen(host_prefix);
is_host = TRUE;
}
/* interface */
if(Curl_if2ip(af, dev, myhost, sizeof(myhost))) {
if(!is_host && (is_interface || Curl_if_is_interface_name(dev))) {
if(Curl_if2ip(af, dev, myhost, sizeof(myhost)) == NULL)
return CURLE_INTERFACE_FAILED;
/*
* We now have the numerical IP address in the 'myhost' buffer
*/
@@ -841,56 +844,13 @@ singleipconnect(struct connectdata *conn,
struct SessionHandle *data = conn->data;
curl_socket_t sockfd;
CURLcode res = CURLE_OK;
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
struct sockaddr_in6 * const sa6 = (void *)&addr.sa_addr;
#endif
*sockp = CURL_SOCKET_BAD;
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold
* any protocol-specific address structures. The variable declared here
* will be used to pass / receive data to/from the fopensocket callback
* if this has been set, before that, it is initialized from parameters.
*/
addr.family = ai->ai_family;
addr.socktype = conn->socktype;
addr.protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
addr.addrlen = ai->ai_addrlen;
if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
addr.addrlen = sizeof(struct Curl_sockaddr_storage);
memcpy(&addr.sa_addr, ai->ai_addr, addr.addrlen);
*connected = FALSE; /* default is not connected */
if(data->set.fopensocket)
/*
* If the opensocket callback is set, all the destination address
* information is passed to the callback. Depending on this information the
* callback may opt to abort the connection, this is indicated returning
* CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
* the callback returns a valid socket the destination address information
* might have been changed and this 'new' address will actually be used
* here to connect.
*/
sockfd = data->set.fopensocket(data->set.opensocket_client,
CURLSOCKTYPE_IPCXN,
(struct curl_sockaddr *)&addr);
else
/* opensocket callback not set, so simply create the socket now */
sockfd = socket(addr.family, addr.socktype, addr.protocol);
if(sockfd == CURL_SOCKET_BAD)
/* no socket, no connection */
return CURLE_OK;
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
if(conn->scope && (addr.family == AF_INET6))
sa6->sin6_scope_id = conn->scope;
#endif
res = Curl_socket(conn, ai, &addr, &sockfd);
if(res)
return res;
/* store remote address and port used in this connection attempt */
if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
@@ -903,7 +863,7 @@ singleipconnect(struct connectdata *conn,
return CURLE_OK;
}
memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
infof(data, " Trying %s... ", conn->ip_addr_str);
infof(data, " Trying %s...\n", conn->ip_addr_str);
Curl_persistconninfo(conn);
@@ -1165,8 +1125,85 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
{
if(conn && conn->fclosesocket)
return conn->fclosesocket(conn->closesocket_client, sock);
else
return sclose(sock);
if(conn && conn->fclosesocket) {
if((sock == conn->sock[SECONDARYSOCKET]) &&
conn->sock_accepted[SECONDARYSOCKET])
/* if this socket matches the second socket, and that was created with
accept, then we MUST NOT call the callback but clear the accepted
status */
conn->sock_accepted[SECONDARYSOCKET] = FALSE;
else
return conn->fclosesocket(conn->closesocket_client, sock);
}
return sclose(sock);
}
/*
* Create a socket based on info from 'conn' and 'ai'.
*
* 'addr' should be a pointer to the correct struct to get data back, or NULL.
* 'sockfd' must be a pointer to a socket descriptor.
*
* If the open socket callback is set, used that!
*
*/
CURLcode Curl_socket(struct connectdata *conn,
const Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd)
{
struct SessionHandle *data = conn->data;
struct Curl_sockaddr_ex dummy;
if(!addr)
/* if the caller doesn't want info back, use a local temp copy */
addr = &dummy;
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold
* any protocol-specific address structures. The variable declared here
* will be used to pass / receive data to/from the fopensocket callback
* if this has been set, before that, it is initialized from parameters.
*/
addr->family = ai->ai_family;
addr->socktype = conn->socktype;
addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
addr->addrlen = ai->ai_addrlen;
if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
addr->addrlen = sizeof(struct Curl_sockaddr_storage);
memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
if(data->set.fopensocket)
/*
* If the opensocket callback is set, all the destination address
* information is passed to the callback. Depending on this information the
* callback may opt to abort the connection, this is indicated returning
* CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
* the callback returns a valid socket the destination address information
* might have been changed and this 'new' address will actually be used
* here to connect.
*/
*sockfd = data->set.fopensocket(data->set.opensocket_client,
CURLSOCKTYPE_IPCXN,
(struct curl_sockaddr *)addr);
else
/* opensocket callback not set, so simply create the socket now */
*sockfd = socket(addr->family, addr->socktype, addr->protocol);
if(*sockfd == CURL_SOCKET_BAD)
/* no socket, no connection */
return CURLE_FAILED_INIT;
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
if(conn->scope && (addr->family == AF_INET6)) {
struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
sa6->sin6_scope_id = conn->scope;
}
#endif
return CURLE_OK;
}

View File

@@ -24,6 +24,7 @@
#include "setup.h"
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
#include "sockaddr.h"
CURLcode Curl_is_connected(struct connectdata *conn,
int sockindex,
@@ -72,4 +73,35 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
void Curl_persistconninfo(struct connectdata *conn);
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
/*
* The Curl_sockaddr_ex structure is basically libcurl's external API
* curl_sockaddr structure with enough space available to directly hold any
* protocol-specific address structures. The variable declared here will be
* used to pass / receive data to/from the fopensocket callback if this has
* been set, before that, it is initialized from parameters.
*/
struct Curl_sockaddr_ex {
int family;
int socktype;
int protocol;
unsigned int addrlen;
union {
struct sockaddr addr;
struct Curl_sockaddr_storage buff;
} _sa_ex_u;
};
#define sa_addr _sa_ex_u.addr
/*
* Create a socket based on info from 'conn' and 'ai'.
*
* Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
* socket callback is set, used that!
*
*/
CURLcode Curl_socket(struct connectdata *conn,
const Curl_addrinfo *ai,
struct Curl_sockaddr_ex *addr,
curl_socket_t *sockfd);
#endif /* HEADER_CURL_CONNECT_H */

View File

@@ -63,6 +63,11 @@
# define DESKEY(x) &x
# endif
#elif defined(USE_GNUTLS_NETTLE)
# include <nettle/des.h>
# include <nettle/md4.h>
#elif defined(USE_GNUTLS)
# include <gcrypt.h>
@@ -133,7 +138,17 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key)
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
}
#if defined(USE_GNUTLS)
#if defined(USE_GNUTLS_NETTLE)
static void setup_des_key(const unsigned char *key_56,
struct des_ctx *des)
{
char key[8];
extend_key_56_to_64(key_56, key);
des_set_key(des, key);
}
#elif defined(USE_GNUTLS)
/*
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
@@ -233,6 +248,14 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
setup_des_key(keys + 14, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
DESKEY(ks), DES_ENCRYPT);
#elif defined(USE_GNUTLS_NETTLE)
struct des_ctx des;
setup_des_key(keys, &des);
des_encrypt(&des, 8, results, plaintext);
setup_des_key(keys + 7, &des);
des_encrypt(&des, 8, results + 8, plaintext);
setup_des_key(keys + 14, &des);
des_encrypt(&des, 8, results + 16, plaintext);
#elif defined(USE_GNUTLS)
gcry_cipher_hd_t des;
@@ -295,6 +318,12 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
setup_des_key(pw + 7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
DESKEY(ks), DES_ENCRYPT);
#elif defined(USE_GNUTLS_NETTLE)
struct des_ctx des;
setup_des_key(pw, &des);
des_encrypt(&des, 8, lmbuffer, magic);
setup_des_key(pw + 7, &des);
des_encrypt(&des, 8, lmbuffer + 8, magic);
#elif defined(USE_GNUTLS)
gcry_cipher_hd_t des;
@@ -357,6 +386,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
MD4_Init(&MD4pw);
MD4_Update(&MD4pw, pw, 2 * len);
MD4_Final(ntbuffer, &MD4pw);
#elif defined(USE_GNUTLS_NETTLE)
struct md4_ctx MD4pw;
md4_init(&MD4pw);
md4_update(&MD4pw, 2 * len, pw);
md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
#elif defined(USE_GNUTLS)
gcry_md_hd_t MD4pw;
gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -54,6 +54,13 @@
# endif
# include "ssluse.h"
#elif defined(USE_GNUTLS_NETTLE)
# include <nettle/md5.h>
# include <gnutls/gnutls.h>
# include <gnutls/crypto.h>
# define MD5_DIGEST_LENGTH 16
#elif defined(USE_GNUTLS)
# include <gcrypt.h>
@@ -688,7 +695,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
/* Get the machine's un-qualified host name as NTLM doesn't like the fully
qualified domain name */
if(Curl_gethostname(host, sizeof(host))) {
infof(data, "gethostname() failed, continuing without!");
infof(data, "gethostname() failed, continuing without!\n");
hostlen = 0;
}
else {
@@ -714,6 +721,9 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
MD5_CTX MD5pw;
Curl_ossl_seed(data); /* Initiate the seed if not already done */
RAND_bytes(entropy, 8);
#elif defined(USE_GNUTLS_NETTLE)
struct md5_ctx MD5pw;
gnutls_rnd(GNUTLS_RND_RANDOM, entropy, 8);
#elif defined(USE_GNUTLS)
gcry_md_hd_t MD5pw;
Curl_gtls_seed(data); /* Initiate the seed if not already done */
@@ -739,6 +749,10 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
MD5_Init(&MD5pw);
MD5_Update(&MD5pw, tmp, 16);
MD5_Final(md5sum, &MD5pw);
#elif defined(USE_GNUTLS_NETTLE)
md5_init(&MD5pw);
md5_update(&MD5pw, 16, tmp);
md5_digest(&MD5pw, 16, md5sum);
#elif defined(USE_GNUTLS)
gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -258,7 +258,7 @@ cyassl_connect_step2(struct connectdata *conn,
}
conssl->connecting_state = ssl_connect_3;
infof(data, "SSL connected");
infof(data, "SSL connected\n");
return CURLE_OK;
}
@@ -404,7 +404,12 @@ size_t Curl_cyassl_version(char *buffer, size_t size)
int Curl_cyassl_init(void)
{
#if (LIBCYASSL_VERSION_HEX >= 0x02000000)
if(SSL_library_init() != SSL_SUCCESS)
return 0;
#else
InitCyaSSL();
#endif
return 1;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -98,7 +98,7 @@ const struct Curl_handler Curl_handler_dict = {
ZERO_NULL, /* readwrite */
PORT_DICT, /* defport */
CURLPROTO_DICT, /* protocol */
PROTOPT_NONE /* flags */
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
@@ -178,7 +178,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
}
if((word == NULL) || (*word == (char)0)) {
infof(data, "lookup word is missing");
infof(data, "lookup word is missing\n");
word=(char *)"default";
}
if((database == NULL) || (*database == (char)0)) {
@@ -232,7 +232,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
}
if((word == NULL) || (*word == (char)0)) {
infof(data, "lookup word is missing");
infof(data, "lookup word is missing\n");
word=(char *)"default";
}
if((database == NULL) || (*database == (char)0)) {

View File

@@ -31,6 +31,7 @@
#include "urldata.h"
#include "warnless.h"
#include "non-ascii.h"
#include "escape.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -84,7 +85,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
char *testing_ptr = NULL;
unsigned char in; /* we need to treat the characters unsigned */
size_t newlen = alloc;
int strindex=0;
size_t strindex=0;
size_t length;
CURLcode res;
@@ -132,23 +133,29 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
}
/*
* Unescapes the given URL escaped string of given length. Returns a
* pointer to a malloced string with length given in *olen.
* If length == 0, the length is assumed to be strlen(string).
* If olen == NULL, no output length is stored.
* Curl_urldecode() URL decodes the given string.
*
* Optionally detects control characters (byte codes lower than 32) in the
* data and rejects such data.
*
* Returns a pointer to a malloced string in *ostring with length given in
* *olen. If length == 0, the length is assumed to be strlen(string).
*
*/
char *curl_easy_unescape(CURL *handle, const char *string, int length,
int *olen)
CURLcode Curl_urldecode(struct SessionHandle *data,
const char *string, size_t length,
char **ostring, size_t *olen,
bool reject_ctrl)
{
int alloc = (length?length:(int)strlen(string))+1;
size_t alloc = (length?length:strlen(string))+1;
char *ns = malloc(alloc);
unsigned char in;
int strindex=0;
size_t strindex=0;
unsigned long hex;
CURLcode res;
if(!ns)
return NULL;
return CURLE_OUT_OF_MEMORY;
while(--alloc > 0) {
in = *string;
@@ -164,16 +171,20 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
res = Curl_convert_from_network(handle, &in, 1);
res = Curl_convert_from_network(data, &in, 1);
if(res) {
/* Curl_convert_from_network calls failf if unsuccessful */
free(ns);
return NULL;
return res;
}
string+=2;
alloc-=2;
}
if(reject_ctrl && (in < 0x20)) {
free(ns);
return CURLE_URL_MALFORMAT;
}
ns[strindex++] = in;
string++;
@@ -183,7 +194,33 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
if(olen)
/* store output size */
*olen = strindex;
return ns;
if(ostring)
/* store output string */
*ostring = ns;
return CURLE_OK;
}
/*
* Unescapes the given URL escaped string of given length. Returns a
* pointer to a malloced string with length given in *olen.
* If length == 0, the length is assumed to be strlen(string).
* If olen == NULL, no output length is stored.
*/
char *curl_easy_unescape(CURL *handle, const char *string, int length,
int *olen)
{
char *str = NULL;
size_t inputlen = length;
size_t outputlen;
CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
FALSE);
if(res)
return NULL;
if(olen)
*olen = curlx_uztosi(outputlen);
return str;
}
/* For operating systems/environments that use different malloc/free

View File

@@ -1,5 +1,5 @@
#ifndef __ESCAPE_H
#define __ESCAPE_H
#ifndef HEADER_CURL_ESCAPE_H
#define HEADER_CURL_ESCAPE_H
/***************************************************************************
* _ _ ____ _
@@ -8,7 +8,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -25,5 +25,9 @@
/* Escape and unescape URL encoding in strings. The functions return a new
* allocated string or NULL if an error occurred. */
CURLcode Curl_urldecode(struct SessionHandle *data,
const char *string, size_t length,
char **ostring, size_t *olen,
bool reject_crlf);
#endif

View File

@@ -119,7 +119,7 @@ const struct Curl_handler Curl_handler_file = {
ZERO_NULL, /* readwrite */
0, /* defport */
CURLPROTO_FILE, /* protocol */
PROTOPT_NONETWORK /* flags */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
};

View File

@@ -156,8 +156,6 @@ static FormInfo * AddFormInfo(char *value,
/* then move the original 'more' to point to ourselves */
parent_form_info->more = form_info;
}
else
return NULL;
return form_info;
}
@@ -458,9 +456,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(current_form->value) {
if(current_form->flags & HTTPPOST_FILENAME) {
if(filename) {
if((current_form = AddFormInfo(strdup(filename),
NULL, current_form)) == NULL)
char *fname = strdup(filename);
if(!fname)
return_value = CURL_FORMADD_MEMORY;
else {
form = AddFormInfo(fname, NULL, current_form);
if(!form) {
Curl_safefree(fname);
return_value = CURL_FORMADD_MEMORY;
}
else {
form->value_alloc = TRUE;
current_form = form;
form = NULL;
}
}
}
else
return_value = CURL_FORMADD_NULL;
@@ -535,10 +545,21 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(current_form->contenttype) {
if(current_form->flags & HTTPPOST_FILENAME) {
if(contenttype) {
if((current_form = AddFormInfo(NULL,
strdup(contenttype),
current_form)) == NULL)
char *type = strdup(contenttype);
if(!type)
return_value = CURL_FORMADD_MEMORY;
else {
form = AddFormInfo(NULL, type, current_form);
if(!form) {
Curl_safefree(type);
return_value = CURL_FORMADD_MEMORY;
}
else {
form->contenttype_alloc = TRUE;
current_form = form;
form = NULL;
}
}
}
else
return_value = CURL_FORMADD_NULL;
@@ -596,6 +617,30 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
}
}
if(CURL_FORMADD_OK != return_value) {
/* On error, free allocated fields for all nodes of the FormInfo linked
list without deallocating nodes. List nodes are deallocated later on */
FormInfo *ptr;
for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
if(ptr->name_alloc) {
Curl_safefree(ptr->name);
ptr->name_alloc = FALSE;
}
if(ptr->value_alloc) {
Curl_safefree(ptr->value);
ptr->value_alloc = FALSE;
}
if(ptr->contenttype_alloc) {
Curl_safefree(ptr->contenttype);
ptr->contenttype_alloc = FALSE;
}
if(ptr->showfilename_alloc) {
Curl_safefree(ptr->showfilename);
ptr->showfilename_alloc = FALSE;
}
}
}
if(CURL_FORMADD_OK == return_value) {
/* go through the list, check for completeness and if everything is
* alright add the HttpPost item otherwise set return_value accordingly */
@@ -675,32 +720,39 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
prevtype = form->contenttype;
}
}
}
if(return_value) {
/* we return on error, free possibly allocated fields */
if(!form)
form = current_form;
if(form) {
if(form->name_alloc)
free(form->name);
if(form->value_alloc)
free(form->value);
if(form->contenttype_alloc)
free(form->contenttype);
if(form->showfilename_alloc)
free(form->showfilename);
if(CURL_FORMADD_OK != return_value) {
/* On error, free allocated fields for nodes of the FormInfo linked
list which are not already owned by the httppost linked list
without deallocating nodes. List nodes are deallocated later on */
FormInfo *ptr;
for(ptr = form; ptr != NULL; ptr = ptr->more) {
if(ptr->name_alloc) {
Curl_safefree(ptr->name);
ptr->name_alloc = FALSE;
}
if(ptr->value_alloc) {
Curl_safefree(ptr->value);
ptr->value_alloc = FALSE;
}
if(ptr->contenttype_alloc) {
Curl_safefree(ptr->contenttype);
ptr->contenttype_alloc = FALSE;
}
if(ptr->showfilename_alloc) {
Curl_safefree(ptr->showfilename);
ptr->showfilename_alloc = FALSE;
}
}
}
}
/* always delete the allocated memory before returning */
form = first_form;
while(form != NULL) {
FormInfo *delete_form;
delete_form = form;
form = form->more;
free (delete_form);
/* Always deallocate FormInfo linked list nodes without touching node
fields given that these have either been deallocated or are owned
now by the httppost linked list */
while(first_form) {
FormInfo *ptr = first_form->more;
Curl_safefree(first_form);
first_form = ptr;
}
return return_value;
@@ -996,12 +1048,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
struct curl_httppost *file;
CURLcode result = CURLE_OK;
curl_off_t size=0; /* support potentially ENORMOUS formposts */
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
char *boundary;
char *fileboundary=NULL;
char *fileboundary = NULL;
struct curl_slist* curList;
*finalform=NULL; /* default form is empty */
*finalform = NULL; /* default form is empty */
if(!post)
return result; /* no input => no output! */
@@ -1018,7 +1070,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
boundary);
if(result) {
free(boundary);
Curl_safefree(boundary);
return result;
}
/* we DO NOT include that line in the total size of the POST, since it'll be
@@ -1061,7 +1113,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
/* If used, this is a link to more file names, we must then do
the magic to include several files with the same field name */
Curl_safefree(fileboundary);
fileboundary = Curl_FormBoundary();
if(!fileboundary) {
result = CURLE_OUT_OF_MEMORY;
break;
}
result = AddFormDataf(&form, &size,
"\r\nContent-Type: multipart/mixed,"
@@ -1081,13 +1138,12 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(post->more) {
/* if multiple-file */
char *filebasename= NULL;
char *filebasename = NULL;
if(!file->showfilename) {
filebasename = strippath(file->contents);
if(!filebasename) {
Curl_formclean(&firstform);
free(boundary);
return CURLE_OUT_OF_MEMORY;
result = CURLE_OUT_OF_MEMORY;
break;
}
}
@@ -1097,8 +1153,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
fileboundary,
(file->showfilename?file->showfilename:
filebasename));
if(filebasename)
free(filebasename);
Curl_safefree(filebasename);
if(result)
break;
}
@@ -1115,8 +1170,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
"; filename=\"%s\"",
(post->showfilename?post->showfilename:
filebasename));
if(filebasename)
free(filebasename);
Curl_safefree(filebasename);
}
if(result)
@@ -1140,11 +1194,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
break;
curList = curList->next;
}
if(result) {
Curl_formclean(&firstform);
free(boundary);
return result;
}
if(result)
break;
result = AddFormDataf(&form, &size, "\r\n\r\n");
if(result)
@@ -1166,7 +1217,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(fileread) {
if(fileread != stdin) {
/* close the file again */
/* close the file */
fclose(fileread);
/* add the file name only - for later reading from this */
result = AddFormData(&form, FORM_FILE, file->contents, 0, &size);
@@ -1210,11 +1261,8 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
file = file->more;
} while(file && !result); /* for each specified file for this field */
if(result) {
Curl_formclean(&firstform);
free(boundary);
return result;
}
if(result)
break;
if(post->more) {
/* this was a multiple-file inclusion, make a termination file
@@ -1222,33 +1270,31 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
result = AddFormDataf(&form, &size,
"\r\n--%s--",
fileboundary);
free(fileboundary);
if(result)
break;
}
} while((post = post->next) != NULL); /* for each field */
if(result) {
Curl_formclean(&firstform);
free(boundary);
return result;
}
/* end-boundary for everything */
result = AddFormDataf(&form, &size,
"\r\n--%s--\r\n",
boundary);
if(CURLE_OK == result)
result = AddFormDataf(&form, &size,
"\r\n--%s--\r\n",
boundary);
if(result) {
Curl_formclean(&firstform);
free(boundary);
Curl_safefree(fileboundary);
Curl_safefree(boundary);
return result;
}
*sizep = size;
free(boundary);
Curl_safefree(fileboundary);
Curl_safefree(boundary);
*finalform=firstform;
*finalform = firstform;
return result;
}

470
lib/ftp.c
View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -108,6 +108,8 @@
#endif
/* Local API functions */
static void state(struct connectdata *conn,
ftpstate newstate);
static CURLcode ftp_sendquote(struct connectdata *conn,
struct curl_slist *quote);
static CURLcode ftp_quit(struct connectdata *conn);
@@ -132,7 +134,7 @@ static CURLcode ftp_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode ftp_connect(struct connectdata *conn, bool *done);
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
static CURLcode ftp_nextconnect(struct connectdata *conn);
static CURLcode ftp_do_more(struct connectdata *conn, bool *completed);
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
@@ -150,6 +152,11 @@ static void wc_data_dtor(void *ptr);
static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
curl_off_t filesize);
static CURLcode ftp_readresp(curl_socket_t sockfd,
struct pingpong *pp,
int *ftpcode,
size_t *size);
/* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \
return result
@@ -166,7 +173,7 @@ const struct Curl_handler Curl_handler_ftp = {
ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */
ftp_done, /* done */
ftp_nextconnect, /* do_more */
ftp_do_more, /* do_more */
ftp_connect, /* connect_it */
ftp_multi_statemach, /* connecting */
ftp_doing, /* doing */
@@ -178,7 +185,8 @@ const struct Curl_handler Curl_handler_ftp = {
ZERO_NULL, /* readwrite */
PORT_FTP, /* defport */
CURLPROTO_FTP, /* protocol */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
| PROTOPT_NOURLQUERY /* flags */
};
@@ -192,7 +200,7 @@ const struct Curl_handler Curl_handler_ftps = {
ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */
ftp_done, /* done */
ftp_nextconnect, /* do_more */
ftp_do_more, /* do_more */
ftp_connect, /* connect_it */
ftp_multi_statemach, /* connecting */
ftp_doing, /* doing */
@@ -205,7 +213,7 @@ const struct Curl_handler Curl_handler_ftps = {
PORT_FTPS, /* defport */
CURLPROTO_FTP | CURLPROTO_FTPS, /* protocol */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD /* flags */
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */
};
#endif
@@ -309,19 +317,16 @@ static bool isBadFtpString(const char *string)
/***********************************************************************
*
* AllowServerConnect()
* AcceptServerConnect()
*
* When we've issue the PORT command, we have told the server to connect
* to us. This function will sit and wait here until the server has
* connected.
* After connection request is received from the server this function is
* called to accept the connection and close the listening socket
*
*/
static CURLcode AllowServerConnect(struct connectdata *conn)
static CURLcode AcceptServerConnect(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
curl_socket_t sock = conn->sock[SECONDARYSOCKET];
long timeout_ms;
long interval_ms;
curl_socket_t s = CURL_SOCKET_BAD;
#ifdef ENABLE_IPV6
struct Curl_sockaddr_storage add;
@@ -330,47 +335,258 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
#endif
curl_socklen_t size = (curl_socklen_t) sizeof(add);
for(;;) {
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
size = sizeof(add);
if(timeout_ms < 0) {
/* if a timeout was already reached, bail out */
failf(data, "Timeout while waiting for server connect");
return CURLE_OPERATION_TIMEDOUT;
s=accept(sock, (struct sockaddr *) &add, &size);
}
Curl_closesocket(conn, sock); /* close the first socket */
if(CURL_SOCKET_BAD == s) {
failf(data, "Error accept()ing server connect");
return CURLE_FTP_PORT_FAILED;
}
infof(data, "Connection accepted from server\n");
conn->sock[SECONDARYSOCKET] = s;
curlx_nonblock(s, TRUE); /* enable non-blocking */
conn->sock_accepted[SECONDARYSOCKET] = TRUE;
return CURLE_OK;
}
/*
* ftp_timeleft_accept() returns the amount of milliseconds left allowed for
* waiting server to connect. If the value is negative, the timeout time has
* already elapsed.
*
* The start time is stored in progress.t_acceptdata - as set with
* Curl_pgrsTime(..., TIMER_STARTACCEPT);
*
*/
static long ftp_timeleft_accept(struct SessionHandle *data)
{
long timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
long other;
struct timeval now;
if(data->set.accepttimeout > 0)
timeout_ms = data->set.accepttimeout;
now = Curl_tvnow();
/* check if the generic timeout possibly is set shorter */
other = Curl_timeleft(data, &now, FALSE);
if(other && (other < timeout_ms))
/* note that this also works fine for when other happens to be negative
due to it already having elapsed */
timeout_ms = other;
else {
/* subtract elapsed time */
timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata);
if(!timeout_ms)
/* avoid returning 0 as that means no timeout! */
return -1;
}
return timeout_ms;
}
/***********************************************************************
*
* ReceivedServerConnect()
*
* After allowing server to connect to us from data port, this function
* checks both data connection for connection establishment and ctrl
* connection for a negative response regarding a failure in connecting
*
*/
static CURLcode ReceivedServerConnect(struct connectdata* conn, bool* received)
{
struct SessionHandle *data = conn->data;
curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
struct ftp_conn *ftpc = &conn->proto.ftpc;
struct pingpong *pp = &ftpc->pp;
int result;
long timeout_ms;
ssize_t nread;
int ftpcode;
*received = FALSE;
timeout_ms = ftp_timeleft_accept(data);
infof(data, "Checking for server connect\n");
if(timeout_ms < 0) {
/* if a timeout was already reached, bail out */
failf(data, "Accept timeout occurred while waiting server connect");
return CURLE_FTP_ACCEPT_TIMEOUT;
}
/* First check whether there is a cached response from server */
if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
/* Data connection could not be established, let's return */
infof(data, "There is negative response in cache while serv connect\n");
Curl_GetFTPResponse(&nread, conn, &ftpcode);
return CURLE_FTP_ACCEPT_FAILED;
}
result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
/* see if the connection request is already here */
switch (result) {
case -1: /* error */
/* let's die here */
failf(data, "Error while waiting for server connect");
return CURLE_FTP_ACCEPT_FAILED;
case 0: /* Server connect is not received yet */
break; /* loop */
default:
if(result & CURL_CSELECT_IN2) {
infof(data, "Ready to accept data connection from server\n");
*received = TRUE;
}
else if(result & CURL_CSELECT_IN) {
infof(data, "Ctrl conn has data while waiting for data conn\n");
Curl_GetFTPResponse(&nread, conn, &ftpcode);
if(ftpcode/100 > 3)
return CURLE_FTP_ACCEPT_FAILED;
return CURLE_FTP_WEIRD_SERVER_REPLY;
}
interval_ms = 1000; /* use 1 second timeout intervals */
if(timeout_ms < interval_ms)
interval_ms = timeout_ms;
break;
} /* switch() */
switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, interval_ms)) {
case -1: /* error */
/* let's die here */
failf(data, "Error while waiting for server connect");
return CURLE_FTP_PORT_FAILED;
case 0: /* timeout */
break; /* loop */
default:
/* we have received data here */
if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
size = sizeof(add);
return CURLE_OK;
}
s=accept(sock, (struct sockaddr *) &add, &size);
}
Curl_closesocket(conn, sock); /* close the first socket */
if(CURL_SOCKET_BAD == s) {
failf(data, "Error accept()ing server connect");
return CURLE_FTP_PORT_FAILED;
}
infof(data, "Connection accepted from server\n");
/***********************************************************************
*
* InitiateTransfer()
*
* After connection from server is accepted this function is called to
* setup transfer parameters and initiate the data transfer.
*
*/
static CURLcode InitiateTransfer(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
struct FTP *ftp = data->state.proto.ftp;
CURLcode result = CURLE_OK;
conn->sock[SECONDARYSOCKET] = s;
curlx_nonblock(s, TRUE); /* enable non-blocking */
return CURLE_OK;
} /* switch() */
if(conn->ssl[SECONDARYSOCKET].use) {
/* since we only have a plaintext TCP connection here, we must now
* do the TLS stuff */
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
if(result)
return result;
}
/* never reaches this point */
if(conn->proto.ftpc.state_saved == FTP_STOR) {
*(ftp->bytecountp)=0;
/* When we know we're uploading a specified file, we can get the file
size prior to the actual upload. */
Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
SECONDARYSOCKET, ftp->bytecountp);
}
else {
/* FTP download: */
Curl_setup_transfer(conn, SECONDARYSOCKET,
conn->proto.ftpc.retr_size_saved, FALSE,
ftp->bytecountp, -1, NULL); /* no upload here */
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
state(conn, FTP_STOP);
return CURLE_OK;
}
/***********************************************************************
*
* AllowServerConnect()
*
* When we've issue the PORT command, we have told the server to connect
* to us. This function
* - will sit and wait here until the server has connected for easy interface
* - will check whether data connection is established if so it is accepted
* for multi interface
*
*/
static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
{
struct SessionHandle *data = conn->data;
long timeout_ms;
long interval_ms;
CURLcode ret = CURLE_OK;
*connected = FALSE;
infof(data, "Preparing for accepting server on data port\n");
/* Save the time we start accepting server connect */
Curl_pgrsTime(data, TIMER_STARTACCEPT);
for(;;) {
timeout_ms = ftp_timeleft_accept(data);
if(timeout_ms < 0) {
/* if a timeout was already reached, bail out */
failf(data, "Accept timeout occurred while waiting server connect");
return CURLE_FTP_ACCEPT_TIMEOUT;
}
/* see if the connection request is already here */
ret = ReceivedServerConnect(conn, connected);
if(ret)
return ret;
if(*connected) {
ret = AcceptServerConnect(conn);
if(ret)
return ret;
ret = InitiateTransfer(conn);
if(ret)
return ret;
break; /* connection is accepted, break the loop */
}
else {
if(data->state.used_interface == Curl_if_easy) {
interval_ms = 1000;
if(timeout_ms < interval_ms)
interval_ms = timeout_ms;
/* sleep for 1 second and then continue */
Curl_socket_ready(CURL_SOCKET_BAD, CURL_SOCKET_BAD, interval_ms);
}
else {
/* Add timeout to multi handle and break out of the loop */
if(ret == CURLE_OK && *connected == FALSE) {
if(data->set.accepttimeout > 0)
Curl_expire(data, data->set.accepttimeout);
else
Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT);
}
break; /* connection was not accepted immediately */
}
}
}
return ret;
}
/* macro to check for a three-digit ftp status code at the start of the
@@ -666,6 +882,10 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
}
socks[0] = conn->sock[SECONDARYSOCKET];
if(ftpc->wait_data_conn) {
socks[1] = conn->sock[FIRSTSOCKET];
return GETSOCK_READSOCK(0) | GETSOCK_READSOCK(1);
}
return GETSOCK_READSOCK(0);
}
@@ -900,14 +1120,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
portsock = CURL_SOCKET_BAD;
error = 0;
for(ai = res; ai; ai = ai->ai_next) {
/*
* Workaround for AIX5 getaddrinfo() problem (it doesn't set ai_socktype):
*/
if(ai->ai_socktype == 0)
ai->ai_socktype = conn->socktype;
portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(portsock == CURL_SOCKET_BAD) {
result = Curl_socket(conn, ai, NULL, &portsock);
if(result) {
error = SOCKERRNO;
continue;
}
@@ -939,7 +1153,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
* the control connection instead and restart the port loop
*/
infof(data, "bind(port=%hu) on non-local address failed: %s", port,
infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
Curl_strerror(conn, error) );
sslen = sizeof(ss);
@@ -2157,11 +2371,10 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
}
static CURLcode ftp_state_stor_resp(struct connectdata *conn,
int ftpcode)
int ftpcode, ftpstate instate)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct FTP *ftp = data->state.proto.ftp;
if(ftpcode>=400) {
failf(data, "Failed FTP upload: %0d", ftpcode);
@@ -2169,41 +2382,29 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
return CURLE_UPLOAD_FAILED;
}
conn->proto.ftpc.state_saved = instate;
/* PORT means we are now awaiting the server to connect to us. */
if(data->set.ftp_use_port) {
/* BLOCKING */
/* PORT means we are now awaiting the server to connect to us. */
result = AllowServerConnect(conn);
bool connected;
result = AllowServerConnect(conn, &connected);
if(result)
return result;
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately\n");
/* as there's not necessarily an immediate action on the control
connection now, we halt the state machine */
state(conn, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
return CURLE_OK;
}
if(conn->ssl[SECONDARYSOCKET].use) {
/* since we only have a plaintext TCP connection here, we must now
do the TLS stuff */
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
/* BLOCKING */
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
if(result)
return result;
}
*(ftp->bytecountp)=0;
/* When we know we're uploading a specified file, we can get the file
size prior to the actual upload. */
Curl_pgrsSetUploadSize(data, data->set.infilesize);
/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
SECONDARYSOCKET, ftp->bytecountp);
state(conn, FTP_STOP);
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect a server response */
return result;
else
return InitiateTransfer(conn);
}
/* for LIST and RETR responses */
@@ -2284,22 +2485,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
else if(ftp->downloadsize > -1)
size = ftp->downloadsize;
if(data->set.ftp_use_port) {
/* BLOCKING */
result = AllowServerConnect(conn);
if(result)
return result;
}
if(conn->ssl[SECONDARYSOCKET].use) {
/* since we only have a plaintext TCP connection here, we must now
do the TLS stuff */
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
result = Curl_ssl_connect(conn, SECONDARYSOCKET);
if(result)
return result;
}
if(size > data->req.maxdownload && data->req.maxdownload > 0)
size = data->req.size = data->req.maxdownload;
else if((instate != FTP_LIST) && (data->set.prefer_ascii))
@@ -2311,11 +2496,25 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
infof(data, "Getting file with size: %" FORMAT_OFF_T "\n", size);
/* FTP download: */
Curl_setup_transfer(conn, SECONDARYSOCKET, size, FALSE,
ftp->bytecountp, -1, NULL); /* no upload here */
conn->proto.ftpc.state_saved = instate;
conn->proto.ftpc.retr_size_saved = size;
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
state(conn, FTP_STOP);
if(data->set.ftp_use_port) {
bool connected;
result = AllowServerConnect(conn, &connected);
if(result)
return result;
if(!connected) {
struct ftp_conn *ftpc = &conn->proto.ftpc;
infof(data, "Data conn was not available immediately\n");
state(conn, FTP_STOP);
ftpc->wait_data_conn = TRUE;
}
}
else
return InitiateTransfer(conn);
}
else {
if((instate == FTP_LIST) && (ftpcode == 450)) {
@@ -2463,7 +2662,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(pp->sendleft)
return Curl_pp_flushsend(pp);
/* we read a piece of response */
result = ftp_readresp(sock, pp, &ftpcode, &nread);
if(result)
return result;
@@ -2869,7 +3067,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
break;
case FTP_STOR:
result = ftp_state_stor_resp(conn, ftpcode);
result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
break;
case FTP_QUIT:
@@ -3085,8 +3283,11 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
case CURLE_BAD_DOWNLOAD_RESUME:
case CURLE_FTP_WEIRD_PASV_REPLY:
case CURLE_FTP_PORT_FAILED:
case CURLE_FTP_ACCEPT_FAILED:
case CURLE_FTP_ACCEPT_TIMEOUT:
case CURLE_FTP_COULDNT_SET_TYPE:
case CURLE_FTP_COULDNT_RETR_FILE:
case CURLE_PARTIAL_FILE:
case CURLE_UPLOAD_FAILED:
case CURLE_REMOTE_ACCESS_DENIED:
case CURLE_FILESIZE_EXCEEDED:
@@ -3457,28 +3658,54 @@ static CURLcode ftp_range(struct connectdata *conn)
/*
* ftp_nextconnect()
* ftp_do_more()
*
* This function shall be called when the second FTP (data) connection is
* connected.
*/
static CURLcode ftp_nextconnect(struct connectdata *conn)
static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
{
struct SessionHandle *data=conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
bool connected = FALSE;
/* the ftp struct is inited in ftp_connect() */
struct FTP *ftp = data->state.proto.ftp;
DEBUGF(infof(data, "DO-MORE phase starts\n"));
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
/* Ready to do more? */
if(connected) {
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
}
else
return result;
}
if(ftp->transfer <= FTPTRANSFER_INFO) {
/* a transfer is about to take place, or if not a file name was given
so we'll do a SIZE on it later and then we need the right TYPE first */
if(data->set.upload) {
if(ftpc->wait_data_conn == TRUE) {
bool serv_conned;
result = ReceivedServerConnect(conn, &serv_conned);
if(result)
return result; /* Failed to accept data connection */
if(serv_conned) {
/* It looks data connection is established */
result = AcceptServerConnect(conn);
ftpc->wait_data_conn = FALSE;
if(result == CURLE_OK)
result = InitiateTransfer(conn);
}
}
else if(data->set.upload) {
result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
if(result)
return result;
@@ -3517,8 +3744,11 @@ static CURLcode ftp_nextconnect(struct connectdata *conn)
too! */
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
/* end of transfer */
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
if(!ftpc->wait_data_conn) {
/* no waiting for the data connection so this is now complete */
*complete = TRUE;
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
}
return result;
}
@@ -3798,8 +4028,10 @@ static CURLcode wc_statemach(struct connectdata *conn)
static CURLcode ftp_do(struct connectdata *conn, bool *done)
{
CURLcode retcode = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
*done = FALSE; /* default to false */
ftpc->wait_data_conn = FALSE; /* default to no such wait */
/*
Since connections can be re-used between SessionHandles, this might be a
@@ -4169,8 +4401,10 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
struct FTP *ftp = conn->data->state.proto.ftp;
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected)
result = ftp_nextconnect(conn);
if(connected) {
bool completed;
result = ftp_do_more(conn, &completed);
}
if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
/* Failure detected, close the second socket if it was created already */

View File

@@ -139,6 +139,7 @@ struct ftp_conn {
already has been done */
bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent
caching the current directory */
bool wait_data_conn; /* this is set TRUE if data connection is waited */
char *prevpath; /* conn->path from the previous transfer */
char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
and others (A/I or zero) */
@@ -146,10 +147,15 @@ struct ftp_conn {
int count2; /* general purpose counter for the state machine */
int count3; /* general purpose counter for the state machine */
ftpstate state; /* always use ftp.c:state() to change state! */
ftpstate state_saved; /* transfer type saved to be reloaded after
data connection is established */
curl_off_t retr_size_saved; /* Size of retrieved file saved */
char * server_os; /* The target server operating system. */
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */
};
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */
#endif /* HEADER_CURL_FTP_H */

View File

@@ -46,6 +46,7 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
pro->t_nslookup = 0;
pro->t_connect = 0;
pro->t_appconnect = 0;
pro->t_pretransfer = 0;
pro->t_starttransfer = 0;
pro->timespent = 0;

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -34,7 +34,9 @@
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
#ifndef USE_GNUTLS_NETTLE
#include <gcrypt.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -85,8 +87,7 @@ static bool gtls_inited = FALSE;
# define USE_GNUTLS_PRIORITY_SET_DIRECT 1
# endif
# if (GNUTLS_VERSION_NUMBER >= 0x020c03)
# undef gnutls_transport_set_global_errno
# define gnutls_transport_set_global_errno(A) SET_ERRNO((A))
# define GNUTLS_MAPS_WINSOCK_ERRORS 1
# endif
#endif
@@ -107,9 +108,13 @@ static bool gtls_inited = FALSE;
* resort global errno variable using gnutls_transport_set_global_errno,
* with a transport agnostic error value. This implies that some winsock
* error translation must take place in these callbacks.
*
* Paragraph above applies to GNU TLS versions older than 2.12.3, since
* this version GNU TLS does its own internal winsock error translation
* using system_errno() function.
*/
#ifdef USE_WINSOCK
#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
# define gtls_EINTR 4
# define gtls_EIO 5
# define gtls_EAGAIN 11
@@ -130,7 +135,7 @@ static int gtls_mapped_sockerrno(void)
static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
{
ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
#ifdef USE_WINSOCK
#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
if(ret < 0)
gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
#endif
@@ -140,7 +145,7 @@ static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
{
ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len);
#ifdef USE_WINSOCK
#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
if(ret < 0)
gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
#endif
@@ -198,7 +203,7 @@ static void showtime(struct SessionHandle *data,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
infof(data, "%s", data->state.buffer);
infof(data, "%s\n", data->state.buffer);
}
static gnutls_datum load_file (const char *file)
@@ -448,7 +453,13 @@ gtls_connect_step1(struct connectdata *conn,
rc = gnutls_protocol_set_priority(session, protocol_priority);
#else
const char *err;
rc = gnutls_priority_set_direct(session, "-VERS-TLS-ALL:+VERS-SSL3.0",
/* the combination of the cipher ARCFOUR with SSL 3.0 and TLS 1.0 is not
vulnerable to attacks such as the BEAST, why this code now explicitly
asks for that
*/
rc = gnutls_priority_set_direct(session,
"NORMAL:-VERS-TLS-ALL:+VERS-SSL3.0:"
"-CIPHER-ALL:+ARCFOUR-128",
&err);
#endif
if(rc != GNUTLS_E_SUCCESS)
@@ -1032,7 +1043,9 @@ int Curl_gtls_seed(struct SessionHandle *data)
static bool ssl_seeded = FALSE;
/* Quickly add a bit of entropy */
#ifndef USE_GNUTLS_NETTLE
gcry_fast_random_poll();
#endif
if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
data->set.str[STRING_SSL_EGDSOCKET]) {

View File

@@ -264,6 +264,9 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
struct curl_llist *list;
int i;
if(!h)
return;
for(i = 0; i < h->slots; ++i) {
list = h->table[i];
le = list->head; /* get first list entry */

View File

@@ -201,14 +201,23 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
}
/*
* Return a hostcache id string for the providing host + port, to be used by
* Return a hostcache id string for the provided host + port, to be used by
* the DNS caching.
*/
static char *
create_hostcache_id(const char *server, int port)
create_hostcache_id(const char *name, int port)
{
/* create and return the new allocated entry */
return aprintf("%s:%d", server, port);
char *id = aprintf("%s:%d", name, port);
char *ptr = id;
if(ptr) {
/* lower case the name part */
while(*ptr && (*ptr != ':')) {
*ptr = (char)TOLOWER(*ptr);
ptr++;
}
}
return id;
}
struct hostcache_prune_data {
@@ -721,4 +730,93 @@ struct curl_hash *Curl_mk_dnscache(void)
return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
}
static int hostcache_inuse(void *data, void *hc)
{
struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
if(c->inuse == 1)
Curl_resolv_unlock(data, c);
return 1; /* free all entries */
}
void Curl_hostcache_destroy(struct SessionHandle *data)
{
/* Entries added to the hostcache with the CURLOPT_RESOLVE function are
* still present in the cache with the inuse counter set to 1. Detect them
* and cleanup!
*/
Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse);
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcachetype = HCACHE_NONE;
data->dns.hostcache = NULL;
}
CURLcode Curl_loadhostpairs(struct SessionHandle *data)
{
struct curl_slist *hostp;
char hostname[256];
char address[256];
int port;
for(hostp = data->change.resolve; hostp; hostp = hostp->next ) {
if(!hostp->data)
continue;
if(hostp->data[0] == '-') {
/* TODO: mark an entry for removal */
}
else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
address)) {
struct Curl_dns_entry *dns;
Curl_addrinfo *addr;
char *entry_id;
size_t entry_len;
addr = Curl_str2addr(address, port);
if(!addr) {
infof(data, "Resolve %s found illegal!\n", hostp->data);
continue;
}
/* 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) {
Curl_freeaddrinfo(addr);
return CURLE_OUT_OF_MEMORY;
}
entry_len = strlen(entry_id);
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
/* 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);
if(!dns)
/* if not in the cache already, put this host in the cache */
dns = Curl_cache_addr(data, addr, hostname, port);
else
/* this is a duplicate, free it again */
Curl_freeaddrinfo(addr);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
if(!dns) {
Curl_freeaddrinfo(addr);
return CURLE_OUT_OF_MEMORY;
}
infof(data, "Added %s:%d:%s to DNS cache\n",
hostname, port, address);
}
}
data->change.resolve = NULL; /* dealt with now */
return CURLE_OK;
}

View File

@@ -195,4 +195,16 @@ Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr,
extern sigjmp_buf curl_jmpenv;
#endif
/*
* Function provided by the resolver backend to set DNS servers to use.
*/
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
/*
* Destroy the hostcache of this handle.
*/
void Curl_hostcache_destroy(struct SessionHandle *data);
CURLcode Curl_loadhostpairs(struct SessionHandle *data);
#endif /* HEADER_CURL_HOSTIP_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -119,6 +119,8 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
#endif /* CURLRES_SYNCH */
#endif /* CURLRES_IPV4 */
#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
/*
* Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
*
@@ -311,3 +313,4 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
return ai;
}
#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */

View File

@@ -66,5 +66,16 @@
**********************************************************************/
#ifdef CURLRES_SYNCH
/*
* Function provided by the resolver backend to set DNS servers to use.
*/
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
(void)data;
(void)servers;
return CURLE_NOT_BUILT_IN;
}
#endif /* truly sync */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -124,7 +124,7 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status,
gss_release_buffer(&min_stat, &status_string);
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
infof(conn->data, "%s", buf);
infof(conn->data, "%s\n", buf);
}
/* returning zero (0) means success, everything else is treated as "failure"

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -29,6 +29,7 @@
#include "urldata.h"
#include "sendf.h"
#include "rawstr.h"
#include "warnless.h"
#include "curl_base64.h"
#include "http_negotiate.h"
#include "curl_memory.h"
@@ -189,7 +190,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
out_buff_desc.cBuffers = 1;
out_buff_desc.pBuffers = &out_sec_buff;
out_sec_buff.cbBuffer = neg_ctx->max_token_length;
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
out_sec_buff.BufferType = SECBUFFER_TOKEN;
out_sec_buff.pvBuffer = neg_ctx->output_token;
@@ -197,9 +198,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
if(input_token) {
in_buff_desc.ulVersion = 0;
in_buff_desc.cBuffers = 1;
in_buff_desc.pBuffers = &out_sec_buff;
in_buff_desc.pBuffers = &in_sec_buff;
in_sec_buff.cbBuffer = input_token_len;
in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
in_sec_buff.BufferType = SECBUFFER_TOKEN;
in_sec_buff.pvBuffer = input_token;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -202,11 +202,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
else {
DEBUGF(infof(data,
"Multi mode finished polling for response from "
"proxy CONNECT."));
"proxy CONNECT\n"));
}
}
else {
DEBUGF(infof(data, "Easy mode waiting response from proxy CONNECT."));
DEBUGF(infof(data, "Easy mode waiting response from proxy CONNECT\n"));
}
/* at this point, either:
@@ -409,8 +409,15 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
keepon=FALSE;
}
}
else
else {
keepon = FALSE;
if(200 == data->info.httpproxycode) {
if(gotbytes - (i+1))
failf(data, "Proxy CONNECT followed by %zd bytes "
"of opaque data. Data ignored (known bug #39)",
gotbytes - (i+1));
}
}
break; /* breaks out of for-loop, not switch() */
}

View File

@@ -71,16 +71,34 @@
#if defined(HAVE_GETIFADDRS)
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
bool Curl_if_is_interface_name(const char *interf)
{
bool result = FALSE;
struct ifaddrs *iface, *head;
if(getifaddrs(&head) >= 0) {
for(iface=head; iface != NULL; iface=iface->ifa_next) {
if(curl_strequal(iface->ifa_name, interf)) {
result = TRUE;
break;
}
}
freeifaddrs(head);
}
return result;
}
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
{
struct ifaddrs *iface, *head;
char *ip=NULL;
char *ip = NULL;
if(getifaddrs(&head) >= 0) {
for(iface=head; iface != NULL; iface=iface->ifa_next) {
if((iface->ifa_addr != NULL) &&
(iface->ifa_addr->sa_family == af) &&
curl_strequal(iface->ifa_name, interface)) {
curl_strequal(iface->ifa_name, interf)) {
void *addr;
char scope[12]="";
#ifdef ENABLE_IPV6
@@ -109,7 +127,17 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
#elif defined(HAVE_IOCTL_SIOCGIFADDR)
char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
bool Curl_if_is_interface_name(const char *interf)
{
/* This is here just to support the old interfaces */
char buf[256];
char *ip = Curl_if2ip(AF_INET, interf, buf, sizeof(buf));
return (ip != NULL) ? TRUE : FALSE;
}
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
{
struct ifreq req;
struct in_addr in;
@@ -118,10 +146,10 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
size_t len;
char *ip;
if(!interface || (af != AF_INET))
if(!interf || (af != AF_INET))
return NULL;
len = strlen(interface);
len = strlen(interf);
if(len >= sizeof(req.ifr_name))
return NULL;
@@ -130,7 +158,7 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
return NULL;
memset(&req, 0, sizeof(req));
memcpy(req.ifr_name, interface, len+1);
memcpy(req.ifr_name, interf, len+1);
req.ifr_addr.sa_family = AF_INET;
if(ioctl(dummy, SIOCGIFADDR, &req) < 0) {
@@ -148,6 +176,13 @@ char *Curl_if2ip(int af, const char *interface, char *buf, int buf_size)
#else
bool Curl_if_is_interface_name(const char *interf)
{
(void) interf;
return FALSE;
}
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size)
{
(void) af;

View File

@@ -1,5 +1,5 @@
#ifndef __IF2IP_H
#define __IF2IP_H
#ifndef HEADER_CURL_IF2IP_H
#define HEADER_CURL_IF2IP_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -23,7 +23,8 @@
***************************************************************************/
#include "setup.h"
extern char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size);
bool Curl_if_is_interface_name(const char *interf);
char *Curl_if2ip(int af, const char *interf, char *buf, int buf_size);
#ifdef __INTERIX
#include <sys/socket.h>
@@ -62,4 +63,4 @@ struct ifreq {
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
#endif /* interix */
#endif
#endif /* HEADER_CURL_IF2IP_H */

View File

@@ -125,7 +125,8 @@ const struct Curl_handler Curl_handler_imap = {
ZERO_NULL, /* readwrite */
PORT_IMAP, /* defport */
CURLPROTO_IMAP, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD /* flags */
PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
| PROTOPT_NOURLQUERY /* flags */
};
@@ -151,7 +152,8 @@ const struct Curl_handler Curl_handler_imaps = {
ZERO_NULL, /* readwrite */
PORT_IMAPS, /* defport */
CURLPROTO_IMAP | CURLPROTO_IMAPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD /* flags */
PROTOPT_CLOSEACTION | PROTOPT_SSL | PROTOPT_NEEDSPWD
| PROTOPT_NOURLQUERY /* flags */
};
#endif
@@ -352,8 +354,12 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn,
(void)instate; /* no use for this yet */
if(imapcode != 'O') {
failf(data, "STARTTLS denied. %c", imapcode);
result = CURLE_LOGIN_DENIED;
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied. %c", imapcode);
result = CURLE_USE_SSL_FAILED;
}
else
result = imap_state_login(conn);
}
else {
if(data->state.used_interface == Curl_if_multi) {
@@ -947,17 +953,12 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
struct imap_conn *imapc = &conn->proto.imapc;
struct SessionHandle *data = conn->data;
const char *path = data->state.path;
int len;
if(!*path)
path = "INBOX";
/* url decode the path and use this mailbox */
imapc->mailbox = curl_easy_unescape(data, path, 0, &len);
if(!imapc->mailbox)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
return Curl_urldecode(data, path, 0, &imapc->mailbox, NULL, TRUE);
}
/* call this when the DO phase has completed */

View File

@@ -2,7 +2,7 @@
*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* Copyright (c) 2004 - 2011 Daniel Stenberg
* Copyright (c) 2004 - 2012 Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -313,10 +313,13 @@ krb5_auth(void *app_data, struct connectdata *conn)
static void krb5_end(void *app_data)
{
OM_uint32 maj, min;
OM_uint32 min;
gss_ctx_id_t *context = app_data;
if(*context != GSS_C_NO_CONTEXT) {
maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
#ifdef DEBUGBUILD
OM_uint32 maj =
#endif
gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
DEBUGASSERT(maj == GSS_S_COMPLETE);
}
}

View File

@@ -3,17 +3,17 @@
<plist version="0.9">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>curl</string>
<key>CFBundleIdentifier</key>
<string>com.libcurl.libcurl</string>
<key>CFBundleVersion</key>
<string>7.12.3</string>
@@ -21,15 +21,15 @@
<string>libcurl</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>libcurl 7.12.3</string>
<key>CFBundleGetInfoString</key>
<string>libcurl.plist 7.12.3</string>
</dict>
</plist>
</plist>

13
lib/libcurl.vers.in Normal file
View File

@@ -0,0 +1,13 @@
HIDDEN
{
local:
__*;
_rest*;
_save*;
};
CURL_@VERSIONED_FLAVOUR@4
{
global: curl_*;
local: *;
};

View File

@@ -27,6 +27,30 @@
#include "curl_md5.h"
#include "curl_hmac.h"
#ifdef USE_GNUTLS_NETTLE
#include <nettle/md5.h>
typedef struct md5_ctx MD5_CTX;
static void MD5_Init(MD5_CTX * ctx)
{
md5_init(ctx);
}
static void MD5_Update(MD5_CTX * ctx,
const unsigned char * input,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
{
md5_digest(ctx, 16, digest);
}
#else
#ifdef USE_GNUTLS
#include <gcrypt.h>
@@ -369,6 +393,8 @@ static void Decode (UINT4 *output,
#endif /* USE_GNUTLS */
#endif /* USE_GNUTLS_NETTLE */
const HMAC_params Curl_HMAC_MD5[] = {
{
(HMAC_hinit_func) MD5_Init, /* Hash initialization function. */

View File

@@ -1085,12 +1085,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* check if we have the name resolved by now */
easy->result = Curl_resolver_is_resolved(easy->easy_conn, &dns);
if(dns) {
/* Update sockets here. Mainly because the socket(s) may have been
closed and the application thus needs to be told, even if it is
likely that the same socket(s) will again be used further down. */
singlesocket(multi, easy);
/* Update sockets here, because the socket(s) may have been
closed and the application thus needs to be told, even if it
is likely that the same socket(s) will again be used further
down. If the name has not yet been resolved, it is likely
that new sockets have been opened in an attempt to contact
another resolver. */
singlesocket(multi, easy);
if(dns) {
/* Perform the next step in the connection phase, and then move on
to the WAITCONNECT state */
easy->result = Curl_async_resolved(easy->easy_conn,
@@ -1236,7 +1239,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
easy->easy_conn->bits.close = FALSE;
multistate(easy, CURLM_STATE_DONE);
easy->result = CURLE_OK;
result = CURLM_OK;
result = CURLM_CALL_MULTI_PERFORM;
}
else {
/* Perform the protocol's DO action */
@@ -1358,29 +1361,27 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
break;
case CURLM_STATE_DO_MORE:
/* Ready to do more? */
easy->result = Curl_is_connected(easy->easy_conn,
SECONDARYSOCKET,
&connected);
if(connected) {
/*
* When we are connected, DO MORE and then go DO_DONE
*/
easy->result = Curl_do_more(easy->easy_conn);
/*
* When we are connected, DO MORE and then go DO_DONE
*/
easy->result = Curl_do_more(easy->easy_conn, &dophase_done);
/* No need to remove ourselves from the send pipeline here since that
is done for us in Curl_done() */
if(CURLE_OK == easy->result) {
/* No need to remove this handle from the send pipeline here since that
is done in Curl_done() */
if(CURLE_OK == easy->result) {
if(dophase_done) {
multistate(easy, CURLM_STATE_DO_DONE);
result = CURLM_CALL_MULTI_PERFORM;
}
else {
/* failure detected */
Curl_posttransfer(data);
Curl_done(&easy->easy_conn, easy->result, FALSE);
disconnect_conn = TRUE;
}
else
/* stay in DO_MORE */
result = CURLM_OK;
}
else {
/* failure detected */
Curl_posttransfer(data);
Curl_done(&easy->easy_conn, easy->result, FALSE);
disconnect_conn = TRUE;
}
break;
@@ -1937,11 +1938,12 @@ static void singlesocket(struct Curl_multi *multi,
}
/* we know (entry != NULL) at this point, see the logic above */
multi->socket_cb(easy->easy_handle,
s,
action,
multi->socket_userp,
entry->socketp);
if(multi->socket_cb)
multi->socket_cb(easy->easy_handle,
s,
action,
multi->socket_userp,
entry->socketp);
entry->action = action; /* store the current action state */
}
@@ -2016,11 +2018,12 @@ static void singlesocket(struct Curl_multi *multi,
remove_sock_from_hash = FALSE;
if(remove_sock_from_hash) {
multi->socket_cb(easy->easy_handle,
s,
CURL_POLL_REMOVE,
multi->socket_userp,
entry ? entry->socketp : NULL);
if(multi->socket_cb)
multi->socket_cb(easy->easy_handle,
s,
CURL_POLL_REMOVE,
multi->socket_userp,
entry ? entry->socketp : NULL);
sh_delentry(multi->sockhash, s);
}

View File

@@ -6,7 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2011 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -336,7 +336,10 @@ retry:
int proto;
ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
if(proto == LDAP_VERSION3) {
ldap_memfree(info);
if(info) {
ldap_memfree(info);
info = NULL;
}
proto = LDAP_VERSION2;
ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
li->didbind = FALSE;
@@ -347,8 +350,13 @@ retry:
if(err) {
failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
info ? info : "");
if(info)
ldap_memfree(info);
return CURLE_LOGIN_DENIED;
}
if(info)
ldap_memfree(info);
conn->recv[FIRSTSOCKET] = ldap_recv;
*done = TRUE;
return CURLE_OK;

View File

@@ -65,6 +65,15 @@
/* The last #include file should be: */
#include "memdebug.h"
/* version dependent differences */
#if POLARSSL_VERSION_NUMBER < 0x01010000
/* the old way */
#define HAVEGE_RANDOM havege_rand
#else
/* from 1.1.0 */
#define HAVEGE_RANDOM havege_random
#endif
/* Define this to enable lots of debugging for PolarSSL */
#undef POLARSSL_DEBUG
@@ -128,7 +137,7 @@ Curl_polarssl_connect(struct connectdata *conn,
if(ret) {
failf(data, "Error reading ca cert file %s: -0x%04X",
data->set.str[STRING_SSL_CAFILE], -ret);
data->set.str[STRING_SSL_CAFILE], ret);
if(data->set.ssl.verifypeer)
return CURLE_SSL_CACERT_BADFILE;
@@ -189,7 +198,7 @@ Curl_polarssl_connect(struct connectdata *conn,
ssl_set_endpoint(&conn->ssl[sockindex].ssl, SSL_IS_CLIENT);
ssl_set_authmode(&conn->ssl[sockindex].ssl, SSL_VERIFY_OPTIONAL);
ssl_set_rng(&conn->ssl[sockindex].ssl, havege_rand,
ssl_set_rng(&conn->ssl[sockindex].ssl, HAVEGE_RANDOM,
&conn->ssl[sockindex].hs);
ssl_set_bio(&conn->ssl[sockindex].ssl,
net_recv, &conn->sock[sockindex],
@@ -267,10 +276,13 @@ Curl_polarssl_connect(struct connectdata *conn,
infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
#if POLARSSL_VERSION_NUMBER<0x01000000
ssl_get_cipher(&conn->ssl[sockindex].ssl));
ssl_get_cipher(&conn->ssl[sockindex].ssl)
#elif POLARSSL_VERSION_NUMBER >= 0x01010000
ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
#else
ssl_get_ciphersuite_name(&conn->ssl[sockindex].ssl));
ssl_get_ciphersuite_name(&conn->ssl[sockindex].ssl)
#endif
);
ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);

View File

@@ -125,7 +125,7 @@ const struct Curl_handler Curl_handler_pop3 = {
ZERO_NULL, /* readwrite */
PORT_POP3, /* defport */
CURLPROTO_POP3, /* protocol */
PROTOPT_CLOSEACTION /* flags */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
};
@@ -151,7 +151,8 @@ const struct Curl_handler Curl_handler_pop3s = {
ZERO_NULL, /* readwrite */
PORT_POP3S, /* defport */
CURLPROTO_POP3 | CURLPROTO_POP3S, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY /* flags */
};
#endif
@@ -297,9 +298,13 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
(void)instate; /* no use for this yet */
if(pop3code != 'O') {
failf(data, "STARTTLS denied. %c", pop3code);
result = CURLE_LOGIN_DENIED;
state(conn, POP3_STOP);
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied. %c", pop3code);
result = CURLE_USE_SSL_FAILED;
state(conn, POP3_STOP);
}
else
result = pop3_state_user(conn);
}
else {
/* Curl_ssl_connect is BLOCKING */
@@ -420,6 +425,16 @@ static CURLcode pop3_state_list_resp(struct connectdata *conn,
return CURLE_RECV_ERROR;
}
/* This 'OK' line ends with a CR LF pair which is the two first bytes of the
EOB string so count this is two matching bytes. This is necessary to make
the code detect the EOB if the only data than comes now is %2e CR LF like
when there is no body to return. */
pop3c->eob = 2;
/* But since this initial CR LF pair is not part of the actual body, we set
the strip counter here so that these bytes won't be delivered. */
pop3c->strip = 2;
/* POP3 download */
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, pop3->bytecountp,
-1, NULL); /* no upload here */
@@ -899,11 +914,7 @@ static CURLcode pop3_parse_url_path(struct connectdata *conn)
const char *path = data->state.path;
/* url decode the path and use this mailbox */
pop3c->mailbox = curl_easy_unescape(data, path, 0, NULL);
if(!pop3c->mailbox)
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
return Curl_urldecode(data, path, 0, &pop3c->mailbox, NULL, TRUE);
}
/* call this when the DO phase has completed */
@@ -1025,41 +1036,115 @@ CURLcode Curl_pop3_write(struct connectdata *conn,
size_t nread)
{
/* This code could be made into a special function in the handler struct. */
CURLcode result;
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct SingleRequest *k = &data->req;
/* Detect the end-of-body marker, which is 5 bytes:
0d 0a 2e 0d 0a. This marker can of course be spread out
over up to 5 different data chunks. Deal with it! */
struct pop3_conn *pop3c = &conn->proto.pop3c;
size_t checkmax = (nread >= POP3_EOB_LEN?POP3_EOB_LEN:nread);
size_t checkleft = POP3_EOB_LEN-pop3c->eob;
size_t check = (checkmax >= checkleft?checkleft:checkmax);
bool strip_dot = FALSE;
size_t last = 0;
size_t i;
if(!memcmp(POP3_EOB, &str[nread - check], check)) {
/* substring match */
pop3c->eob += check;
if(pop3c->eob == POP3_EOB_LEN) {
/* full match, the transfer is done! */
str[nread - check] = '\0';
nread -= check;
k->keepon &= ~KEEP_RECV;
/* Search through the buffer looking for the end-of-body marker which is
5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches
the eob so the server will have prefixed it with an extra dot which we
need to strip out. Additionally the marker could of course be spread out
over 5 different data chunks */
for(i = 0; i < nread; i++) {
size_t prev = pop3c->eob;
switch(str[i]) {
case 0x0d:
if(pop3c->eob == 0) {
pop3c->eob++;
if(i) {
/* Write out the body part that didn't match */
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
i - last);
if(result)
return result;
last = i;
}
}
else if(pop3c->eob == 3)
pop3c->eob++;
else
/* If the character match wasn't at position 0 or 3 then restart the
pattern matching */
pop3c->eob = 1;
break;
case 0x0a:
if(pop3c->eob == 1 || pop3c->eob == 4)
pop3c->eob++;
else
/* If the character match wasn't at position 1 or 4 then start the
search again */
pop3c->eob = 0;
break;
case 0x2e:
if(pop3c->eob == 2)
pop3c->eob++;
else if(pop3c->eob == 3) {
/* We have an extra dot after the CRLF which we need to strip off */
strip_dot = TRUE;
pop3c->eob = 0;
}
else
/* If the character match wasn't at position 2 then start the search
again */
pop3c->eob = 0;
break;
default:
pop3c->eob = 0;
break;
}
/* Did we have a partial match which has subsequently failed? */
if(prev && prev >= pop3c->eob) {
/* Strip can only be non-zero for the very first mismatch after CRLF
and then both prev and strip are equal and nothing will be output
below */
while(prev && pop3c->strip) {
prev--;
pop3c->strip--;
}
if(prev) {
/* If the partial match was the CRLF and dot then only write the CRLF
as the server would have inserted the dot */
result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB,
strip_dot ? prev - 1 : prev);
if(result)
return result;
last = i;
strip_dot = FALSE;
}
}
}
else if(pop3c->eob) {
/* not a match, but we matched a piece before so we must now
send that part as body first, before we move on and send
this buffer */
result = Curl_client_write(conn, CLIENTWRITE_BODY,
(char *)POP3_EOB, pop3c->eob);
if(result)
return result;
if(pop3c->eob == POP3_EOB_LEN) {
/* We have a full match so the transfer is done! */
k->keepon &= ~KEEP_RECV;
pop3c->eob = 0;
return CURLE_OK;
}
result = Curl_client_write(conn, CLIENTWRITE_BODY, str, nread);
if(pop3c->eob)
/* While EOB is matching nothing should be output */
return CURLE_OK;
if(nread - last) {
result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
nread - last);
}
return result;
}

View File

@@ -1,5 +1,5 @@
#ifndef __POP3_H
#define __POP3_H
#ifndef HEADER_CURL_POP3_H
#define HEADER_CURL_POP3_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2009 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -46,6 +46,7 @@ struct pop3_conn {
char *mailbox; /* what to RETR */
size_t eob; /* number of bytes of the EOB (End Of Body) that has been
received thus far */
size_t strip; /* number of bytes from the start to ignore as non-body */
pop3state state; /* always use pop3.c:state() to change state! */
};
@@ -60,4 +61,4 @@ CURLcode Curl_pop3_write(struct connectdata *conn,
char *str,
size_t nread);
#endif /* __POP3_H */
#endif /* HEADER_CURL_POP3_H */

View File

@@ -157,6 +157,8 @@ void Curl_pgrsResetTimes(struct SessionHandle *data)
void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
{
struct timeval now = Curl_tvnow();
switch(timer) {
default:
case TIMER_NONE:
@@ -164,35 +166,38 @@ void Curl_pgrsTime(struct SessionHandle *data, timerid timer)
break;
case TIMER_STARTSINGLE:
/* This is set at the start of a single fetch */
data->progress.t_startsingle = Curl_tvnow();
data->progress.t_startsingle = now;
break;
case TIMER_STARTACCEPT:
data->progress.t_acceptdata = Curl_tvnow();
break;
case TIMER_NAMELOOKUP:
data->progress.t_nslookup =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
Curl_tvdiff_secs(now, data->progress.t_startsingle);
break;
case TIMER_CONNECT:
data->progress.t_connect =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
Curl_tvdiff_secs(now, data->progress.t_startsingle);
break;
case TIMER_APPCONNECT:
data->progress.t_appconnect =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
Curl_tvdiff_secs(now, data->progress.t_startsingle);
break;
case TIMER_PRETRANSFER:
data->progress.t_pretransfer =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
Curl_tvdiff_secs(now, data->progress.t_startsingle);
break;
case TIMER_STARTTRANSFER:
data->progress.t_starttransfer =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.t_startsingle);
Curl_tvdiff_secs(now, data->progress.t_startsingle);
break;
case TIMER_POSTRANSFER:
/* this is the normal end-of-transfer thing */
break;
case TIMER_REDIRECT:
data->progress.t_redirect =
Curl_tvdiff_secs(Curl_tvnow(), data->progress.start);
data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start);
break;
}
}

View File

@@ -34,6 +34,7 @@ typedef enum {
TIMER_STARTTRANSFER,
TIMER_POSTRANSFER,
TIMER_STARTSINGLE,
TIMER_STARTACCEPT,
TIMER_REDIRECT,
TIMER_LAST /* must be last */
} timerid;

View File

@@ -125,11 +125,11 @@ int Curl_wait_ms(int timeout_ms)
}
/*
* This is an internal function used for waiting for read or write
* events on a pair of file descriptors. It uses poll() when a fine
* poll() is available, in order to avoid limits with FD_SETSIZE,
* otherwise select() is used. An error is returned if select() is
* being used and a file descriptor is too large for FD_SETSIZE.
* Wait for read or write events on a set of file descriptors. It uses poll()
* when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
* otherwise select() is used. An error is returned if select() is being used
* and a file descriptor is too large for FD_SETSIZE.
*
* A negative timeout value makes this function wait indefinitely,
* unles no valid file descriptor is given, when this happens the
* negative timeout is ignored and the function times out immediately.
@@ -140,13 +140,20 @@ int Curl_wait_ms(int timeout_ms)
* Return values:
* -1 = system call error or fd >= FD_SETSIZE
* 0 = timeout
* CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
* [bitmask] = action as described below
*
* CURL_CSELECT_IN - first socket is readable
* CURL_CSELECT_IN2 - second socket is readable
* CURL_CSELECT_OUT - write socket is writable
* CURL_CSELECT_ERR - an error condition occurred
*/
int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
long timeout_ms)
int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
curl_socket_t readfd1,
curl_socket_t writefd, /* socket to write to */
long timeout_ms) /* milliseconds to wait */
{
#ifdef HAVE_POLL_FINE
struct pollfd pfd[2];
struct pollfd pfd[3];
int num;
#else
struct timeval pending_tv;
@@ -162,7 +169,9 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
int r;
int ret;
if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
(writefd == CURL_SOCKET_BAD)) {
/* no sockets, just wait */
r = Curl_wait_ms((int)timeout_ms);
return r;
}
@@ -180,8 +189,14 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
#ifdef HAVE_POLL_FINE
num = 0;
if(readfd != CURL_SOCKET_BAD) {
pfd[num].fd = readfd;
if(readfd0 != CURL_SOCKET_BAD) {
pfd[num].fd = readfd0;
pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
pfd[num].revents = 0;
num++;
}
if(readfd1 != CURL_SOCKET_BAD) {
pfd[num].fd = readfd1;
pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
pfd[num].revents = 0;
num++;
@@ -218,13 +233,20 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
ret = 0;
num = 0;
if(readfd != CURL_SOCKET_BAD) {
if(readfd0 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
ret |= CURL_CSELECT_IN;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
ret |= CURL_CSELECT_ERR;
num++;
}
if(readfd1 != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
ret |= CURL_CSELECT_IN2;
if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
ret |= CURL_CSELECT_ERR;
num++;
}
if(writefd != CURL_SOCKET_BAD) {
if(pfd[num].revents & (POLLWRNORM|POLLOUT))
ret |= CURL_CSELECT_OUT;
@@ -240,11 +262,18 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
maxfd = (curl_socket_t)-1;
FD_ZERO(&fds_read);
if(readfd != CURL_SOCKET_BAD) {
VERIFY_SOCK(readfd);
FD_SET(readfd, &fds_read);
FD_SET(readfd, &fds_err);
maxfd = readfd;
if(readfd0 != CURL_SOCKET_BAD) {
VERIFY_SOCK(readfd0);
FD_SET(readfd0, &fds_read);
FD_SET(readfd0, &fds_err);
maxfd = readfd0;
}
if(readfd1 != CURL_SOCKET_BAD) {
VERIFY_SOCK(readfd1);
FD_SET(readfd1, &fds_read);
FD_SET(readfd1, &fds_err);
if(readfd1 > maxfd)
maxfd = readfd1;
}
FD_ZERO(&fds_write);
@@ -286,10 +315,16 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
return 0;
ret = 0;
if(readfd != CURL_SOCKET_BAD) {
if(FD_ISSET(readfd, &fds_read))
if(readfd0 != CURL_SOCKET_BAD) {
if(FD_ISSET(readfd0, &fds_read))
ret |= CURL_CSELECT_IN;
if(FD_ISSET(readfd, &fds_err))
if(FD_ISSET(readfd0, &fds_err))
ret |= CURL_CSELECT_ERR;
}
if(readfd1 != CURL_SOCKET_BAD) {
if(FD_ISSET(readfd1, &fds_read))
ret |= CURL_CSELECT_IN2;
if(FD_ISSET(readfd1, &fds_err))
ret |= CURL_CSELECT_ERR;
}
if(writefd != CURL_SOCKET_BAD) {

View File

@@ -84,9 +84,19 @@ struct pollfd
#define POLLRDBAND POLLPRI
#endif
int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
/* there are three CSELECT defines that are defined in the public header that
are exposed to users, but this *IN2 bit is only ever used internally and
therefore defined here */
#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
curl_socket_t writefd,
long timeout_ms);
/* provide the former API internally */
#define Curl_socket_ready(x,y,z) \
Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
int Curl_wait_ms(int timeout_ms);

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -487,6 +487,9 @@
#ifdef USE_ARES
# define CURLRES_ASYNCH
# define CURLRES_ARES
/* now undef the stock libc functions just to avoid them being used */
# undef HAVE_GETADDRINFO
# undef HAVE_GETHOSTBYNAME
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
# define CURLRES_ASYNCH
# define CURLRES_THREADED
@@ -628,4 +631,14 @@ int netware_init(void);
# endif
#endif
/*
* Portable symbolic names for Winsock shutdown() mode flags.
*/
#ifdef USE_WINSOCK
# define SHUT_RD 0x00
# define SHUT_WR 0x01
# define SHUT_RDWR 0x02
#endif
#endif /* HEADER_CURL_LIB_SETUP_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -88,9 +88,10 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
case CURL_LOCK_DATA_SSL_SESSION:
#ifdef USE_SSL
if(!share->sslsession) {
share->nsslsession = 8;
share->sslsession = calloc(share->nsslsession,
share->max_ssl_sessions = 8;
share->sslsession = calloc(share->max_ssl_sessions,
sizeof(struct curl_ssl_session));
share->sessionage = 0;
if(!share->sslsession)
return CURLSHE_NOMEM;
}
@@ -131,11 +132,7 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...)
case CURL_LOCK_DATA_SSL_SESSION:
#ifdef USE_SSL
if(share->sslsession) {
free(share->sslsession);
share->sslsession = NULL;
share->nsslsession = 0;
}
Curl_safefree(share->sslsession);
break;
#else
return CURLSHE_NOT_BUILT_IN;
@@ -201,8 +198,8 @@ curl_share_cleanup(CURLSH *sh)
#ifdef USE_SSL
if(share->sslsession) {
unsigned int i;
for(i = 0; i < share->nsslsession; ++i)
size_t i;
for(i = 0; i < share->max_ssl_sessions; i++)
Curl_ssl_kill_session(&(share->sslsession[i]));
free(share->sslsession);
}

View File

@@ -1,6 +1,5 @@
#ifndef __CURL_SHARE_H
#define __CURL_SHARE_H
#ifndef HEADER_CURL_SHARE_H
#define HEADER_CURL_SHARE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -8,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -51,11 +50,12 @@ struct Curl_share {
#endif
struct curl_ssl_session *sslsession;
unsigned int nsslsession;
size_t max_ssl_sessions;
long sessionage;
};
CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data,
curl_lock_access);
CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data);
#endif /* __CURL_SHARE_H */
#endif /* HEADER_CURL_SHARE_H */

View File

@@ -133,7 +133,7 @@ const struct Curl_handler Curl_handler_smtp = {
ZERO_NULL, /* readwrite */
PORT_SMTP, /* defport */
CURLPROTO_SMTP, /* protocol */
PROTOPT_CLOSEACTION /* flags */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */
};
#ifdef USE_SSL
@@ -158,7 +158,8 @@ const struct Curl_handler Curl_handler_smtps = {
ZERO_NULL, /* readwrite */
PORT_SMTPS, /* defport */
CURLPROTO_SMTP | CURLPROTO_SMTPS, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY /* flags */
};
#endif
@@ -509,7 +510,7 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
if(smtpcode != 220) {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied. %c", smtpcode);
result = CURLE_LOGIN_DENIED;
result = CURLE_USE_SSL_FAILED;
}
else
result = smtp_authenticate(conn);
@@ -1243,7 +1244,6 @@ static CURLcode smtp_connect(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct pingpong *pp = &smtpc->pp;
const char *path = conn->data->state.path;
int len;
char localhost[HOSTNAME_MAX + 1];
*done = FALSE; /* default to not done yet */
@@ -1315,9 +1315,9 @@ static CURLcode smtp_connect(struct connectdata *conn,
}
/* url decode the path and use it as domain with EHLO */
smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len);
if(!smtpc->domain)
return CURLE_OUT_OF_MEMORY;
result = Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
if(result)
return result;
/* When we connect, we start in the state where we await the server greeting
*/

136
lib/ssh.c
View File

@@ -171,7 +171,8 @@ const struct Curl_handler Curl_handler_scp = {
ZERO_NULL, /* readwrite */
PORT_SSH, /* defport */
CURLPROTO_SCP, /* protocol */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
@@ -196,7 +197,8 @@ const struct Curl_handler Curl_handler_sftp = {
ZERO_NULL, /* readwrite */
PORT_SSH, /* defport */
CURLPROTO_SFTP, /* protocol */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION /* flags */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
| PROTOPT_NOURLQUERY /* flags */
};
@@ -642,10 +644,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
struct SSHPROTO *sftp_scp = data->state.proto.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
#ifdef CURL_LIBSSH2_DEBUG
const char *fingerprint;
#endif /* CURL_LIBSSH2_DEBUG */
const char *host_public_key_md5;
char md5buffer[33];
char *new_readdir_line;
int rc = LIBSSH2_ERROR_NONE, i;
int err;
@@ -668,7 +668,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* fall-through */
case SSH_S_STARTUP:
rc = libssh2_session_startup(sshc->ssh_session, sock);
rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
@@ -683,48 +683,40 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* fall-through */
case SSH_HOSTKEY:
#ifdef CURL_LIBSSH2_DEBUG
/*
* Before we authenticate we should check the hostkey's fingerprint
* against our known hosts. How that is handled (reading from file,
* whatever) is up to us. As for know not much is implemented, besides
* showing how to get the fingerprint.
* whatever) is up to us.
*/
fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
LIBSSH2_HOSTKEY_HASH_MD5);
/* The fingerprint points to static storage (!), don't free() it. */
infof(data, "Fingerprint: ");
for(rc = 0; rc < 16; rc++)
infof(data, "%02X ", (unsigned char) fingerprint[rc]);
infof(data, "\n");
#endif /* CURL_LIBSSH2_DEBUG */
for(i = 0; i < 16; i++)
snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
/* Before we authenticate we check the hostkey's MD5 fingerprint
* against a known fingerprint, if available. This implementation pulls
* it from the curl option.
* against a known fingerprint, if available.
*/
if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
char buf[33];
host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
LIBSSH2_HOSTKEY_HASH_MD5);
for(i = 0; i < 16; i++)
snprintf(&buf[i*2], 3, "%02x",
(unsigned char) host_public_key_md5[i]);
if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
if(!strequal(md5buffer,
data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
failf(data,
"Denied establishing ssh session: mismatch md5 fingerprint. "
"Remote %s is not equal to %s",
buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
state(conn, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
break;
result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "MD5 checksum match!\n");
/* as we already matched, we skip the check for known hosts */
}
else
result = ssh_knownhost(conn);
result = ssh_knownhost(conn);
if(!result)
state(conn, SSH_AUTHLIST);
break;
@@ -1063,7 +1055,20 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/*
* Support some of the "FTP" commands
*/
if(curl_strequal("pwd", sshc->quote_item->data)) {
char *cmd = sshc->quote_item->data;
sshc->acceptfail = FALSE;
/* if a command starts with an asterisk, which a legal SFTP command never
can, the command will be allowed to fail without it causing any
aborts or cancels etc. It will cause libcurl to act as if the command
is successful, whatever the server reponds. */
if(cmd[0] == '*') {
cmd++;
sshc->acceptfail = TRUE;
}
if(curl_strequal("pwd", cmd)) {
/* output debug output if that is requested */
char *tmp = aprintf("257 \"%s\" is current directory.\n",
sftp_scp->path);
@@ -1085,12 +1090,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_SFTP_NEXT_QUOTE);
break;
}
else if(sshc->quote_item->data) {
else if(cmd) {
/*
* the arguments following the command must be separated from the
* command with a space so we can check for it unconditionally
*/
cp = strchr(sshc->quote_item->data, ' ');
cp = strchr(cmd, ' ');
if(cp == NULL) {
failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
state(conn, SSH_SFTP_CLOSE);
@@ -1121,9 +1126,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
* OpenSSH's sftp program and call the appropriate libssh2
* functions.
*/
if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
if(curl_strnequal(cmd, "chgrp ", 6) ||
curl_strnequal(cmd, "chmod ", 6) ||
curl_strnequal(cmd, "chown ", 6) ) {
/* attribute change */
/* sshc->quote_path1 contains the mode to set */
@@ -1146,8 +1151,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_SFTP_QUOTE_STAT);
break;
}
else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
else if(curl_strnequal(cmd, "ln ", 3) ||
curl_strnequal(cmd, "symlink ", 8)) {
/* symbolic linking */
/* sshc->quote_path1 is the source */
/* get the destination */
@@ -1168,12 +1173,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_SFTP_QUOTE_SYMLINK);
break;
}
else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
else if(curl_strnequal(cmd, "mkdir ", 6)) {
/* create dir */
state(conn, SSH_SFTP_QUOTE_MKDIR);
break;
}
else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
else if(curl_strnequal(cmd, "rename ", 7)) {
/* rename file */
/* first param is the source path */
/* second param is the dest. path */
@@ -1193,12 +1198,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
state(conn, SSH_SFTP_QUOTE_RENAME);
break;
}
else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
else if(curl_strnequal(cmd, "rmdir ", 6)) {
/* delete dir */
state(conn, SSH_SFTP_QUOTE_RMDIR);
break;
}
else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
else if(curl_strnequal(cmd, "rm ", 3)) {
state(conn, SSH_SFTP_QUOTE_UNLINK);
break;
}
@@ -1246,7 +1251,21 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
case SSH_SFTP_QUOTE_STAT:
if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
{
char *cmd = sshc->quote_item->data;
sshc->acceptfail = FALSE;
/* if a command starts with an asterisk, which a legal SFTP command never
can, the command will be allowed to fail without it causing any
aborts or cancels etc. It will cause libcurl to act as if the command
is successful, whatever the server reponds. */
if(cmd[0] == '*') {
cmd++;
sshc->acceptfail = TRUE;
}
if(!curl_strnequal(cmd, "chmod", 5)) {
/* Since chown and chgrp only set owner OR group but libssh2 wants to
* set them both at once, we need to obtain the current ownership
* first. This takes an extra protocol round trip.
@@ -1258,7 +1277,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) { /* get those attributes */
else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1274,10 +1293,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
/* Now set the new attributes... */
if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
if(curl_strnequal(cmd, "chgrp", 5)) {
sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
!sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
Curl_safefree(sshc->quote_path2);
@@ -1289,7 +1309,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
}
else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
else if(curl_strnequal(cmd, "chmod", 5)) {
sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
/* permissions are octal */
@@ -1306,10 +1326,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
}
else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
else if(curl_strnequal(cmd, "chown", 5)) {
sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
!sshc->acceptfail) {
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
Curl_safefree(sshc->quote_path2);
@@ -1325,6 +1346,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* Now send the completed structure... */
state(conn, SSH_SFTP_QUOTE_SETSTAT);
break;
}
case SSH_SFTP_QUOTE_SETSTAT:
rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
@@ -1334,7 +1356,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1359,7 +1381,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1378,11 +1400,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
case SSH_SFTP_QUOTE_MKDIR:
rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
(unsigned int)strlen(sshc->quote_path1),
0755);
data->set.new_directory_perms);
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1407,7 +1429,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1428,7 +1450,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1447,7 +1469,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if(rc == LIBSSH2_ERROR_EAGAIN) {
break;
}
else if(rc != 0) {
else if(rc != 0 && !sshc->acceptfail) {
err = (int)(libssh2_sftp_last_error(sshc->sftp_session));
Curl_safefree(sshc->quote_path1);
sshc->quote_path1 = NULL;
@@ -1863,9 +1885,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(sshc->readdir_linkPath);
sshc->readdir_linkPath = NULL;
new_readdir_line = realloc(sshc->readdir_line,
sshc->readdir_totalLen + 4 +
sshc->readdir_len);
/* get room for the filename and extra output */
sshc->readdir_totalLen += 4 + sshc->readdir_len;
new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen);
if(!new_readdir_line) {
Curl_safefree(sshc->readdir_line);
sshc->readdir_line = NULL;

View File

@@ -115,6 +115,8 @@ struct ssh_conn {
char *quote_path1; /* two generic pointers for the QUOTE stuff */
char *quote_path2;
LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
bool acceptfail; /* used by the SFTP_QUOTE (continue if
quote command fails) */
char *homedir; /* when doing SFTP we figure out home dir in the
connect phase */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -66,6 +66,11 @@
/* The last #include file should be: */
#include "memdebug.h"
/* convenience macro to check if this handle is using a shared SSL session */
#define SSLSESSION_SHARED(data) (data->share && \
(data->share->specifier & \
(1<<CURL_LOCK_DATA_SSL_SESSION)))
static bool safe_strequal(char* str1, char* str2)
{
if(str1 && str2)
@@ -216,8 +221,7 @@ Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
return res;
#else
*done = TRUE; /* fallback to BLOCKING */
conn->ssl[sockindex].use = TRUE;
return curlssl_connect(conn, sockindex);
return Curl_ssl_connect(conn, sockindex);
#endif /* non-blocking connect support */
}
@@ -231,17 +235,25 @@ int Curl_ssl_getsessionid(struct connectdata *conn,
{
struct curl_ssl_session *check;
struct SessionHandle *data = conn->data;
long i;
size_t i;
long *general_age;
bool no_match = TRUE;
*ssl_sessionid = NULL;
if(!conn->ssl_config.sessionid)
/* session ID re-use is disabled */
return TRUE;
/* Lock for reading if shared */
if(data->share && data->share->sslsession == data->state.session)
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SHARED);
/* Lock if shared */
if(SSLSESSION_SHARED(data)) {
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
general_age = &data->share->sessionage;
}
else
general_age = &data->state.sessionage;
for(i=0; i< data->set.ssl.numsessions; i++) {
for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
check = &data->state.session[i];
if(!check->sessionid)
/* not session ID means blank entry */
@@ -250,28 +262,27 @@ int Curl_ssl_getsessionid(struct connectdata *conn,
(conn->remote_port == check->remote_port) &&
Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) {
/* yes, we have a session ID! */
data->state.sessionage++; /* increase general age */
check->age = data->state.sessionage; /* set this as used in this age */
(*general_age)++; /* increase general age */
check->age = *general_age; /* set this as used in this age */
*ssl_sessionid = check->sessionid;
if(idsize)
*idsize = check->idsize;
return FALSE;
no_match = FALSE;
break;
}
}
*ssl_sessionid = NULL;
/* Unlock for reading */
if(data->share && data->share->sslsession == data->state.session)
/* Unlock */
if(SSLSESSION_SHARED(data))
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
return TRUE;
return no_match;
}
/*
* Kill a single session ID entry in the cache.
*/
int Curl_ssl_kill_session(struct curl_ssl_session *session)
void Curl_ssl_kill_session(struct curl_ssl_session *session)
{
if(session->sessionid) {
/* defensive check */
@@ -279,18 +290,13 @@ int Curl_ssl_kill_session(struct curl_ssl_session *session)
/* free the ID the SSL-layer specific way */
curlssl_session_free(session->sessionid);
session->sessionid=NULL;
session->sessionid = NULL;
session->age = 0; /* fresh */
Curl_free_ssl_config(&session->ssl_config);
Curl_safefree(session->name);
session->name = NULL; /* no name */
return 0; /* ok */
}
else
return 1;
}
/*
@@ -298,14 +304,13 @@ int Curl_ssl_kill_session(struct curl_ssl_session *session)
*/
void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
{
int i;
size_t i;
struct SessionHandle *data=conn->data;
if(data->share && data->share->sslsession == data->state.session)
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION,
CURL_LOCK_ACCESS_SINGLE);
if(SSLSESSION_SHARED(data))
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
for(i=0; i< data->set.ssl.numsessions; i++) {
for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) {
struct curl_ssl_session *check = &data->state.session[i];
if(check->sessionid == ssl_sessionid) {
@@ -314,7 +319,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
}
}
if(data->share && data->share->sslsession == data->state.session)
if(SSLSESSION_SHARED(data))
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
}
@@ -328,11 +333,12 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
void *ssl_sessionid,
size_t idsize)
{
long i;
size_t i;
struct SessionHandle *data=conn->data; /* the mother of all structs */
struct curl_ssl_session *store = &data->state.session[0];
long oldest_age=data->state.session[0].age; /* zero if unused */
char *clone_host;
long *general_age;
/* Even though session ID re-use might be disabled, that only disables USING
IT. We still store it here in case the re-using is again enabled for an
@@ -346,18 +352,23 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
the oldest if necessary) */
/* If using shared SSL session, lock! */
if(data->share && data->share->sslsession == data->state.session)
if(SSLSESSION_SHARED(data)) {
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
general_age = &data->share->sessionage;
}
else {
general_age = &data->state.sessionage;
}
/* find an empty slot for us, or find the oldest */
for(i=1; (i<data->set.ssl.numsessions) &&
for(i = 1; (i < data->set.ssl.max_ssl_sessions) &&
data->state.session[i].sessionid; i++) {
if(data->state.session[i].age < oldest_age) {
oldest_age = data->state.session[i].age;
store = &data->state.session[i];
}
}
if(i == data->set.ssl.numsessions)
if(i == data->set.ssl.max_ssl_sessions)
/* cache is full, we must "kill" the oldest entry! */
Curl_ssl_kill_session(store);
else
@@ -366,7 +377,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
/* now init the session struct wisely */
store->sessionid = ssl_sessionid;
store->idsize = idsize;
store->age = data->state.sessionage; /* set current age */
store->age = *general_age; /* set current age */
if(store->name)
/* free it if there's one already present */
free(store->name);
@@ -375,7 +386,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
/* Unlock */
if(data->share && data->share->sslsession == data->state.session)
if(SSLSESSION_SHARED(data))
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
@@ -390,22 +401,15 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
void Curl_ssl_close_all(struct SessionHandle *data)
{
long i;
/* kill the session ID cache */
if(data->state.session &&
!(data->share && data->share->sslsession == data->state.session)) {
Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
for(i=0; i< data->set.ssl.numsessions; i++)
size_t i;
/* kill the session ID cache if not shared */
if(data->state.session && !SSLSESSION_SHARED(data)) {
for(i = 0; i < data->set.ssl.max_ssl_sessions; i++)
/* the single-killer function handles empty table slots */
Curl_ssl_kill_session(&data->state.session[i]);
/* free the cache data */
free(data->state.session);
data->state.session = NULL;
Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION);
Curl_safefree(data->state.session);
}
curlssl_close_all(data);
@@ -455,7 +459,7 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data)
* This sets up a session ID cache to the specified size. Make sure this code
* is agnostic to what underlying SSL technology we use.
*/
CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
CURLcode Curl_ssl_initsessions(struct SessionHandle *data, size_t amount)
{
struct curl_ssl_session *session;
@@ -468,7 +472,7 @@ CURLcode Curl_ssl_initsessions(struct SessionHandle *data, long amount)
return CURLE_OUT_OF_MEMORY;
/* store the info in the SSL section */
data->set.ssl.numsessions = amount;
data->set.ssl.max_ssl_sessions = amount;
data->state.session = session;
data->state.sessionage = 1; /* this is brand new */
return CURLE_OK;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -47,7 +47,7 @@ CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data);
struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data);
/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct SessionHandle *, long);
CURLcode Curl_ssl_initsessions(struct SessionHandle *, size_t);
size_t Curl_ssl_version(char *buffer, size_t size);
bool Curl_ssl_data_pending(const struct connectdata *conn,
int connindex);
@@ -65,7 +65,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
void *ssl_sessionid,
size_t idsize);
/* Kill a single session ID entry in the cache */
int Curl_ssl_kill_session(struct curl_ssl_session *session);
void Curl_ssl_kill_session(struct curl_ssl_session *session);
/* delete a session from the cache */
void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
@@ -90,7 +90,7 @@ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
#define Curl_ssl_check_cxn(x) 0
#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
#define Curl_ssl_kill_session(x) 0
#define Curl_ssl_kill_session(x) Curl_nop_stmt
#endif
#endif /* HEADER_CURL_SSLGEN_H */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -127,6 +127,11 @@
#define HAVE_ERR_REMOVE_THREAD_STATE 1
#endif
#ifndef HAVE_SSLV2_CLIENT_METHOD
#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
#define OPENSSL_NO_SSL2
#endif
/*
* Number of bytes to read from the random number seed file. This must be
* a finite value (because some entropy "files" like /dev/urandom have
@@ -461,6 +466,7 @@ int cert_stuff(struct connectdata *conn,
failf(data, SSL_CLIENT_CERT_ERR);
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
return 0;
}
@@ -469,6 +475,7 @@ int cert_stuff(struct connectdata *conn,
cert_file);
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
return 0;
}
@@ -477,6 +484,7 @@ int cert_stuff(struct connectdata *conn,
"does not match certificate in same file", cert_file);
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
return 0;
}
/* Set Certificate Verification chain */
@@ -486,12 +494,14 @@ int cert_stuff(struct connectdata *conn,
failf(data, "cannot add certificate to certificate chain");
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
return 0;
}
if(!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) {
failf(data, "cannot add certificate to client CA list");
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
return 0;
}
}
@@ -499,6 +509,7 @@ int cert_stuff(struct connectdata *conn,
EVP_PKEY_free(pri);
X509_free(x509);
sk_X509_pop_free(ca, X509_free);
cert_done = 1;
break;
#else
@@ -1420,6 +1431,7 @@ ossl_connect_step1(struct connectdata *conn,
X509_LOOKUP *lookup=NULL;
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long ctx_options;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
bool sni;
#ifdef ENABLE_IPV6
@@ -1525,20 +1537,43 @@ ossl_connect_step1(struct connectdata *conn,
If someone writes an application with libcurl and openssl who wants to
enable the feature, one can do this in the SSL callback.
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
interoperability with web server Netscape Enterprise Server 2.0.1 which
was released back in 1996.
Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
CVE-2010-4180 when using previous OpenSSL versions we no longer enable
this option regardless of OpenSSL version and SSL_OP_ALL definition.
OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
(http://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
SSL_OP_ALL that _disables_ that work-around despite the fact that
SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
must not be set.
*/
ctx_options = SSL_OP_ALL;
#ifdef SSL_OP_NO_TICKET
/* expect older openssl releases to not have this define so only use it if
present */
#define CURL_CTX_OPTIONS SSL_OP_ALL|SSL_OP_NO_TICKET
#else
#define CURL_CTX_OPTIONS SSL_OP_ALL
ctx_options |= SSL_OP_NO_TICKET;
#endif
SSL_CTX_set_options(connssl->ctx, CURL_CTX_OPTIONS);
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
/* mitigate CVE-2010-4180 */
ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
#endif
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
/* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */
if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT)
SSL_CTX_set_options(connssl->ctx, SSL_OP_NO_SSLv2);
ctx_options |= SSL_OP_NO_SSLv2;
SSL_CTX_set_options(connssl->ctx, ctx_options);
#if 0
/*
@@ -1631,7 +1666,8 @@ ossl_connect_step1(struct connectdata *conn,
if(data->set.str[STRING_SSL_CRLFILE]) {
/* tell SSL where to find CRL file that is used to check certificate
* revocation */
lookup=X509_STORE_add_lookup(connssl->ctx->cert_store,X509_LOOKUP_file());
lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
X509_LOOKUP_file());
if(!lookup ||
(!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE],
X509_FILETYPE_PEM)) ) {
@@ -1642,7 +1678,7 @@ ossl_connect_step1(struct connectdata *conn,
else {
/* Everything is fine. */
infof(data, "successfully load CRL file:\n");
X509_STORE_set_flags(connssl->ctx->cert_store,
X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
}
infof(data,

View File

@@ -81,6 +81,12 @@ curl_easy_strerror(CURLcode error)
case CURLE_REMOTE_ACCESS_DENIED:
return "Access denied to remote resource";
case CURLE_FTP_ACCEPT_FAILED:
return "FTP: The server failed to connect to data port";
case CURLE_FTP_ACCEPT_TIMEOUT:
return "FTP: Accepting server connect has timed out";
case CURLE_FTP_PRET_FAILED:
return "FTP: The server did not accept the PRET command.";
@@ -284,8 +290,6 @@ curl_easy_strerror(CURLcode error)
return "Chunk callback failed";
/* error codes not used by current libcurl */
case CURLE_OBSOLETE10:
case CURLE_OBSOLETE12:
case CURLE_OBSOLETE16:
case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24:

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -75,12 +75,17 @@
#define SUBBUFSIZE 512
#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer;
#define CURL_SB_TERM(x) { x->subend = x->subpointer; CURL_SB_CLEAR(x); }
#define CURL_SB_ACCUM(x,c) \
if(x->subpointer < (x->subbuffer+sizeof x->subbuffer)) { \
*x->subpointer++ = (c); \
}
#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer
#define CURL_SB_TERM(x) \
do { \
x->subend = x->subpointer; \
CURL_SB_CLEAR(x); \
} WHILE_FALSE
#define CURL_SB_ACCUM(x,c) \
do { \
if(x->subpointer < (x->subbuffer+sizeof x->subbuffer)) \
*x->subpointer++ = (c); \
} WHILE_FALSE
#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
@@ -116,10 +121,13 @@ static void printsub(struct SessionHandle *data,
int direction, unsigned char *pointer,
size_t length);
static void suboption(struct connectdata *);
static void sendsuboption(struct connectdata *conn, int option);
static CURLcode telnet_do(struct connectdata *conn, bool *done);
static CURLcode telnet_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode send_telnet_data(struct connectdata *conn,
char *buffer, ssize_t nread);
/* For negotiation compliant to RFC 1143 */
#define CURL_NO 0
@@ -155,9 +163,12 @@ struct TELNET {
int him[256];
int himq[256];
int him_preferred[256];
int subnegotiation[256];
char subopt_ttype[32]; /* Set with suboption TTYPE */
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
struct curl_slist *telnet_vars; /* Environment variables */
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
unsigned short subopt_wsx; /* Set with suboption NAWS */
unsigned short subopt_wsy; /* Set with suboption NAWS */
struct curl_slist *telnet_vars; /* Environment variables */
/* suboptions */
unsigned char subbuffer[SUBBUFSIZE];
@@ -188,7 +199,7 @@ const struct Curl_handler Curl_handler_telnet = {
ZERO_NULL, /* readwrite */
PORT_TELNET, /* defport */
CURLPROTO_TELNET, /* protocol */
PROTOPT_NONE /* flags */
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
@@ -249,11 +260,37 @@ CURLcode init_telnet(struct connectdata *conn)
CURL_SB_CLEAR(tn);
/* Set the options we want by default */
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES;
/* To be compliant with previous releases of libcurl
we enable this option by default. This behaviour
can be changed thanks to the "BINARY" option in
CURLOPT_TELNETOPTIONS
*/
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
/* We must allow the server to echo what we sent
but it is not necessary to request the server
to do so (it might forces the server to close
the connection). Hence, we ignore ECHO in the
negotiate function
*/
tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES;
/* Set the subnegotiation fields to send information
just after negotiation passed (do/will)
Default values are (0,0) initialized by calloc.
According to the RFC1013 it is valid:
A value equal to zero is acceptable for the width (or height),
and means that no character width (or height) is being sent.
In this case, the width (or height) that will be assumed by the
Telnet server is operating system specific (it will probably be
based upon the terminal type information that may have been sent
using the TERMINAL TYPE Telnet option). */
tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES;
return CURLE_OK;
}
@@ -263,6 +300,9 @@ static void negotiate(struct connectdata *conn)
struct TELNET *tn = (struct TELNET *) conn->data->state.proto.telnet;
for(i = 0;i < CURL_NTELOPTS;i++) {
if(i==CURL_TELOPT_ECHO)
continue;
if(tn->us_preferred[i] == CURL_YES)
set_local_option(conn, i, CURL_YES);
@@ -575,6 +615,15 @@ void rec_do(struct connectdata *conn, int option)
if(tn->us_preferred[option] == CURL_YES) {
tn->us[option] = CURL_YES;
send_negotiation(conn, CURL_WILL, option);
if(tn->subnegotiation[option] == CURL_YES)
/* transmission of data option */
sendsuboption(conn, option);
}
else if(tn->subnegotiation[option] == CURL_YES) {
/* send information to achieve this option*/
tn->us[option] = CURL_YES;
send_negotiation(conn, CURL_WILL, option);
sendsuboption(conn, option);
}
else
send_negotiation(conn, CURL_WONT, option);
@@ -602,6 +651,10 @@ void rec_do(struct connectdata *conn, int option)
switch(tn->usq[option]) {
case CURL_EMPTY:
tn->us[option] = CURL_YES;
if(tn->subnegotiation[option] == CURL_YES) {
/* transmission of data option */
sendsuboption(conn, option);
}
break;
case CURL_OPPOSITE:
tn->us[option] = CURL_WANTNO;
@@ -662,6 +715,7 @@ static void printsub(struct SessionHandle *data,
size_t length) /* length of suboption data */
{
unsigned int i = 0;
unsigned short *pval;
if(data->set.verbose) {
if(direction) {
@@ -698,20 +752,28 @@ static void printsub(struct SessionHandle *data,
if(CURL_TELOPT_OK(pointer[0])) {
switch(pointer[0]) {
case CURL_TELOPT_TTYPE:
case CURL_TELOPT_XDISPLOC:
case CURL_TELOPT_NEW_ENVIRON:
infof(data, "%s", CURL_TELOPT(pointer[0]));
break;
default:
infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
break;
case CURL_TELOPT_TTYPE:
case CURL_TELOPT_XDISPLOC:
case CURL_TELOPT_NEW_ENVIRON:
case CURL_TELOPT_NAWS:
infof(data, "%s", CURL_TELOPT(pointer[0]));
break;
default:
infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
break;
}
}
else
infof(data, "%d (unknown)", pointer[i]);
switch(pointer[1]) {
switch(pointer[0]) {
case CURL_TELOPT_NAWS:
pval = (unsigned short*)(pointer+1);
infof(data, "Width: %hu ; Height: %hu",
ntohs(pval[0]), ntohs(pval[1]));
break;
default:
switch(pointer[1]) {
case CURL_TELQUAL_IS:
infof(data, " IS");
break;
@@ -724,9 +786,9 @@ static void printsub(struct SessionHandle *data,
case CURL_TELQUAL_NAME:
infof(data, " NAME");
break;
}
}
switch(pointer[0]) {
switch(pointer[0]) {
case CURL_TELOPT_TTYPE:
case CURL_TELOPT_XDISPLOC:
pointer[length] = 0;
@@ -737,15 +799,15 @@ static void printsub(struct SessionHandle *data,
infof(data, " ");
for(i = 3;i < length;i++) {
switch(pointer[i]) {
case CURL_NEW_ENV_VAR:
infof(data, ", ");
break;
case CURL_NEW_ENV_VALUE:
infof(data, " = ");
break;
default:
infof(data, "%c", pointer[i]);
break;
case CURL_NEW_ENV_VAR:
infof(data, ", ");
break;
case CURL_NEW_ENV_VALUE:
infof(data, " = ");
break;
default:
infof(data, "%c", pointer[i]);
break;
}
}
}
@@ -754,8 +816,8 @@ static void printsub(struct SessionHandle *data,
for(i = 2; i < length; i++)
infof(data, " %.2x", pointer[i]);
break;
}
}
if(direction)
infof(data, "\n");
}
@@ -770,6 +832,7 @@ static CURLcode check_telnet_options(struct connectdata *conn)
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->data->state.proto.telnet;
CURLcode result = CURLE_OK;
int binary_option;
/* Add the user name as an environment variable if it
was given on the command line */
@@ -817,6 +880,29 @@ static CURLcode check_telnet_options(struct connectdata *conn)
continue;
}
/* Window Size */
if(Curl_raw_equal(option_keyword, "WS")) {
if(sscanf(option_arg, "%hu%*[xX]%hu",
&tn->subopt_wsx, &tn->subopt_wsy) == 2)
tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
else {
failf(data, "Syntax error in telnet option: %s", head->data);
result = CURLE_TELNET_OPTION_SYNTAX;
break;
}
continue;
}
/* To take care or not of the 8th bit in data exchange */
if(Curl_raw_equal(option_keyword, "BINARY")) {
binary_option=atoi(option_arg);
if(binary_option!=1) {
tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
}
continue;
}
failf(data, "Unknown telnet option %s", head->data);
result = CURLE_UNKNOWN_TELNET_OPTION;
break;
@@ -913,6 +999,69 @@ static void suboption(struct connectdata *conn)
return;
}
/*
* sendsuboption()
*
* Send suboption information to the server side.
*/
static void sendsuboption(struct connectdata *conn, int option)
{
ssize_t bytes_written;
int err;
unsigned short x, y;
unsigned char*uc1, *uc2;
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)data->state.proto.telnet;
switch (option) {
case CURL_TELOPT_NAWS:
/* We prepare data to be sent */
CURL_SB_CLEAR(tn);
CURL_SB_ACCUM(tn, CURL_IAC);
CURL_SB_ACCUM(tn, CURL_SB);
CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
/* We must deal either with litte or big endien processors */
/* Window size must be sent according to the 'network order' */
x=htons(tn->subopt_wsx);
y=htons(tn->subopt_wsy);
uc1 = (unsigned char*)&x;
uc2 = (unsigned char*)&y;
CURL_SB_ACCUM(tn, uc1[0]);
CURL_SB_ACCUM(tn, uc1[1]);
CURL_SB_ACCUM(tn, uc2[0]);
CURL_SB_ACCUM(tn, uc2[1]);
CURL_SB_ACCUM(tn, CURL_IAC);
CURL_SB_ACCUM(tn, CURL_SE);
CURL_SB_TERM(tn);
/* data suboption is now ready */
printsub(data, '>', (unsigned char *)tn->subbuffer+2,
CURL_SB_LEN(tn)-2);
/* we send the header of the suboption... */
bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
if(bytes_written < 0) {
err = SOCKERRNO;
failf(data, "Sending data failed (%d)", err);
}
/* ... then the window size with the send_telnet_data() function
to deal with 0xFF cases ... */
send_telnet_data(conn, (char *)tn->subbuffer+3, 4);
/* ... and the footer */
bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer+7, 2);
if(bytes_written < 0) {
err = SOCKERRNO;
failf(data, "Sending data failed (%d)", err);
}
break;
}
}
static
CURLcode telrcv(struct connectdata *conn,
const unsigned char *inbuf, /* Data received from socket */
@@ -1124,11 +1273,13 @@ static CURLcode telnet_done(struct connectdata *conn,
(void)status; /* unused */
(void)premature; /* not used */
if(!tn)
return CURLE_OK;
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
free(conn->data->state.proto.telnet);
conn->data->state.proto.telnet = NULL;
Curl_safefree(conn->data->state.proto.telnet);
return CURLE_OK;
}
@@ -1420,12 +1571,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
pfd[0].fd = sockfd;
pfd[0].events = POLLIN;
if(data->set.is_fread_set) {
if(conn->fread_func != (curl_read_callback)fread) {
poll_cnt = 1;
interval_ms = 100; /* poll user-supplied read function */
}
else {
pfd[1].fd = 0;
/* really using fread, so infile is a FILE* */
pfd[1].fd = fileno((FILE *)conn->fread_in);
pfd[1].events = POLLIN;
poll_cnt = 2;
interval_ms = 1 * 1000;
@@ -1478,8 +1630,8 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
nread = 0;
if(poll_cnt == 2) {
if(pfd[1].revents & POLLIN) { /* read from stdin */
nread = read(0, buf, BUFSIZE - 1);
if(pfd[1].revents & POLLIN) { /* read from in file */
nread = read(pfd[1].fd, buf, BUFSIZE - 1);
}
}
else {

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -190,7 +190,7 @@ const struct Curl_handler Curl_handler_tftp = {
ZERO_NULL, /* readwrite */
PORT_TFTP, /* defport */
CURLPROTO_TFTP, /* protocol */
PROTOPT_NONE /* flags */
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
};
/**********************************************************
@@ -727,7 +727,7 @@ static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
}
else {
/* Re-send the data packet */
sbytes = sendto(state->sockfd, (void *)&state->spacket.data,
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
4+state->sbytes, SEND_4TH_ARG,
(struct sockaddr *)&state->remote_addr,
state->remote_addrlen);

View File

@@ -120,8 +120,11 @@ long curlx_tvdiff(struct timeval newer, struct timeval older)
*/
double curlx_tvdiff_secs(struct timeval newer, struct timeval older)
{
return (double)(newer.tv_sec-older.tv_sec)+
(double)(newer.tv_usec-older.tv_usec)/1000000.0;
if(newer.tv_sec != older.tv_sec)
return (double)(newer.tv_sec-older.tv_sec)+
(double)(newer.tv_usec-older.tv_usec)/1000000.0;
else
return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
}
/* return the number of seconds in the given input timeval struct */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -332,7 +332,7 @@ static void read_rewind(struct connectdata *conn,
}
DEBUGF(infof(conn->data,
"Buffer after stream rewind (read_pos = %zu): [%s]",
"Buffer after stream rewind (read_pos = %zu): [%s]\n",
conn->read_pos, buf));
}
#endif
@@ -606,7 +606,8 @@ static CURLcode readwrite_data(struct SessionHandle *data,
dataleft = conn->chunk.dataleft;
if(dataleft != 0) {
infof(conn->data, "Leftovers after chunking: %zu bytes", dataleft);
infof(conn->data, "Leftovers after chunking: %zu bytes\n",
dataleft);
if(conn->data->multi &&
Curl_multi_canPipeline(conn->data->multi)) {
/* only attempt the rewind if we truly are pipelining */
@@ -1405,52 +1406,6 @@ Transfer(struct connectdata *conn)
return CURLE_OK;
}
static CURLcode loadhostpairs(struct SessionHandle *data)
{
struct curl_slist *hostp;
char hostname[256];
char address[256];
int port;
for(hostp = data->change.resolve; hostp; hostp = hostp->next ) {
if(!hostp->data)
continue;
if(hostp->data[0] == '-') {
/* TODO: mark an entry for removal */
}
else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
address)) {
struct Curl_dns_entry *dns;
Curl_addrinfo *addr;
addr = Curl_str2addr(address, port);
if(!addr) {
infof(data, "Resolve %s found illegal!\n", hostp->data);
continue;
}
infof(data, "Added %s:%d:%s to DNS cache\n",
hostname, port, address);
if(data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
/* put this host in the cache */
dns = Curl_cache_addr(data, addr, hostname, port);
if(data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
if(!dns) {
Curl_freeaddrinfo(addr);
return CURLE_OUT_OF_MEMORY;
}
}
}
data->change.resolve = NULL; /* dealt with now */
return CURLE_OK;
}
/*
* Curl_pretransfer() is called immediately before a transfer starts.
@@ -1465,9 +1420,9 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
}
/* Init the SSL session ID cache here. We do it here since we want to do it
after the *_setopt() calls (that could change the size of the cache) but
after the *_setopt() calls (that could specify the size of the cache) but
before any transfer takes place. */
res = Curl_ssl_initsessions(data, data->set.ssl.numsessions);
res = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
if(res)
return res;
@@ -1490,7 +1445,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
/* If there is a list of host pairs to deal with */
if(data->change.resolve)
res = loadhostpairs(data);
res = Curl_loadhostpairs(data);
if(!res) {
/* Allow data->set.use_port to set which port to use. This needs to be
@@ -2364,7 +2319,7 @@ Curl_setup_transfer(
(data->state.proto.http->sending == HTTPSEND_BODY)) {
/* wait with write until we either got 100-continue or a timeout */
k->exp100 = EXP100_AWAITING_CONTINUE;
k->start100 = k->start;
k->start100 = Curl_tvnow();
/* set a timeout for the multi interface */
Curl_expire(data, CURL_TIMEOUT_EXPECT_100);

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