Compare commits
243 Commits
curl-7_27_
...
curl-7_28_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9fdb721f2 | ||
|
|
c830115c48 | ||
|
|
52af6e69f0 | ||
|
|
32be348af2 | ||
|
|
7e87499213 | ||
|
|
7719333f55 | ||
|
|
276452ca10 | ||
|
|
1b10dd7aae | ||
|
|
7aebb3cc42 | ||
|
|
6f444b2761 | ||
|
|
81d96c4421 | ||
|
|
10296ac665 | ||
|
|
ab0fa55780 | ||
|
|
409f2a041f | ||
|
|
dd75cba3ef | ||
|
|
ee588fe088 | ||
|
|
db4215f14a | ||
|
|
32afaaef93 | ||
|
|
0ac827848d | ||
|
|
c277bd6ce7 | ||
|
|
6d8443a245 | ||
|
|
53c83ee3ed | ||
|
|
fa1ae0abcd | ||
|
|
38ed72cd37 | ||
|
|
1099f3a071 | ||
|
|
6a4bdb027b | ||
|
|
7c0cbcf2f6 | ||
|
|
076e1fa348 | ||
|
|
cd5261ea6d | ||
|
|
4b994e14fb | ||
|
|
e62ee60c7a | ||
|
|
e237402c47 | ||
|
|
1c23d2b392 | ||
|
|
7ecd874bce | ||
|
|
49c37e6c1c | ||
|
|
dca8ae5f02 | ||
|
|
cf75a64651 | ||
|
|
0af1a9d270 | ||
|
|
1394cad30f | ||
|
|
18c0e9bd71 | ||
|
|
c70c1a22d2 | ||
|
|
5a4f6413d1 | ||
|
|
6d1b493f3d | ||
|
|
7840c4c70c | ||
|
|
9096f4f451 | ||
|
|
487538e87a | ||
|
|
e1fa945e7e | ||
|
|
cda6d891ab | ||
|
|
473003fbdf | ||
|
|
3f20303702 | ||
|
|
a1be8e7f9b | ||
|
|
8d97bed806 | ||
|
|
13ce9031cc | ||
|
|
95326a40ff | ||
|
|
8e329bb759 | ||
|
|
da82f59b69 | ||
|
|
ab1f80200a | ||
|
|
41eec4efa2 | ||
|
|
2045d83dd3 | ||
|
|
0da6c113ce | ||
|
|
fa6d78829f | ||
|
|
550e403f00 | ||
|
|
f99430d89e | ||
|
|
09a491378a | ||
|
|
9019a0a86c | ||
|
|
b2954e66e8 | ||
|
|
7c0f201075 | ||
|
|
0ecb57056f | ||
|
|
3be96564a8 | ||
|
|
0cb5650386 | ||
|
|
8f61e5cea7 | ||
|
|
34ff881ece | ||
|
|
af121ccad8 | ||
|
|
c81eb7e226 | ||
|
|
74fe1b95fb | ||
|
|
d1c769877a | ||
|
|
94891ff296 | ||
|
|
12a40e17a9 | ||
|
|
8ffc971138 | ||
|
|
f1d2e18508 | ||
|
|
1a02e84589 | ||
|
|
c79c0909d9 | ||
|
|
3fc5779b91 | ||
|
|
ff32546d81 | ||
|
|
99b036c9b2 | ||
|
|
33c02d4771 | ||
|
|
8373ca3641 | ||
|
|
3644a35027 | ||
|
|
542802af23 | ||
|
|
9547be37c2 | ||
|
|
974d5d5921 | ||
|
|
211605f0c5 | ||
|
|
a5b6f91e8d | ||
|
|
fbf3560886 | ||
|
|
07593b2422 | ||
|
|
cd423348d9 | ||
|
|
90821c6202 | ||
|
|
dee2ef8083 | ||
|
|
50a7d32af0 | ||
|
|
a5c6ecba8d | ||
|
|
7a53474f43 | ||
|
|
6b18f18b4c | ||
|
|
971f5bcedd | ||
|
|
42bbc5ce10 | ||
|
|
c01b6f4d09 | ||
|
|
9da2c96039 | ||
|
|
e8ab9a0d27 | ||
|
|
628c4e7af1 | ||
|
|
4ea7a65af7 | ||
|
|
d89861f651 | ||
|
|
0c8ccf7207 | ||
|
|
39dff07a27 | ||
|
|
84e6c7a9e5 | ||
|
|
c1400f6f12 | ||
|
|
889038f668 | ||
|
|
907a9d25e8 | ||
|
|
b3d72a95be | ||
|
|
b78944146a | ||
|
|
9b25b00fa3 | ||
|
|
ba41ecfa17 | ||
|
|
1ab6c35363 | ||
|
|
5162cb8ad6 | ||
|
|
8a2be299f4 | ||
|
|
f73a27cadc | ||
|
|
f332f14102 | ||
|
|
775cc1be66 | ||
|
|
f05e51362f | ||
|
|
ce515e993f | ||
|
|
a34197ef77 | ||
|
|
7f7e2ea72f | ||
|
|
4d384a8714 | ||
|
|
c44e6741ce | ||
|
|
94c3e0f702 | ||
|
|
c8846c0907 | ||
|
|
f9da9a0edb | ||
|
|
6372144be0 | ||
|
|
ef753b710b | ||
|
|
e6ba048701 | ||
|
|
71813f5e46 | ||
|
|
a6df3550cf | ||
|
|
8a57b3c972 | ||
|
|
f665e5d130 | ||
|
|
fa4b4d2033 | ||
|
|
a492632022 | ||
|
|
6c6f1f64c2 | ||
|
|
160312d945 | ||
|
|
badb81769a | ||
|
|
8b5d050267 | ||
|
|
2e7d2c8f74 | ||
|
|
3a0b64489f | ||
|
|
ee3551e45e | ||
|
|
1b0477a5a9 | ||
|
|
4ae2f77ba1 | ||
|
|
0a0f3c63a6 | ||
|
|
da0d15733c | ||
|
|
cb2feb9def | ||
|
|
abb0da9193 | ||
|
|
b6a141ea8a | ||
|
|
ca84361e4b | ||
|
|
09d9dd8873 | ||
|
|
925707c0f8 | ||
|
|
de24d7bd4c | ||
|
|
2f6e1a8cc3 | ||
|
|
40153716a3 | ||
|
|
7735141e73 | ||
|
|
5ede86ae51 | ||
|
|
3b7d31c1ed | ||
|
|
d4af0bb8f6 | ||
|
|
4eec66e479 | ||
|
|
4c070de4fb | ||
|
|
54faab69cb | ||
|
|
8136649e9d | ||
|
|
71358ddffd | ||
|
|
be5fbf7372 | ||
|
|
ba569a27cc | ||
|
|
0f76e492ae | ||
|
|
a90492a083 | ||
|
|
f4b4365c19 | ||
|
|
d792e75f2c | ||
|
|
41a3bff3da | ||
|
|
82b0aebef3 | ||
|
|
23ef5e4ba2 | ||
|
|
44154e0733 | ||
|
|
d22186bbbc | ||
|
|
b8983aa309 | ||
|
|
4dcde5aa3d | ||
|
|
99f0e45b61 | ||
|
|
7520f9f1c3 | ||
|
|
f208bf5a2d | ||
|
|
52b6eda4f2 | ||
|
|
73342f0ee0 | ||
|
|
0774386b23 | ||
|
|
e351972bc8 | ||
|
|
021e89b8c6 | ||
|
|
4dd44d9c20 | ||
|
|
31f39120b7 | ||
|
|
b9fb9c2380 | ||
|
|
14afbf361a | ||
|
|
bf6dc61967 | ||
|
|
1de496cf0f | ||
|
|
154fc29f58 | ||
|
|
52db6e370d | ||
|
|
672f24b1dc | ||
|
|
2f02d825f1 | ||
|
|
15108d6308 | ||
|
|
c771968ab6 | ||
|
|
b61e8b81f5 | ||
|
|
77f72aa6c3 | ||
|
|
b4a558041f | ||
|
|
8bad5f2a61 | ||
|
|
f0d611df9e | ||
|
|
013d043d22 | ||
|
|
382429e760 | ||
|
|
0b08491f83 | ||
|
|
5fbf4e348c | ||
|
|
73b1a965f7 | ||
|
|
42e4c34ff3 | ||
|
|
0df14c8393 | ||
|
|
60a2ee88a5 | ||
|
|
66a77a9b49 | ||
|
|
3b9103e4a6 | ||
|
|
77c66e0247 | ||
|
|
9f304291bd | ||
|
|
986c7949c0 | ||
|
|
69f5fe070d | ||
|
|
5dedda1448 | ||
|
|
24c43e9d34 | ||
|
|
50b87c4e68 | ||
|
|
ce8311c7e4 | ||
|
|
674da8ae07 | ||
|
|
84490052d4 | ||
|
|
19035292d0 | ||
|
|
81656a8466 | ||
|
|
76ba591957 | ||
|
|
1f8518c5d9 | ||
|
|
a52857cb02 | ||
|
|
9e01625779 | ||
|
|
6e1f867523 | ||
|
|
cd350e3829 | ||
|
|
0bededd7c5 | ||
|
|
a797e9efdf | ||
|
|
27893c64f3 | ||
|
|
dd4699c111 |
@@ -1,5 +1,10 @@
|
||||
# Google Android makefile for curl and libcurl
|
||||
#
|
||||
# This file can be used when building curl using the full Android source
|
||||
# release or the NDK. Most users do not want or need to do this; please
|
||||
# instead read the Android section in docs/INSTALL for alternate
|
||||
# methods.
|
||||
#
|
||||
# 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 versions 1.5, 2.1-2.3
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
# Adds OPENSSL_INCLUDE_DIRS and libeay32
|
||||
include("${CMAKE_ROOT}/Modules/FindOpenSSL.cmake")
|
||||
|
||||
# Bill Hoffman told that libeay32 is necessary for him:
|
||||
find_library(SSL_LIBEAY NAMES libeay32)
|
||||
# starting 2.8 it is better to use standard modules
|
||||
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
# Bill Hoffman told that libeay32 is necessary for him:
|
||||
find_library(SSL_LIBEAY NAMES libeay32)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
if(SSL_LIBEAY)
|
||||
list(APPEND OPENSSL_LIBRARIES ${SSL_LIBEAY})
|
||||
else()
|
||||
set(OPENSSL_FOUND FALSE)
|
||||
if(OPENSSL_FOUND)
|
||||
if(SSL_LIBEAY)
|
||||
list(APPEND OPENSSL_LIBRARIES ${SSL_LIBEAY})
|
||||
else()
|
||||
set(OPENSSL_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif() # if (CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Locate zlib
|
||||
include("${CMAKE_ROOT}/Modules/FindZLIB.cmake")
|
||||
|
||||
find_library(ZLIB_LIBRARY_DEBUG NAMES zd zlibd zdlld zlib1d )
|
||||
|
||||
if(ZLIB_FOUND AND ZLIB_LIBRARY_DEBUG)
|
||||
set( ZLIB_LIBRARIES optimized "${ZLIB_LIBRARY}" debug ${ZLIB_LIBRARY_DEBUG})
|
||||
# starting 2.8 it is better to use standard modules
|
||||
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
find_library(ZLIB_LIBRARY_DEBUG NAMES zd zlibd zdlld zlib1d )
|
||||
if(ZLIB_FOUND AND ZLIB_LIBRARY_DEBUG)
|
||||
set( ZLIB_LIBRARIES optimized "${ZLIB_LIBRARY}" debug ${ZLIB_LIBRARY_DEBUG})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
115
RELEASE-NOTES
115
RELEASE-NOTES
@@ -1,52 +1,51 @@
|
||||
Curl and libcurl 7.27.0
|
||||
Curl and libcurl 7.28.1
|
||||
|
||||
Public curl releases: 128
|
||||
Public curl releases: 130
|
||||
Command line options: 152
|
||||
curl_easy_setopt() options: 199
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 953
|
||||
Contributors: 979
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o nss: use human-readable error messages provided by NSS
|
||||
o added --metalink for metalink download support [5]
|
||||
o pop3: Added support for sasl plain text authentication
|
||||
o pop3: Added support for sasl login authentication
|
||||
o pop3: Added support for sasl ntlm authentication
|
||||
o pop3: Added support for sasl cram-md5 authentication
|
||||
o pop3: Added support for sasl digest-md5 authentication
|
||||
o pop3: Added support for apop authentication
|
||||
o Added support for Schannel (Native Windows) SSL/TLS encryption [2]
|
||||
o Added support for Darwin SSL (Native Mac OS X and iOS) [6]
|
||||
o http: print reason phrase from HTTP status line on error [8]
|
||||
o metalink/md5: Use CommonCrypto on Apple operating systems
|
||||
o href_extractor: new example code extracting href elements
|
||||
o NSS can be used for metalink hashing [13]
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o pop3: Fixed the issue of having to supply the user name for all requests
|
||||
o configure: fix LDAPS disabling related misplaced closing parenthesis
|
||||
o cmdline: made -D option work with -O and -J
|
||||
o configure: Fix libcurl.pc and curl-config generation for static MingW*
|
||||
cross builds
|
||||
o ssl: fix duplicated SSL handshake with multi interface and proxy [1]
|
||||
o winbuild: Fix Makefile.vc ignoring USE_IPV6 and USE_IDN flags
|
||||
o OpenSSL: support longer certificate subject names [3]
|
||||
o openldap: OOM fixes
|
||||
o log2changes.pl: fix the Version output
|
||||
o lib554.c: use curl_formadd() properly [4]
|
||||
o urldata.h: fix cyassl build clash with wincrypt.h
|
||||
o cookies: changed the URL in the cookiejar headers [7]
|
||||
o http-proxy: keep CONNECT connections alive (for NTLM)
|
||||
o NTLM SSPI: fixed to work with unicode user names and passwords
|
||||
o OOM fix in the curl tool when cloning cmdline options
|
||||
o fixed some examples to use curl_global_init() properly
|
||||
o cmdline: stricter numerical option parser
|
||||
o HTTP HEAD: don't force-close after response-headers
|
||||
o test231: fix wrong -C use
|
||||
o docs: switch to proper UTF-8 for text file encoding
|
||||
o keepalive: DragonFly uses milliseconds [9]
|
||||
o HTTP Digest: Client's "qop" value should not be quoted
|
||||
o make distclean works again
|
||||
o Fix broken libmetalink-aware OpenSSL build
|
||||
o gnutls: fix the error is fatal logic [1]
|
||||
o darwinssl: un-broke iOS build, fix error on server disconnect
|
||||
o asyn-ares: restore functionality with c-ares < 1.6.1 [2]
|
||||
o tlsauthtype: deal with the string case insensitively [3]
|
||||
o Fixed MSVC libssh2 static build
|
||||
o evhiperfifo: fix the pointer passed to WRITEDATA [6]
|
||||
o BUGS: fix the bug tracker URL [4]
|
||||
o winbuild: Use machine type of development environment
|
||||
o FTP: prevent the multi interface from blocking [5]
|
||||
o uniformly use AM_CPPFLAGS, avoid deprecated INCLUDES
|
||||
o httpcustomheader.c: free the headers after use
|
||||
o fix >2000 bytes POST over NTLM-using proxy [7]
|
||||
o redirects to URLs with fragments [8]
|
||||
o don't send '#' fragments when using proxy [9]
|
||||
o OpenSSL: show full issuer string [10]
|
||||
o fix HTTP auth regression [11]
|
||||
o CURLOPT_SSL_VERIFYHOST: stop supporting the 1 value [12]
|
||||
o ftp: EPSV-disable fix over SOCKS [14]
|
||||
o Digest: Add microseconds into nounce calculation [15]
|
||||
o SCP/SFTP: improve error code used for send failures
|
||||
o SSL: Several SSL-backend related fixes
|
||||
o removed the notorious "additional stuff not fine" debug output
|
||||
o OpenSSL: Disable SSL/TLS compression - avoid the "CRIME" attack
|
||||
o FILE: Make upload-writes unbuffered
|
||||
o custom memory callbacks failure with HTTP proxy (and more) [16]
|
||||
o TFTP: handle resends
|
||||
o autoconf: don't force-disable compiler debug option
|
||||
o winbuild: Fix PDB file output [17]
|
||||
o test2032: spurious failure caused by premature termination [18]
|
||||
o memory leak: CURLOPT_RESOLVE with multi interface [19]
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -55,22 +54,34 @@ 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:
|
||||
|
||||
Anthony Bryan, Guenter Knauf, Kamil Dudka, Steve Holme, Tatsuhiro Tsujikawa,
|
||||
Yang Tse, Gokhan Sengun, Marc Hoersken, Ghennadi Procopciuc, Gisle Vanem,
|
||||
Mark Salisbury, Anthony G. Basile, Enrico Scholz, Robert B. Harris,
|
||||
Neil Bowers, Marcel Raad, Christian Hägele, Philip Craig, Nick Zitzmann,
|
||||
Eelco Dolstra, Anton Yabchinskiy, Santhana Todatry, John Marino
|
||||
Guenter Knauf, Alessandro Ghedini, Nick Zitzmann, Michal Kowalczyk,
|
||||
Jeff Connelly, Oscar Norlander, Guido Berhoerster, Marc Hoersken,
|
||||
Dave Reisner, Jan Ehrhardt, John Suprock, Alessandro Ghedini,
|
||||
Lars Buitinck, Anton Malov, Sergei Nikulov, Patrick Monnerat,
|
||||
Gabriel Sjoberg, Oscar Koeroo, Fabian Keil, Johnny Luong, Cristian Rodríguez,
|
||||
Sebastian Rasmussen, Mark Snelling, Christian Vogt, Marcin Adamski,
|
||||
Ajit Dhumale, Alex Gruz
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
References to bug reports and discussions on issues:
|
||||
|
||||
[1] = https://bugzilla.redhat.com/788526
|
||||
[2] = http://daniel.haxx.se/blog/2012/06/12/schannel-support-in-libcurl/
|
||||
[3] = http://curl.haxx.se/bug/view.cgi?id=3533045
|
||||
[4] = http://curl.haxx.se/mail/lib-2012-06/0001.html
|
||||
[5] = http://daniel.haxx.se/blog/2012/06/03/curling-the-metalink/
|
||||
[6] = http://daniel.haxx.se/blog/2012/06/28/darwin-native-ssl-for-curl/
|
||||
[7] = http://daniel.haxx.se/blog/2012/07/08/curls-new-http-cookies-docs/
|
||||
[8] = https://bugzilla.redhat.com/676596
|
||||
[9] = http://curl.haxx.se/bug/view.cgi?id=3546257
|
||||
[1] = http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=690551
|
||||
[2] = http://curl.haxx.se/bug/view.cgi?id=3577710
|
||||
[3] = http://curl.haxx.se/bug/view.cgi?id=3578418
|
||||
[4] = http://curl.haxx.se/bug/view.cgi?id=3582408
|
||||
[5] = http://curl.haxx.se/bug/view.cgi?id=3579064
|
||||
[6] = http://curl.haxx.se/bug/view.cgi?id=3582407
|
||||
[7] = http://curl.haxx.se/bug/view.cgi?id=3582321
|
||||
[8] = http://curl.haxx.se/bug/view.cgi?id=3581898
|
||||
[9] = http://curl.haxx.se/bug/view.cgi?id=3579813
|
||||
[10] = http://curl.haxx.se/bug/view.cgi?id=3579286
|
||||
[11] = http://curl.haxx.se/bug/view.cgi?id=3582718
|
||||
[12] = http://daniel.haxx.se/blog/2012/10/25/libcurl-claimed-to-be-dangerous/
|
||||
[13] = http://curl.haxx.se/bug/view.cgi?id=3578163
|
||||
[14] = http://curl.haxx.se/bug/view.cgi?id=3586338
|
||||
[15] = https://github.com/bagder/curl/pull/50
|
||||
[16] = http://curl.haxx.se/mail/lib-2012-11/0125.html
|
||||
[17] = http://curl.haxx.se/bug/view.cgi?id=3586741
|
||||
[18] = http://curl.haxx.se/mail/lib-2012-11/0095.html
|
||||
[19] = http://curl.haxx.se/bug/view.cgi?id=3575448
|
||||
|
||||
19
TODO-RELEASE
19
TODO-RELEASE
@@ -1,21 +1,14 @@
|
||||
Try to fix in 7.27
|
||||
==================
|
||||
|
||||
313 - host.name vs. host.dispname and "(nil)" outputs
|
||||
|
||||
To be addressed in 7.28
|
||||
To be addressed in 7.29
|
||||
=======================
|
||||
|
||||
310 - a new authentication callback
|
||||
|
||||
312 - custom Content-Length appears in CONNECT, solve it by offering a separate
|
||||
option to provide headers for the CONNECT request
|
||||
|
||||
314 - CURL_SOCKOPTFUNCTION for accept()ed connection
|
||||
|
||||
315 - multiple receivers with SMTP and one fails
|
||||
312 - custom Content-Length appears in CONNECT, solve it by offering a
|
||||
separate option to provide headers for the CONNECT request:
|
||||
http://curl.haxx.se/mail/lib-2012-09/0059.html
|
||||
|
||||
317 - CURLINFO_SSL_TRUST to return SSL-specific data for a darwinssl build
|
||||
|
||||
318 -
|
||||
322 - pipelining improvements
|
||||
|
||||
327 -
|
||||
|
||||
@@ -30,7 +30,7 @@ XC_OVR_ZZ50
|
||||
CURL_OVERRIDE_AUTOCONF
|
||||
|
||||
dnl configure script copyright
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2011 Daniel Stenberg, <daniel@haxx.se>
|
||||
AC_COPYRIGHT([Copyright (c) 1998 - 2012 Daniel Stenberg, <daniel@haxx.se>
|
||||
This configure script may be copied, distributed and modified under the
|
||||
terms of the curl license; see COPYING for more details])
|
||||
|
||||
@@ -3074,10 +3074,6 @@ if test "$ipv6" = "yes"; then
|
||||
CURL_CHECK_NI_WITHSCOPEID
|
||||
fi
|
||||
|
||||
dnl ************************************************************
|
||||
dnl enable non-blocking communications
|
||||
dnl
|
||||
CURL_CHECK_OPTION_NONBLOCKING
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
dnl ************************************************************
|
||||
|
||||
@@ -135,9 +135,9 @@ while test $# -gt 0; do
|
||||
CPPFLAG_CURL_STATICLIB=""
|
||||
fi
|
||||
if test "X@includedir@" = "X/usr/include"; then
|
||||
echo "$(CPPFLAG_CURL_STATICLIB)"
|
||||
echo "$CPPFLAG_CURL_STATICLIB"
|
||||
else
|
||||
echo "$(CPPFLAG_CURL_STATICLIB)-I@includedir@"
|
||||
echo "${CPPFLAG_CURL_STATICLIB}-I@includedir@"
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
@@ -35,9 +35,11 @@ BUGS
|
||||
have a go at a solution. You can optionally also post your bug/problem at
|
||||
curl's bug tracking system over at
|
||||
|
||||
http://sourceforge.net/bugs/?group_id=976
|
||||
http://sourceforge.net/tracker/?group_id=976&atid=100976
|
||||
|
||||
(but please read the sections below first before doing that)
|
||||
Please read the rest of this document below first before doing that! Also,
|
||||
you need to login to your sourceforge account before being able to submit a
|
||||
bug report (necessary evil done to avoid spam).
|
||||
|
||||
If you feel you need to ask around first, find a suitable mailing list and
|
||||
post there. The lists are available on http://curl.haxx.se/mail/
|
||||
|
||||
18
docs/FAQ
18
docs/FAQ
@@ -1,4 +1,3 @@
|
||||
Updated: December 7, 2011 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -97,6 +96,7 @@ FAQ
|
||||
5.13 How do I stop an ongoing transfer?
|
||||
5.14 Using C++ non-static functions for callbacks?
|
||||
5.15 How do I get an FTP directory listing?
|
||||
5.16 I want a different time-out!
|
||||
|
||||
6. License Issues
|
||||
6.1 I have a GPL program, can I use the libcurl library?
|
||||
@@ -1294,6 +1294,22 @@ FAQ
|
||||
libcurl since 7.21.0 also provide the ability to specify a wildcard to
|
||||
download multiple files from one FTP directory.
|
||||
|
||||
5.16 I want a different time-out!
|
||||
|
||||
Time and time again users realize that CURLOPT_TIMEOUT and
|
||||
CURLOPT_CONNECTIMEOUT are not sufficiently advanced or flexible to cover all
|
||||
the various use cases and scenarios applications end up with.
|
||||
|
||||
libcurl offers many more ways to time-out operations. A common alternative
|
||||
is to use the CURLOPT_LOW_SPEED_LIMIT and CURLOPT_LOW_SPEED_TIME options to
|
||||
specify the lowest possible speed to accept before to consider the transfer
|
||||
timed out.
|
||||
|
||||
The most flexible way is by writing your own time-out logic and using
|
||||
CURLOPT_PROGRESSFUNCTION (perhaps in combination with other callbacks) and
|
||||
use that to figure out exactly when the right condition is met when the
|
||||
transfer should get stopped.
|
||||
|
||||
|
||||
6. License Issues
|
||||
|
||||
|
||||
11
docs/INSTALL
11
docs/INSTALL
@@ -970,8 +970,9 @@ REDUCING SIZE
|
||||
The GNU compiler and linker have a number of options that can reduce the
|
||||
size of the libcurl dynamic libraries on some platforms even further.
|
||||
Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
|
||||
configure command-line:
|
||||
CFLAGS="-ffunction-sections -fdata-sections" \
|
||||
configure command-line, e.g.
|
||||
CFLAGS="-Os -ffunction-sections -fdata-sections \
|
||||
-fno-unwind-tables -fno-asynchronous-unwind-tables" \
|
||||
LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
|
||||
|
||||
Be sure also to strip debugging symbols from your binaries after
|
||||
@@ -981,9 +982,9 @@ REDUCING SIZE
|
||||
.comment section).
|
||||
|
||||
Using these techniques it is possible to create a basic HTTP-only shared
|
||||
libcurl library for i386 Linux platforms that is only 101 KiB in size, and
|
||||
an FTP-only library that is 105 KiB in size (as of libcurl version 7.21.5,
|
||||
using gcc 4.4.3).
|
||||
libcurl library for i386 Linux platforms that is only 106 KiB in size, and
|
||||
an FTP-only library that is 108 KiB in size (as of libcurl version 7.27.0,
|
||||
using gcc 4.6.3).
|
||||
|
||||
You may find that statically linking libcurl to your application will
|
||||
result in a lower total size than dynamically linking.
|
||||
|
||||
@@ -18,6 +18,25 @@ Building with CMake
|
||||
CMake builds can be configured either from the command line, or from one
|
||||
of CMake's GUI's.
|
||||
|
||||
Current flaws in the curl CMake build
|
||||
=====================================
|
||||
|
||||
Missing features in the cmake build:
|
||||
|
||||
- Builds libcurl without large file support
|
||||
- It doesn't build src/hugehelp.c which creates the --manual output
|
||||
- Can't select which SSL library to build with, only OpenSSL
|
||||
- Doesn't build with SCP and SFTP support (libssh2)
|
||||
- Doesn't allow different resolver backends (no c-ares build support)
|
||||
- No RTMP support built
|
||||
- Doesn't allow build curl and libcurl debug enabled
|
||||
- Doesn't allow a custom CA bundle path
|
||||
- Doesn't allow you to disable specific protocols from the build
|
||||
- Doesn't properly enable IPv6 support by default
|
||||
- Doesn't find or use krb4 or GSS
|
||||
- Rebuilds test files too eagerly, but still can't run the tests
|
||||
|
||||
|
||||
Important notice
|
||||
==================
|
||||
If you got your curl sources from a distribution tarball, make sure to
|
||||
@@ -31,22 +50,28 @@ Important notice
|
||||
|
||||
Command Line CMake
|
||||
==================
|
||||
A command line build of Curl is similar to the autotools build of Curl. It
|
||||
A CMake build of curl is similar to the autotools build of curl. It
|
||||
consists of the following steps after you have unpacked the source.
|
||||
# 1st create an out of source build tree parallel to the curl source
|
||||
# tree and change into that directory
|
||||
mkdir curl-build
|
||||
cd curl-build
|
||||
# now run CMake from the build tree, giving it the path to the top of
|
||||
# the Curl source tree. CMake will pick a compiler for you. If you
|
||||
# want to specify the compile, you can set the CC environment
|
||||
# variable prior to running CMake.
|
||||
cmake ../curl
|
||||
make
|
||||
# currently make test is not implemented
|
||||
#make test
|
||||
# Install to default location:
|
||||
make install
|
||||
|
||||
1. Create an out of source build tree parallel to the curl source
|
||||
tree and change into that directory
|
||||
|
||||
$ mkdir curl-build
|
||||
$ cd curl-build
|
||||
|
||||
2. Run CMake from the build tree, giving it the path to the top of
|
||||
the curl source tree. CMake will pick a compiler for you. If you
|
||||
want to specify the compile, you can set the CC environment
|
||||
variable prior to running CMake.
|
||||
|
||||
$ cmake ../curl
|
||||
$ make
|
||||
|
||||
3. Install to default location:
|
||||
|
||||
$ make install
|
||||
|
||||
(The teste suit does not work with the cmake build)
|
||||
|
||||
ccmake
|
||||
=========
|
||||
|
||||
@@ -134,13 +134,6 @@ may have been fixed since this was written!
|
||||
38. Kumar Swamy Bhatt's problem in ftp/ssl "LIST" operation:
|
||||
http://curl.haxx.se/mail/lib-2007-01/0103.html
|
||||
|
||||
37. Having more than one connection to the same host when doing NTLM
|
||||
authentication (with performs multiple "passes" and authenticates a
|
||||
connection rather than a HTTP request), and particularly when using the
|
||||
multi interface, there's a risk that libcurl will re-use a wrong connection
|
||||
when doing the different passes in the NTLM negotiation and thus fail to
|
||||
negotiate (in seemingly mysterious ways).
|
||||
|
||||
35. Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very
|
||||
bad when used with the multi interface.
|
||||
|
||||
@@ -170,7 +163,6 @@ may have been fixed since this was written!
|
||||
to what winhttp does. See http://curl.haxx.se/bug/view.cgi?id=1281867
|
||||
|
||||
23. SOCKS-related problems:
|
||||
A) libcurl doesn't support SOCKS for IPv6.
|
||||
B) libcurl doesn't support FTPS over a SOCKS proxy.
|
||||
E) libcurl doesn't support active FTP over a SOCKS proxy
|
||||
|
||||
|
||||
110
docs/MANUAL
110
docs/MANUAL
@@ -19,7 +19,7 @@ SIMPLE USAGE
|
||||
|
||||
curl http://www.weirdserver.com:8000/
|
||||
|
||||
Get a list of a directory of an FTP site:
|
||||
Get a directory listing of an FTP site:
|
||||
|
||||
curl ftp://cool.haxx.se/
|
||||
|
||||
@@ -54,7 +54,7 @@ SIMPLE USAGE
|
||||
|
||||
DOWNLOAD TO A FILE
|
||||
|
||||
Get a web page and store in a local file:
|
||||
Get a web page and store in a local file with a specific name:
|
||||
|
||||
curl -o thatpage.html http://www.netscape.com/
|
||||
|
||||
@@ -113,9 +113,10 @@ USING PASSWORDS
|
||||
ones out of the ones that the server accepts for the given URL, by using
|
||||
--anyauth.
|
||||
|
||||
NOTE! Since HTTP URLs don't support user and password, you can't use that
|
||||
style when using Curl via a proxy. You _must_ use the -u style fetch
|
||||
during such circumstances.
|
||||
NOTE! According to the URL specification, HTTP URLs can not contain a user
|
||||
and password, so that style will not work when using curl via a proxy, even
|
||||
though curl allows it at other times. When using a proxy, you _must_ use
|
||||
the -u style for user and password.
|
||||
|
||||
HTTPS
|
||||
|
||||
@@ -133,7 +134,7 @@ PROXY
|
||||
|
||||
curl -x my-proxy:888 ftp://ftp.leachsite.com/README
|
||||
|
||||
Get a file from a HTTP server that requires user and password, using the
|
||||
Get a file from an HTTP server that requires user and password, using the
|
||||
same proxy as above:
|
||||
|
||||
curl -u user:passwd -x my-proxy:888 http://www.get.this/
|
||||
@@ -171,7 +172,7 @@ PROXY
|
||||
|
||||
RANGES
|
||||
|
||||
With HTTP 1.1 byte-ranges were introduced. Using this, a client can request
|
||||
HTTP 1.1 introduced byte-ranges. Using this, a client can request
|
||||
to get only one or more subparts of a specified document. Curl supports
|
||||
this with the -r flag.
|
||||
|
||||
@@ -202,8 +203,8 @@ UPLOADING
|
||||
|
||||
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile
|
||||
|
||||
Upload a local file to the remote site, and use the local file name remote
|
||||
too:
|
||||
Upload a local file to the remote site, and use the local file name at the remote
|
||||
site too:
|
||||
|
||||
curl -T uploadfile -u user:passwd ftp://ftp.upload.com/
|
||||
|
||||
@@ -219,14 +220,14 @@ UPLOADING
|
||||
|
||||
HTTP
|
||||
|
||||
Upload all data on stdin to a specified http site:
|
||||
Upload all data on stdin to a specified HTTP site:
|
||||
|
||||
curl -T - http://www.upload.com/myfile
|
||||
|
||||
Note that the http server must have been configured to accept PUT before
|
||||
Note that the HTTP server must have been configured to accept PUT before
|
||||
this can be done successfully.
|
||||
|
||||
For other ways to do http data upload, see the POST section below.
|
||||
For other ways to do HTTP data upload, see the POST section below.
|
||||
|
||||
VERBOSE / DEBUG
|
||||
|
||||
@@ -289,7 +290,7 @@ POST (HTTP)
|
||||
The 'variable' names are the names set with "name=" in the <input> tags, and
|
||||
the data is the contents you want to fill in for the inputs. The data *must*
|
||||
be properly URL encoded. That means you replace space with + and that you
|
||||
write weird letters with %XX where XX is the hexadecimal representation of
|
||||
replace weird letters with %XX where XX is the hexadecimal representation of
|
||||
the letter's ASCII code.
|
||||
|
||||
Example:
|
||||
@@ -361,8 +362,8 @@ POST (HTTP)
|
||||
|
||||
REFERRER
|
||||
|
||||
A HTTP request has the option to include information about which address
|
||||
that referred to actual page. Curl allows you to specify the
|
||||
An HTTP request has the option to include information about which address
|
||||
referred it to the actual page. Curl allows you to specify the
|
||||
referrer to be used on the command line. It is especially useful to
|
||||
fool or trick stupid servers or CGI scripts that rely on that information
|
||||
being available or contain certain data.
|
||||
@@ -373,7 +374,7 @@ REFERRER
|
||||
|
||||
USER AGENT
|
||||
|
||||
A HTTP request has the option to include information about the browser
|
||||
An HTTP request has the option to include information about the browser
|
||||
that generated the request. Curl allows it to be specified on the command
|
||||
line. It is especially useful to fool or trick stupid servers or CGI
|
||||
scripts that only accept certain browsers.
|
||||
@@ -618,16 +619,16 @@ FTP and firewalls
|
||||
|
||||
The default way for curl is to issue the PASV command which causes the
|
||||
server to open another port and await another connection performed by the
|
||||
client. This is good if the client is behind a firewall that don't allow
|
||||
client. This is good if the client is behind a firewall that doesn't allow
|
||||
incoming connections.
|
||||
|
||||
curl ftp.download.com
|
||||
|
||||
If the server for example, is behind a firewall that don't allow connections
|
||||
on other ports than 21 (or if it just doesn't support the PASV command), the
|
||||
If the server, for example, is behind a firewall that doesn't allow connections
|
||||
on ports other than 21 (or if it just doesn't support the PASV command), the
|
||||
other way to do it is to use the PORT command and instruct the server to
|
||||
connect to the client on the given (as parameters to the PORT command) IP
|
||||
number and port.
|
||||
connect to the client on the given IP number and port (as parameters to the
|
||||
PORT command).
|
||||
|
||||
The -P flag to curl supports a few different options. Your machine may have
|
||||
several IP-addresses and/or network interfaces and curl allows you to select
|
||||
@@ -685,8 +686,8 @@ HTTPS
|
||||
If you neglect to specify the password on the command line, you will be
|
||||
prompted for the correct password before any data can be received.
|
||||
|
||||
Many older SSL-servers have problems with SSLv3 or TLS, that newer versions
|
||||
of OpenSSL etc is using, therefore it is sometimes useful to specify what
|
||||
Many older SSL-servers have problems with SSLv3 or TLS, which newer versions
|
||||
of OpenSSL etc use, therefore it is sometimes useful to specify what
|
||||
SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL
|
||||
version to use (for SSLv3, SSLv2 or TLSv1 respectively):
|
||||
|
||||
@@ -695,14 +696,13 @@ HTTPS
|
||||
Otherwise, curl will first attempt to use v3 and then v2.
|
||||
|
||||
To use OpenSSL to convert your favourite browser's certificate into a PEM
|
||||
formatted one that curl can use, do something like this (assuming netscape,
|
||||
but IE is likely to work similarly):
|
||||
formatted one that curl can use, do something like this:
|
||||
|
||||
You start with hitting the 'security' menu button in netscape.
|
||||
In Netscape, you start with hitting the 'Security' menu button.
|
||||
|
||||
Select 'certificates->yours' and then pick a certificate in the list
|
||||
|
||||
Press the 'export' button
|
||||
Press the 'Export' button
|
||||
|
||||
enter your PIN code for the certs
|
||||
|
||||
@@ -713,11 +713,21 @@ HTTPS
|
||||
|
||||
# ./apps/openssl pkcs12 -in [file you saved] -clcerts -out [PEMfile]
|
||||
|
||||
In Firefox, select Options, then Advanced, then the Encryption tab,
|
||||
View Certificates. This opens the Certificate Manager, where you can
|
||||
Export. Be sure to select PEM for the Save as type.
|
||||
|
||||
In Internet Explorer, select Internet Options, then the Content tab, then
|
||||
Certificates. Then you can Export, and depending on the format you may
|
||||
need to convert to PEM.
|
||||
|
||||
In Chrome, select Settings, then Show Advanced Settings. Under HTTPS/SSL
|
||||
select Manage Certificates.
|
||||
|
||||
RESUMING FILE TRANSFERS
|
||||
|
||||
To continue a file transfer where it was previously aborted, curl supports
|
||||
resume on http(s) downloads as well as ftp uploads and downloads.
|
||||
resume on HTTP(S) downloads as well as FTP uploads and downloads.
|
||||
|
||||
Continue downloading a document:
|
||||
|
||||
@@ -731,7 +741,7 @@ RESUMING FILE TRANSFERS
|
||||
|
||||
curl -C - -o file http://www.server.com/
|
||||
|
||||
(*1) = This requires that the ftp server supports the non-standard command
|
||||
(*1) = This requires that the FTP server supports the non-standard command
|
||||
SIZE. If it doesn't, curl will say so.
|
||||
|
||||
(*2) = This requires that the web server supports at least HTTP/1.1. If it
|
||||
@@ -740,7 +750,7 @@ RESUMING FILE TRANSFERS
|
||||
TIME CONDITIONS
|
||||
|
||||
HTTP allows a client to specify a time condition for the document it
|
||||
requests. It is If-Modified-Since or If-Unmodified-Since. Curl allow you to
|
||||
requests. It is If-Modified-Since or If-Unmodified-Since. Curl allows you to
|
||||
specify them with the -z/--time-cond flag.
|
||||
|
||||
For example, you can easily make a download that only gets performed if the
|
||||
@@ -788,7 +798,7 @@ LDAP
|
||||
and offer ldap:// support.
|
||||
|
||||
LDAP is a complex thing and writing an LDAP query is not an easy task. I do
|
||||
advice you to dig up the syntax description for that elsewhere. Two places
|
||||
advise you to dig up the syntax description for that elsewhere. Two places
|
||||
that might suit you are:
|
||||
|
||||
Netscape's "Netscape Directory SDK 3.0 for C Programmer's Guide Chapter 10:
|
||||
@@ -797,7 +807,7 @@ LDAP
|
||||
|
||||
RFC 2255, "The LDAP URL Format" http://curl.haxx.se/rfc/rfc2255.txt
|
||||
|
||||
To show you an example, this is now I can get all people from my local LDAP
|
||||
To show you an example, this is how I can get all people from my local LDAP
|
||||
server that has a certain sub-domain in their email address:
|
||||
|
||||
curl -B "ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se"
|
||||
@@ -831,15 +841,15 @@ ENVIRONMENT VARIABLES
|
||||
NETRC
|
||||
|
||||
Unix introduced the .netrc concept a long time ago. It is a way for a user
|
||||
to specify name and password for commonly visited ftp sites in a file so
|
||||
to specify name and password for commonly visited FTP sites in a file so
|
||||
that you don't have to type them in each time you visit those sites. You
|
||||
realize this is a big security risk if someone else gets hold of your
|
||||
passwords, so therefore most unix programs won't read this file unless it is
|
||||
only readable by yourself (curl doesn't care though).
|
||||
|
||||
Curl supports .netrc files if told so (using the -n/--netrc and
|
||||
--netrc-optional options). This is not restricted to only ftp,
|
||||
but curl can use it for all protocols where authentication is used.
|
||||
Curl supports .netrc files if told to (using the -n/--netrc and
|
||||
--netrc-optional options). This is not restricted to just FTP,
|
||||
so curl can use it for all protocols where authentication is used.
|
||||
|
||||
A very simple .netrc file could look something like:
|
||||
|
||||
@@ -860,7 +870,7 @@ KERBEROS FTP TRANSFER
|
||||
|
||||
Curl supports kerberos4 and kerberos5/GSSAPI for FTP transfers. You need
|
||||
the kerberos package installed and used at curl build time for it to be
|
||||
used.
|
||||
available.
|
||||
|
||||
First, get the krb-ticket the normal way, like with the kinit/kauth tool.
|
||||
Then use curl in way similar to:
|
||||
@@ -895,7 +905,7 @@ TELNET
|
||||
|
||||
- NEW_ENV=<var,val> Sets an environment variable.
|
||||
|
||||
NOTE: the telnet protocol does not specify any way to login with a specified
|
||||
NOTE: The telnet protocol does not specify any way to login with a specified
|
||||
user and password so curl can't do that automatically. To do that, you need
|
||||
to track when the login prompt is received and send the username and
|
||||
password accordingly.
|
||||
@@ -914,7 +924,7 @@ PERSISTENT CONNECTIONS
|
||||
Note that curl cannot use persistent connections for transfers that are used
|
||||
in subsequence curl invokes. Try to stuff as many URLs as possible on the
|
||||
same command line if they are using the same host, as that'll make the
|
||||
transfers faster. If you use a http proxy for file transfers, practically
|
||||
transfers faster. If you use an HTTP proxy for file transfers, practically
|
||||
all transfers will be persistent.
|
||||
|
||||
MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE
|
||||
@@ -955,6 +965,28 @@ IPv6
|
||||
IPv6 addresses provided other than in URLs (e.g. to the --proxy, --interface
|
||||
or --ftp-port options) should not be URL encoded.
|
||||
|
||||
METALINK
|
||||
|
||||
Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way
|
||||
to list multiple URIs and hashes for a file. Curl will make use of the mirrors
|
||||
listed within for failover if there are errors (such as the file or server not
|
||||
being available). It will also verify the hash of the file after the download
|
||||
completes. The Metalink file itself is downloaded and processed in memory and
|
||||
not stored in the local file system.
|
||||
|
||||
Example to use a remote Metalink file:
|
||||
|
||||
curl --metalink http://www.example.com/example.metalink
|
||||
|
||||
To use a Metalink file in the local file system, use FILE protocol (file://):
|
||||
|
||||
curl --metalink file://example.metalink
|
||||
|
||||
Please note that if FILE protocol is disabled, there is no way to use a local
|
||||
Metalink file at the time of this writing. Also note that if --metalink and
|
||||
--include are used together, --include will be ignored. This is because including
|
||||
headers in the response will break Metalink parser and if the headers are included
|
||||
in the file described in Metalink file, hash check will fail.
|
||||
|
||||
MAILING LISTS
|
||||
|
||||
|
||||
26
docs/THANKS
26
docs/THANKS
@@ -71,9 +71,11 @@ Andy Serpa
|
||||
Andy Tsouladze
|
||||
Angus Mackay
|
||||
Anthony Bryan
|
||||
Anthony G. Basile
|
||||
Antoine Calando
|
||||
Anton Bychkov
|
||||
Anton Kalmykov
|
||||
Anton Yabchinskiy
|
||||
Arkadiusz Miskiewicz
|
||||
Armel Asselin
|
||||
Arnaud Compan
|
||||
@@ -146,6 +148,7 @@ Chris Mumford
|
||||
Chris Smowton
|
||||
Christian Grothoff
|
||||
Christian Hagele
|
||||
Christian Hägele
|
||||
Christian Krause
|
||||
Christian Kurz
|
||||
Christian Robottom Reis
|
||||
@@ -204,6 +207,7 @@ Dave Reisner
|
||||
Dave Vasilevsky
|
||||
David Bau
|
||||
David Binderman
|
||||
David Blaikie
|
||||
David Byron
|
||||
David Cohen
|
||||
David Eriksson
|
||||
@@ -260,6 +264,8 @@ Early Ehlinger
|
||||
Ebenezer Ikonne
|
||||
Edin Kadribasic
|
||||
Eduard Bloch
|
||||
Edward Sheldrake
|
||||
Eelco Dolstra
|
||||
Eetu Ojanen
|
||||
Ellis Pritchard
|
||||
Emanuele Bovisio
|
||||
@@ -298,6 +304,7 @@ Frank McGeough
|
||||
Frank Meier
|
||||
Frank Ticheler
|
||||
Frank Van Uffelen
|
||||
František Kučera
|
||||
Fred Machado
|
||||
Fred New
|
||||
Fred Noz
|
||||
@@ -316,6 +323,7 @@ Georg Wicherski
|
||||
Gerd v. Egidy
|
||||
Gerhard Herre
|
||||
Gerrit Bruchhäuser
|
||||
Ghennadi Procopciuc
|
||||
Giancarlo Formicuccia
|
||||
Giaslas Georgios
|
||||
Gil Weber
|
||||
@@ -355,6 +363,7 @@ Henrik Storner
|
||||
Henry Ludemann
|
||||
Herve Amblard
|
||||
Hidemoto Nakada
|
||||
Ho-chi Chen
|
||||
Hoi-Ho Chan
|
||||
Hongli Lai
|
||||
Howard Chu
|
||||
@@ -392,6 +401,7 @@ Jamie Lokier
|
||||
Jamie Newton
|
||||
Jamie Wilkinson
|
||||
Jan Ehrhardt
|
||||
Jan Koen Annot
|
||||
Jan Kunder
|
||||
Jan Schaumann
|
||||
Jan Van Boghout
|
||||
@@ -423,6 +433,7 @@ Jerry Wu
|
||||
Jes Badwal
|
||||
Jesper Jensen
|
||||
Jesse Noller
|
||||
Jie He
|
||||
Jim Drash
|
||||
Jim Freeman
|
||||
Jim Hollinger
|
||||
@@ -430,6 +441,7 @@ Jim Meyering
|
||||
Jocelyn Jaubert
|
||||
Joe Halpin
|
||||
Joe Malicki
|
||||
Joe Mason
|
||||
Joel Chen
|
||||
Jofell Gallardo
|
||||
Johan Anderson
|
||||
@@ -445,6 +457,7 @@ John Joseph Bachir
|
||||
John Kelly
|
||||
John Lask
|
||||
John Lightsey
|
||||
John Marino
|
||||
John McGowan
|
||||
John P. McCaskey
|
||||
John Wilkinson
|
||||
@@ -555,6 +568,7 @@ Manuel Massing
|
||||
Marc Boucher
|
||||
Marc Hoersken
|
||||
Marc Kleine-Budde
|
||||
Marcel Raad
|
||||
Marcel Roelofs
|
||||
Marcelo Juchem
|
||||
Marcin Adamski
|
||||
@@ -571,6 +585,8 @@ Mark Eichin
|
||||
Mark Incley
|
||||
Mark Karpeles
|
||||
Mark Lentczner
|
||||
Mark Salisbury
|
||||
Mark Tully
|
||||
Markus Duft
|
||||
Markus Koetter
|
||||
Markus Moeller
|
||||
@@ -604,6 +620,7 @@ Max Katsev
|
||||
Maxim Ivanov
|
||||
Maxim Perenesenko
|
||||
Maxim Prohorov
|
||||
Maxime Larocque
|
||||
Mehmet Bozkurt
|
||||
Mekonikum
|
||||
Mettgut Jamalla
|
||||
@@ -644,6 +661,7 @@ Nathan O'Sullivan
|
||||
Nathanael Nerode
|
||||
Naveen Chandran
|
||||
Naveen Noel
|
||||
Neil Bowers
|
||||
Neil Dunbar
|
||||
Neil Spring
|
||||
Nic Roets
|
||||
@@ -671,6 +689,7 @@ Ofer
|
||||
Olaf Flebbe
|
||||
Olaf Stueben
|
||||
Olaf Stüben
|
||||
Olivier Berger
|
||||
Oren Tirosh
|
||||
Ori Avtalion
|
||||
P R Schaffner
|
||||
@@ -718,6 +737,7 @@ Phil Blundell
|
||||
Phil Karn
|
||||
Phil Lisiecki
|
||||
Phil Pellouchoud
|
||||
Philip Craig
|
||||
Philip Gladstone
|
||||
Philip Langdale
|
||||
Philippe Hameau
|
||||
@@ -773,6 +793,7 @@ Rob Jones
|
||||
Rob Stanzel
|
||||
Rob Ward
|
||||
Robert A. Monat
|
||||
Robert B. Harris
|
||||
Robert D. Young
|
||||
Robert Foreman
|
||||
Robert Iakobashvili
|
||||
@@ -810,14 +831,18 @@ Samuel Listopad
|
||||
Samuel Thibault
|
||||
Sander Gates
|
||||
Sandor Feldi
|
||||
Santhana Todatry
|
||||
Saqib Ali
|
||||
Sara Golemon
|
||||
Saul good
|
||||
Scott Bailey
|
||||
Scott Barrett
|
||||
Scott Cantor
|
||||
Scott Davis
|
||||
Scott McCreary
|
||||
Sebastien Willemijns
|
||||
Senthil Raja Velu
|
||||
Sergei Nikulov
|
||||
Sergio Ballestrero
|
||||
Seshubabu Pasam
|
||||
Sh Diao
|
||||
@@ -901,6 +926,7 @@ Tom Mueller
|
||||
Tom Regner
|
||||
Tom Wright
|
||||
Tom Zerucha
|
||||
Tomas Mlcoch
|
||||
Tomas Pospisek
|
||||
Tomas Szepe
|
||||
Tomasz Lacki
|
||||
|
||||
201
docs/TODO
201
docs/TODO
@@ -55,22 +55,19 @@
|
||||
7.6 Provide callback for cert verification
|
||||
7.7 Support other SSL libraries
|
||||
7.9 improve configure --with-ssl
|
||||
7.10 Support DANE
|
||||
|
||||
8. GnuTLS
|
||||
8.1 SSL engine stuff
|
||||
8.3 check connection
|
||||
8.4 non-gcrypt
|
||||
|
||||
9. SMTP
|
||||
9.1 Other authentication mechanisms
|
||||
9.2 Specify the preferred authentication mechanism
|
||||
9.3 Initial response
|
||||
9.4 Pipelining
|
||||
9.1 Specify the preferred authentication mechanism
|
||||
9.2 Initial response
|
||||
9.3 Pipelining
|
||||
|
||||
10. POP3
|
||||
10.1 APOP Authentication
|
||||
10.2 SASL based authentication mechanisms
|
||||
10.3 auth= in URLs
|
||||
10.1 auth= in URLs
|
||||
|
||||
11. IMAP
|
||||
11.1 SASL based authentication mechanisms
|
||||
@@ -83,42 +80,44 @@
|
||||
14. New protocols
|
||||
14.1 RSYNC
|
||||
|
||||
15. Client
|
||||
15.1 sync
|
||||
15.2 glob posts
|
||||
15.3 prevent file overwriting
|
||||
15.4 simultaneous parallel transfers
|
||||
15.5 provide formpost headers
|
||||
15.6 url-specific options
|
||||
15.7 metalink support
|
||||
15.8 warning when setting an option
|
||||
15.9 IPv6 addresses with globbing
|
||||
15. SASL
|
||||
15.1 Other authentication mechanisms
|
||||
|
||||
16. Client
|
||||
16.1 sync
|
||||
16.2 glob posts
|
||||
16.3 prevent file overwriting
|
||||
16.4 simultaneous parallel transfers
|
||||
16.5 provide formpost headers
|
||||
16.6 url-specific options
|
||||
16.7 warning when setting an option
|
||||
16.8 IPv6 addresses with globbing
|
||||
|
||||
16. Build
|
||||
16.1 roffit
|
||||
17. Build
|
||||
17.1 roffit
|
||||
|
||||
17. Test suite
|
||||
17.1 SSL tunnel
|
||||
17.2 nicer lacking perl message
|
||||
17.3 more protocols supported
|
||||
17.4 more platforms supported
|
||||
18. Test suite
|
||||
18.1 SSL tunnel
|
||||
18.2 nicer lacking perl message
|
||||
18.3 more protocols supported
|
||||
18.4 more platforms supported
|
||||
|
||||
18. Next SONAME bump
|
||||
18.1 http-style HEAD output for ftp
|
||||
18.2 combine error codes
|
||||
18.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
19. Next SONAME bump
|
||||
19.1 http-style HEAD output for ftp
|
||||
19.2 combine error codes
|
||||
19.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
19. Next major release
|
||||
19.1 cleanup return codes
|
||||
19.2 remove obsolete defines
|
||||
19.3 size_t
|
||||
19.4 remove several functions
|
||||
19.5 remove CURLOPT_FAILONERROR
|
||||
19.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
19.7 remove progress meter from libcurl
|
||||
19.8 remove 'curl_httppost' from public
|
||||
19.9 have form functions use CURL handle argument
|
||||
19.10 Add CURLOPT_MAIL_CLIENT option
|
||||
20. Next major release
|
||||
20.1 cleanup return codes
|
||||
20.2 remove obsolete defines
|
||||
20.3 size_t
|
||||
20.4 remove several functions
|
||||
20.5 remove CURLOPT_FAILONERROR
|
||||
20.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
20.7 remove progress meter from libcurl
|
||||
20.8 remove 'curl_httppost' from public
|
||||
20.9 have form functions use CURL handle argument
|
||||
20.10 Add CURLOPT_MAIL_CLIENT option
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -356,6 +355,13 @@ to provide the data to send.
|
||||
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||
then NSS...
|
||||
|
||||
7.10 Support DANE
|
||||
|
||||
DNS-Based Authentication of Named Entities (DANE) is a way to provide SSL
|
||||
keys and certs over DNS using DNSSEC as an alternative to the CA model.
|
||||
http://www.rfc-editor.org/rfc/rfc6698.txt
|
||||
|
||||
|
||||
8. GnuTLS
|
||||
|
||||
8.1 SSL engine stuff
|
||||
@@ -367,30 +373,16 @@ to provide the data to send.
|
||||
Add a way to check if the connection seems to be alive, to correspond to the
|
||||
SSL_peak() way we use with OpenSSL.
|
||||
|
||||
8.4 non-gcrypt
|
||||
|
||||
libcurl assumes that there are gcrypt functions available when
|
||||
GnuTLS is.
|
||||
|
||||
GnuTLS can be built to use libnettle instead as crypto library,
|
||||
which breaks the previously mentioned assumption
|
||||
|
||||
The correct fix would be to detect which crypto layer that is in use and
|
||||
adapt our code to use that instead of blindly assuming gcrypt.
|
||||
|
||||
9. SMTP
|
||||
|
||||
9.1 Other authentication mechanisms
|
||||
|
||||
Add support for gssapi.
|
||||
|
||||
9.2 Specify the preferred authentication mechanism
|
||||
9.1 Specify the preferred authentication mechanism
|
||||
|
||||
Add the ability to specify the preferred authentication mechanism or a list
|
||||
of mechanisms that should be used. Not only that, but the order that is
|
||||
returned by the server during the EHLO response should be honored by curl.
|
||||
|
||||
9.3 Initial response
|
||||
9.2 Initial response
|
||||
|
||||
Add the ability for the user to specify whether the initial response is
|
||||
included in the AUTH command. Some email servers, such as Microsoft
|
||||
@@ -399,27 +391,13 @@ to provide the data to send.
|
||||
|
||||
http://curl.haxx.se/mail/lib-2012-03/0114.html
|
||||
|
||||
9.4 Pipelining
|
||||
9.3 Pipelining
|
||||
|
||||
Add support for pipelining emails.
|
||||
|
||||
10. POP3
|
||||
|
||||
10.1 APOP Authentication
|
||||
|
||||
Add support for the APOP command rather than using plain text authentication
|
||||
(USER and PASS) as this is very week security wise. Note: The APOP command
|
||||
is specified as "APOP <username> <md5 password>", however, it isn't
|
||||
supported by all mail servers.
|
||||
|
||||
10.2 SASL authentication mechanisms
|
||||
|
||||
SASL offers support for additional authentication mechanisms via the AUTH
|
||||
command. Detection of an email server's support for SASL authentication
|
||||
can be detected via the CAPA command whilst a list of supported mechanisms
|
||||
can be retrieved with an empty AUTH command.
|
||||
|
||||
10.3 auth= in URLs
|
||||
10.1 auth= in URLs
|
||||
|
||||
Being able to specify the preferred authentication mechanism in the URL as
|
||||
per RFC2384.
|
||||
@@ -428,9 +406,9 @@ to provide the data to send.
|
||||
|
||||
11.1 SASL based authentication mechanisms
|
||||
|
||||
Like POP3 curl currently sends usernames and passwords as clear text.
|
||||
Support should also be added to support SASL based authentication mechanisms
|
||||
as these are more secure.
|
||||
Curl currently sends usernames and passwords as clear text whilst SASL based
|
||||
authentication mechanisms can be more secure. As such, support should be
|
||||
added to support these authentication mechanisms.
|
||||
|
||||
12. LDAP
|
||||
|
||||
@@ -451,9 +429,15 @@ to provide the data to send.
|
||||
There's no RFC for the protocol or an URI/URL format. An implementation
|
||||
should most probably use an existing rsync library, such as librsync.
|
||||
|
||||
15. Client
|
||||
15. SASL
|
||||
|
||||
15.1 sync
|
||||
15.1 Other authentication mechanisms
|
||||
|
||||
Add support for gssapi to SMTP and POP3.
|
||||
|
||||
16. Client
|
||||
|
||||
16.1 sync
|
||||
|
||||
"curl --sync http://example.com/feed[1-100].rss" or
|
||||
"curl --sync http://example.net/{index,calendar,history}.html"
|
||||
@@ -462,12 +446,12 @@ to provide the data to send.
|
||||
remote file is newer than the local file. A Last-Modified HTTP date header
|
||||
should also be used to set the mod date on the downloaded file.
|
||||
|
||||
15.2 glob posts
|
||||
16.2 glob posts
|
||||
|
||||
Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'.
|
||||
This is easily scripted though.
|
||||
|
||||
15.3 prevent file overwriting
|
||||
16.3 prevent file overwriting
|
||||
|
||||
Add an option that prevents cURL from overwriting existing local files. When
|
||||
used, and there already is an existing file with the target file name
|
||||
@@ -475,14 +459,14 @@ to provide the data to send.
|
||||
existing). So that index.html becomes first index.html.1 and then
|
||||
index.html.2 etc.
|
||||
|
||||
15.4 simultaneous parallel transfers
|
||||
16.4 simultaneous parallel transfers
|
||||
|
||||
The client could be told to use maximum N simultaneous parallel transfers and
|
||||
then just make sure that happens. It should of course not make more than one
|
||||
connection to the same remote host. This would require the client to use the
|
||||
multi interface. http://curl.haxx.se/bug/feature.cgi?id=1558595
|
||||
|
||||
15.5 provide formpost headers
|
||||
16.5 provide formpost headers
|
||||
|
||||
Extending the capabilities of the multipart formposting. How about leaving
|
||||
the ';type=foo' syntax as it is and adding an extra tag (headers) which
|
||||
@@ -496,7 +480,7 @@ to provide the data to send.
|
||||
which should overwrite the program reasonable defaults (plain/text,
|
||||
8bit...)
|
||||
|
||||
15.6 url-specific options
|
||||
16.6 url-specific options
|
||||
|
||||
Provide a way to make options bound to a specific URL among several on the
|
||||
command line. Possibly by letting ':' separate options between URLs,
|
||||
@@ -510,62 +494,57 @@ to provide the data to send.
|
||||
|
||||
The example would do a POST-GET-POST combination on a single command line.
|
||||
|
||||
15.7 metalink support
|
||||
|
||||
Add metalink support to curl (http://www.metalinker.org/). This is most useful
|
||||
with simultaneous parallel transfers (11.6) but not necessary.
|
||||
|
||||
15.8 warning when setting an option
|
||||
16.7 warning when setting an option
|
||||
|
||||
Display a warning when libcurl returns an error when setting an option.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
|
||||
15.9 IPv6 addresses with globbing
|
||||
16.8 IPv6 addresses with globbing
|
||||
|
||||
Currently the command line client needs to get url globbing disabled (with
|
||||
-g) for it to support IPv6 numerical addresses. This is a rather silly flaw
|
||||
that should be corrected. It probably involves a smarter detection of the
|
||||
'[' and ']' letters.
|
||||
|
||||
16. Build
|
||||
17. Build
|
||||
|
||||
16.1 roffit
|
||||
17.1 roffit
|
||||
|
||||
Consider extending 'roffit' to produce decent ASCII output, and use that
|
||||
instead of (g)nroff when building src/hugehelp.c
|
||||
|
||||
17. Test suite
|
||||
18. Test suite
|
||||
|
||||
17.1 SSL tunnel
|
||||
18.1 SSL tunnel
|
||||
|
||||
Make our own version of stunnel for simple port forwarding to enable HTTPS
|
||||
and FTP-SSL tests without the stunnel dependency, and it could allow us to
|
||||
provide test tools built with either OpenSSL or GnuTLS
|
||||
|
||||
17.2 nicer lacking perl message
|
||||
18.2 nicer lacking perl message
|
||||
|
||||
If perl wasn't found by the configure script, don't attempt to run the tests
|
||||
but explain something nice why it doesn't.
|
||||
|
||||
17.3 more protocols supported
|
||||
18.3 more protocols supported
|
||||
|
||||
Extend the test suite to include more protocols. The telnet could just do ftp
|
||||
or http operations (for which we have test servers).
|
||||
|
||||
17.4 more platforms supported
|
||||
18.4 more platforms supported
|
||||
|
||||
Make the test suite work on more platforms. OpenBSD and Mac OS. Remove
|
||||
fork()s and it should become even more portable.
|
||||
|
||||
18. Next SONAME bump
|
||||
19. Next SONAME bump
|
||||
|
||||
18.1 http-style HEAD output for ftp
|
||||
19.1 http-style HEAD output for ftp
|
||||
|
||||
#undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers
|
||||
from being output in NOBODY requests over ftp
|
||||
|
||||
18.2 combine error codes
|
||||
19.2 combine error codes
|
||||
|
||||
Combine some of the error codes to remove duplicates. The original
|
||||
numbering should not be changed, and the old identifiers would be
|
||||
@@ -590,29 +569,29 @@ to provide the data to send.
|
||||
|
||||
CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED
|
||||
|
||||
18.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
19.3 extend CURLOPT_SOCKOPTFUNCTION prototype
|
||||
|
||||
The current prototype only provides 'purpose' that tells what the
|
||||
connection/socket is for, but not any protocol or similar. It makes it hard
|
||||
for applications to differentiate on TCP vs UDP and even HTTP vs FTP and
|
||||
similar.
|
||||
|
||||
19. Next major release
|
||||
20. Next major release
|
||||
|
||||
19.1 cleanup return codes
|
||||
20.1 cleanup return codes
|
||||
|
||||
curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a
|
||||
CURLMcode. These should be changed to be the same.
|
||||
|
||||
19.2 remove obsolete defines
|
||||
20.2 remove obsolete defines
|
||||
|
||||
remove obsolete defines from curl/curl.h
|
||||
|
||||
19.3 size_t
|
||||
20.3 size_t
|
||||
|
||||
make several functions use size_t instead of int in their APIs
|
||||
|
||||
19.4 remove several functions
|
||||
20.4 remove several functions
|
||||
|
||||
remove the following functions from the public API:
|
||||
|
||||
@@ -633,18 +612,18 @@ to provide the data to send.
|
||||
|
||||
curl_multi_socket_all
|
||||
|
||||
19.5 remove CURLOPT_FAILONERROR
|
||||
20.5 remove CURLOPT_FAILONERROR
|
||||
|
||||
Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird
|
||||
internally. Let the app judge success or not for itself.
|
||||
|
||||
19.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
20.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
|
||||
Remove support for a global DNS cache. Anything global is silly, and we
|
||||
already offer the share interface for the same functionality but done
|
||||
"right".
|
||||
|
||||
19.7 remove progress meter from libcurl
|
||||
20.7 remove progress meter from libcurl
|
||||
|
||||
The internally provided progress meter output doesn't belong in the library.
|
||||
Basically no application wants it (apart from curl) but instead applications
|
||||
@@ -654,7 +633,7 @@ to provide the data to send.
|
||||
variable types passed to it instead of doubles so that big files work
|
||||
correctly.
|
||||
|
||||
19.8 remove 'curl_httppost' from public
|
||||
20.8 remove 'curl_httppost' from public
|
||||
|
||||
curl_formadd() was made to fill in a public struct, but the fact that the
|
||||
struct is public is never really used by application for their own advantage
|
||||
@@ -663,7 +642,7 @@ to provide the data to send.
|
||||
Changing them to return a private handle will benefit the implementation and
|
||||
allow us much greater freedoms while still maintining a solid API and ABI.
|
||||
|
||||
19.9 have form functions use CURL handle argument
|
||||
20.9 have form functions use CURL handle argument
|
||||
|
||||
curl_formadd() and curl_formget() both currently have no CURL handle
|
||||
argument, but both can use a callback that is set in the easy handle, and
|
||||
@@ -671,7 +650,7 @@ to provide the data to send.
|
||||
curl_easy_perform() (or similar) called - which is hard to grasp and a design
|
||||
mistake.
|
||||
|
||||
19.10 Add CURLOPT_MAIL_CLIENT option
|
||||
20.10 Add CURLOPT_MAIL_CLIENT option
|
||||
|
||||
Rather than use the URL to specify the mail client string to present in the
|
||||
HELO and EHLO commands, libcurl should support a new CURLOPT specifically for
|
||||
|
||||
356
docs/curl.1
356
docs/curl.1
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "16 February 2012" "Curl 7.25.0" "Curl Manual"
|
||||
.TH curl 1 "27 July 2012" "Curl 7.27.0" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -79,14 +79,14 @@ curl will do its best to use what you pass to it as a URL. It is not trying to
|
||||
validate it as a syntactically correct URL by any means but is instead
|
||||
\fBvery\fP liberal with what it accepts.
|
||||
|
||||
Curl will attempt to re-use connections for multiple file transfers, so that
|
||||
curl will attempt to re-use connections for multiple file transfers, so that
|
||||
getting many files from the same server will not do multiple connects /
|
||||
handshakes. This improves speed. Of course this is only done on files
|
||||
specified on a single command line and cannot be used between separate curl
|
||||
invokes.
|
||||
.SH "PROGRESS METER"
|
||||
curl normally displays a progress meter during operations, indicating the amount
|
||||
of transferred data, transfer speeds and estimated time left, etc.
|
||||
curl normally displays a progress meter during operations, indicating the
|
||||
amount of transferred data, transfer speeds and estimated time left, etc.
|
||||
|
||||
curl displays this data to the terminal by default, so if you invoke curl to
|
||||
do an operation and it is about to write data to the terminal, it
|
||||
@@ -103,7 +103,7 @@ any response data to the terminal.
|
||||
If you prefer a progress "bar" instead of the regular meter, \fI-#\fP is your
|
||||
friend.
|
||||
.SH OPTIONS
|
||||
In general, all boolean options are enabled with --option and yet again
|
||||
In general, all boolean options are enabled with --\fBoption\fP and yet again
|
||||
disabled with --\fBno-\fPoption. That is, you use the exact same option name
|
||||
but prefix it with "no-". However, in this list we mostly only list and show
|
||||
the --option version of them. (This concept with --no options was added in
|
||||
@@ -125,14 +125,13 @@ Forces curl to use SSL version 2 when negotiating with a remote SSL server.
|
||||
(SSL)
|
||||
Forces curl to use SSL version 3 when negotiating with a remote SSL server.
|
||||
.IP "-4, --ipv4"
|
||||
If libcurl is capable of resolving an address to multiple IP versions (which
|
||||
it is if it is IPv6-capable), this option tells libcurl to resolve names to
|
||||
IPv4 addresses only.
|
||||
If curl is capable of resolving an address to multiple IP versions (which it
|
||||
is if it is IPv6-capable), this option tells curl to resolve names to IPv4
|
||||
addresses only.
|
||||
.IP "-6, --ipv6"
|
||||
If libcurl is capable of resolving an address to multiple IP versions (which
|
||||
it is if it is IPv6-capable), this option tells libcurl to resolve names to
|
||||
IPv6 addresses only.
|
||||
default statistics.
|
||||
If curl is capable of resolving an address to multiple IP versions (which it
|
||||
is if it is IPv6-capable), this option tells curl to resolve names to IPv6
|
||||
addresses only.
|
||||
.IP "-a, --append"
|
||||
(FTP/SFTP) When used in an upload, this will tell curl to append to the target
|
||||
file instead of overwriting it. If the file doesn't exist, it will be created.
|
||||
@@ -143,8 +142,7 @@ done CGIs fail if this field isn't set to "Mozilla/4.0". To encode blanks in
|
||||
the string, surround the string with single quote marks. This can also be set
|
||||
with the \fI-H, --header\fP option of course.
|
||||
|
||||
If this option is set more than once, the last one will be the one that's
|
||||
used.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--anyauth"
|
||||
(HTTP) Tells curl to figure out authentication method by itself, and use the
|
||||
most secure one the remote site claims to support. This is done by first
|
||||
@@ -176,10 +174,9 @@ input. No cookies will be stored in the file. To store cookies, use the
|
||||
\fI-c, --cookie-jar\fP option or you could even save the HTTP headers to a file
|
||||
using \fI-D, --dump-header\fP!
|
||||
|
||||
If this option is set more than once, the last one will be the one that's
|
||||
used.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-B, --use-ascii"
|
||||
Enable ASCII transfer when using FTP or LDAP. For FTP, this can also be
|
||||
(FTP/LDAP) Enable ASCII transfer. For FTP, this can also be
|
||||
enforced by using an URL that ends with ";type=A". This option causes data
|
||||
sent to stdout to be in text mode for win32 systems.
|
||||
.IP "--basic"
|
||||
@@ -188,12 +185,12 @@ this option is usually pointless, unless you use it to override a previously
|
||||
set option that sets a different authentication method (such as \fI--ntlm\fP,
|
||||
\fI--digest\fP, or \fI--negotiate\fP).
|
||||
.IP "-c, --cookie-jar <file name>"
|
||||
Specify to which file you want curl to write all cookies after a completed
|
||||
operation. Curl writes all cookies previously read from a specified file as
|
||||
well as all cookies received from remote server(s). If no cookies are known,
|
||||
no file will be written. The file will be written using the Netscape cookie
|
||||
file format. If you set the file name to a single dash, "-", the cookies will
|
||||
be written to stdout.
|
||||
(HTTP) Specify to which file you want curl to write all cookies after a
|
||||
completed operation. Curl writes all cookies previously read from a specified
|
||||
file as well as all cookies received from remote server(s). If no cookies are
|
||||
known, no file will be written. The file will be written using the Netscape
|
||||
cookie file format. If you set the file name to a single dash, "-", the
|
||||
cookies will be written to stdout.
|
||||
|
||||
This command line option will activate the cookie engine that makes curl
|
||||
record and use cookies. Another way to activate it is to use the \fI-b,
|
||||
@@ -221,13 +218,13 @@ If this option is used several times, the last one will be used.
|
||||
must specify valid ciphers. Read up on SSL cipher list details on this URL:
|
||||
\fIhttp://www.openssl.org/docs/apps/ciphers.html\fP
|
||||
|
||||
NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of
|
||||
NSS ciphers is in the NSSCipherSuite entry at this URL:
|
||||
\fIhttp://directory.fedora.redhat.com/docs/mod_nss.html#Directives\fP
|
||||
NSS ciphers are done differently than OpenSSL and GnuTLS. The full list of NSS
|
||||
ciphers is in the NSSCipherSuite entry at this URL:
|
||||
\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP
|
||||
|
||||
If this option is used several times, the last one will override the others.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--compressed"
|
||||
(HTTP) Request a compressed response using one of the algorithms libcurl
|
||||
(HTTP) Request a compressed response using one of the algorithms curl
|
||||
supports, and save the uncompressed document. If this option is used and the
|
||||
server sends an unsupported encoding, curl will report an error.
|
||||
.IP "--connect-timeout <seconds>"
|
||||
@@ -237,10 +234,10 @@ of no more use. See also the \fI-m, --max-time\fP option.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--create-dirs"
|
||||
When used in conjunction with the -o option, curl will create the necessary
|
||||
local directory hierarchy as needed. This option creates the dirs mentioned
|
||||
with the -o option, nothing else. If the -o file name uses no dir or if the
|
||||
dirs it mentions already exist, no dir will be created.
|
||||
When used in conjunction with the \fI-o\fP option, curl will create the
|
||||
necessary local directory hierarchy as needed. This option creates the dirs
|
||||
mentioned with the \fI-o\fP option, nothing else. If the \fI-o\fP file name
|
||||
uses no dir or if the dirs it mentions already exist, no dir will be created.
|
||||
|
||||
To create remote directories when using FTP or SFTP, try
|
||||
\fI--ftp-create-dirs\fP.
|
||||
@@ -277,7 +274,7 @@ specified. Posting data from a file named 'foobar' would thus be done with
|
||||
.IP "-D, --dump-header <file>"
|
||||
Write the protocol headers to the specified file.
|
||||
|
||||
This option is handy to use when you want to store the headers that a HTTP
|
||||
This option is handy to use when you want to store the headers that an HTTP
|
||||
site sends to you. Cookies from the headers could then be read in a second
|
||||
curl invocation by using the \fI-b, --cookie\fP option! The
|
||||
\fI-c, --cookie-jar\fP option is however a better way to store cookies.
|
||||
@@ -285,8 +282,10 @@ curl invocation by using the \fI-b, --cookie\fP option! The
|
||||
When used in FTP, the FTP server response lines are considered being "headers"
|
||||
and thus are saved there.
|
||||
|
||||
If this option is used several times, the last one will be used. IP
|
||||
"--data-ascii <data>" See \fI-d, --data\fP.
|
||||
If this option is used several times, the last one will be used.
|
||||
|
||||
.IP "--data-ascii <data>"
|
||||
See \fI-d, --data\fP.
|
||||
.IP "--data-binary <data>"
|
||||
(HTTP) This posts data exactly as specified with no extra processing
|
||||
whatsoever.
|
||||
@@ -337,21 +336,20 @@ service ticket, which is a matter of realm policy.
|
||||
Unconditionally allow the server to delegate.
|
||||
.RE
|
||||
.IP "--digest"
|
||||
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
||||
prevents the password from being sent over the wire in clear text. Use this in
|
||||
combination with the normal \fI-u, --user\fP option to set user name and
|
||||
password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for
|
||||
(HTTP) Enables HTTP Digest authentication. This is an authentication scheme
|
||||
that prevents the password from being sent over the wire in clear text. Use
|
||||
this in combination with the normal \fI-u, --user\fP option to set user name
|
||||
and password. See also \fI--ntlm\fP, \fI--negotiate\fP and \fI--anyauth\fP for
|
||||
related options.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
If this option is used several times, only the first one is used.
|
||||
.IP "--disable-eprt"
|
||||
(FTP) Tell curl to disable the use of the EPRT and LPRT commands when doing
|
||||
active FTP transfers. Curl will normally always first attempt to use EPRT,
|
||||
then LPRT before using PORT, but with this option, it will use PORT right
|
||||
away. EPRT and LPRT are extensions to the original FTP protocol, and may not work
|
||||
on all servers, but they enable more functionality in a better way than the
|
||||
traditional PORT command.
|
||||
away. EPRT and LPRT are extensions to the original FTP protocol, and may not
|
||||
work on all servers, but they enable more functionality in a better way than
|
||||
the traditional PORT command.
|
||||
|
||||
\fB--eprt\fP can be used to explicitly enable EPRT again and \fB--no-eprt\fP
|
||||
is an alias for \fB--disable-eprt\fP.
|
||||
@@ -399,9 +397,9 @@ operations. Use \fI--engine list\fP to print a list of build-time supported
|
||||
engines. Note that not all (or none) of the engines may be available at
|
||||
run-time.
|
||||
.IP "--environment"
|
||||
(RISC OS ONLY) Sets a range of environment variables, using the names the -w
|
||||
option supports, to allow easier extraction of useful information after having
|
||||
run curl.
|
||||
(RISC OS ONLY) Sets a range of environment variables, using the names the
|
||||
\fI-w\fP option supports, to allow easier extraction of useful information
|
||||
after having run curl.
|
||||
.IP "--egd-file <file>"
|
||||
(SSL) Specify the path name to the Entropy Gathering Daemon socket. The socket
|
||||
is used to seed the random engine for SSL connections. See also the
|
||||
@@ -446,7 +444,7 @@ 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
|
||||
normal cases when a HTTP server fails to deliver a document, it returns an
|
||||
normal cases when an HTTP server fails to deliver a document, it returns an
|
||||
HTML document stating so (which often also describes why and more). This flag
|
||||
will prevent curl from outputting that and return error 22.
|
||||
|
||||
@@ -494,7 +492,7 @@ This option can be used multiple times.
|
||||
has been provided, this data is sent off using the ACCT command. (Added in
|
||||
7.13.0)
|
||||
|
||||
If this option is used twice, the second will override the previous use.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--ftp-alternative-to-user <command>"
|
||||
(FTP) If authenticating with the USER and PASS commands fails, send this
|
||||
command. When connecting to Tumbleweed's Secure Transport server over FTPS
|
||||
@@ -506,7 +504,7 @@ currently exist on the server, the standard behavior of curl is to
|
||||
fail. Using this option, curl will instead attempt to create missing
|
||||
directories.
|
||||
.IP "--ftp-method [method]"
|
||||
(FTP) Control what method curl should use to reach a file on a FTP(S)
|
||||
(FTP) Control what method curl should use to reach a file on an FTP(S)
|
||||
server. The method argument should be one of the following alternatives:
|
||||
.RS
|
||||
.IP multicwd
|
||||
@@ -527,9 +525,9 @@ compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||
behavior, but using this option can be used to override a previous
|
||||
\fI-P/-ftp-port\fP option. (Added in 7.11.0)
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference. Undoing an enforced passive really isn't doable but you must then
|
||||
instead enforce the correct \fI-P, --ftp-port\fP again.
|
||||
If this option is used several times, only the first one is used. Undoing an
|
||||
enforced passive really isn't doable but you must then instead enforce the
|
||||
correct \fI-P, --ftp-port\fP again.
|
||||
|
||||
Passive mode means that curl will try the EPSV command first and then PASV,
|
||||
unless \fI--disable-epsv\fP is used.
|
||||
@@ -550,7 +548,7 @@ directory listings as well as up and downloads in PASV mode.
|
||||
Shuts down the SSL/TLS layer after authenticating. The rest of the
|
||||
control channel communication will be unencrypted. This allows
|
||||
NAT routers to follow the FTP transaction. The default mode is
|
||||
passive. See --ftp-ssl-ccc-mode for other modes.
|
||||
passive. See \fI--ftp-ssl-ccc-mode\fP for other modes.
|
||||
(Added in 7.16.1)
|
||||
.IP "--ftp-ssl-ccc-mode [active/passive]"
|
||||
(FTP) Use CCC (Clear Command Channel)
|
||||
@@ -577,16 +575,16 @@ interpreted by curl itself. Note that these letters are not normal legal URL
|
||||
contents but they should be encoded according to the URI standard.
|
||||
.IP "-G, --get"
|
||||
When used, this option will make all data specified with \fI-d, --data\fP or
|
||||
\fI--data-binary\fP to be used in a HTTP GET request instead of the POST
|
||||
\fI--data-binary\fP to be used in an HTTP GET request instead of the POST
|
||||
request that otherwise would be used. The data will be appended to the URL
|
||||
with a '?' separator.
|
||||
|
||||
If used in combination with -I, the POST data will instead be appended to the
|
||||
URL with a HEAD request.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference. This is because undoing a GET doesn't make sense, but you should
|
||||
then instead enforce the alternative method you prefer.
|
||||
If this option is used several times, only the first one is used. This is
|
||||
because undoing a GET doesn't make sense, but you should then instead enforce
|
||||
the alternative method you prefer.
|
||||
.IP "-H, --header <header>"
|
||||
(HTTP) Extra header to use when getting a web page. You may specify any number
|
||||
of extra headers. Note that if you should add a custom header that has the
|
||||
@@ -595,9 +593,9 @@ header will be used instead of the internal one. This allows you to make even
|
||||
trickier stuff than curl would normally do. You should not replace internally
|
||||
set headers without knowing perfectly well what you're doing. Remove an
|
||||
internal header by giving a replacement without content on the right side of
|
||||
the colon, as in: -H \&"Host:". If you send the custom header with no-value then
|
||||
its header must be terminated with a semicolon, such as \-H "X-Custom-Header;"
|
||||
to send "X-Custom-Header:".
|
||||
the colon, as in: -H \&"Host:". If you send the custom header with no-value
|
||||
then its header must be terminated with a semicolon, such as \-H
|
||||
\&"X-Custom-Header;" to send "X-Custom-Header:".
|
||||
|
||||
curl will make sure that each header you add/replace is sent with the proper
|
||||
end-of-line marker, you should thus \fBnot\fP add that as a part of the header
|
||||
@@ -608,10 +606,9 @@ See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options.
|
||||
|
||||
This option can be used multiple times to add/replace/remove multiple headers.
|
||||
.IP "--hostpubmd5 <md5>"
|
||||
Pass a string containing 32 hexadecimal digits. The string should be the 128
|
||||
bit MD5 checksum of the remote host's public key, curl will refuse the
|
||||
connection with the host unless the md5sums match. This option is only for SCP
|
||||
and SFTP transfers. (Added in 7.17.1)
|
||||
(SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should
|
||||
be the 128 bit MD5 checksum of the remote host's public key, curl will refuse
|
||||
the connection with the host unless the md5sums match. (Added in 7.17.1)
|
||||
.IP "--ignore-content-length"
|
||||
(HTTP)
|
||||
Ignore the Content-Length header. This is particularly useful for servers
|
||||
@@ -624,7 +621,7 @@ like server-name, date of the document, HTTP-version and more...
|
||||
(HTTP/FTP/FILE)
|
||||
Fetch the HTTP-header only! HTTP-servers feature the command HEAD
|
||||
which this uses to get nothing but the header of a document. When used
|
||||
on a FTP or FILE file, curl displays the file size and last modification
|
||||
on an FTP or FILE file, curl displays the file size and last modification
|
||||
time only.
|
||||
.IP "--interface <name>"
|
||||
Perform an operation using a specified interface. You can enter interface
|
||||
@@ -639,8 +636,9 @@ make it discard all "session cookies". This will basically have the same effect
|
||||
as if a new session is started. Typical browsers always discard session
|
||||
cookies when they're closed down.
|
||||
.IP "-J, --remote-header-name"
|
||||
(HTTP) This option tells the -O, --remote-name option to use the server-specified
|
||||
Content-Disposition filename instead of extracting a filename from the URL.
|
||||
(HTTP) This option tells the \fI-O, --remote-name\fP option to use the
|
||||
server-specified Content-Disposition filename instead of extracting a filename
|
||||
from the URL.
|
||||
.IP "-k, --insecure"
|
||||
(SSL) This option explicitly allows curl to perform "insecure" SSL connections
|
||||
and transfers. All SSL connections are attempted to be made secure by using
|
||||
@@ -711,7 +709,7 @@ currently effective on operating systems offering the TCP_KEEPIDLE and
|
||||
TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This
|
||||
option has no effect if \fI--no-keepalive\fP is used. (Added in 7.18.0)
|
||||
|
||||
If this option is used multiple times, the last occurrence sets the amount. If
|
||||
If this option is used several times, the last one will be used. If
|
||||
unspecified, the option defaults to 60 seconds.
|
||||
.IP "--key <key>"
|
||||
(SSL/SSH) Private key file name. Allows you to provide your private key in this
|
||||
@@ -817,9 +815,9 @@ Specify the maximum size (in bytes) of a file to download. If the file
|
||||
requested is larger than this value, the transfer will not start and curl will
|
||||
return with exit code 63.
|
||||
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such files
|
||||
this option has no effect even if the file transfer ends up being larger than
|
||||
this given limit. This concerns both FTP and HTTP transfers.
|
||||
\fBNOTE:\fP The file size is not always known prior to download, and for such
|
||||
files this option has no effect even if the file transfer ends up being larger
|
||||
than this given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP "--mail-rcpt <address>"
|
||||
(SMTP) Specify a single address that the given mail should get sent to. This
|
||||
option can be used multiple times to specify many recipients.
|
||||
@@ -833,12 +831,12 @@ option to -1 to make it limitless.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--metalink"
|
||||
This option can tell curl to parse and process a given URI as Metalink file (both
|
||||
version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
|
||||
listed within for failover if there are errors (such as the file or
|
||||
server not being available). It will also verify the hashe of the file
|
||||
after the download completes. The Metalink file itself is downloaded
|
||||
and processed in memory and not stored in the local file system.
|
||||
This option can tell curl to parse and process a given URI as Metalink file
|
||||
(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
|
||||
listed within for failover if there are errors (such as the file or server not
|
||||
being available). It will also verify the hash of the file after the download
|
||||
completes. The Metalink file itself is downloaded and processed in memory and
|
||||
not stored in the local file system.
|
||||
|
||||
Example to use a remote Metalink file:
|
||||
|
||||
@@ -850,8 +848,8 @@ To use a Metalink file in the local file system, use FILE protocol
|
||||
\fBcurl\fP --metalink file://example.metalink
|
||||
|
||||
Please note that if FILE protocol is disabled, there is no way to use
|
||||
a local Metalink file at the time of this writing. Also note that If
|
||||
--metalink and --include are used together, --include will be
|
||||
a local Metalink file at the time of this writing. Also note that if
|
||||
\fI--metalink\fP and \fI--include\fP are used together, \fI--include\fP will be
|
||||
ignored. This is because including headers in the response will break
|
||||
Metalink parser and if the headers are included in the file described
|
||||
in Metalink file, hash check will fail.
|
||||
@@ -890,7 +888,7 @@ You can only specify one netrc file per invocation. If several
|
||||
(Added in 7.21.5)
|
||||
|
||||
This option overrides any use of \fI--netrc\fP as they are mutually exclusive.
|
||||
It will also abide by --netrc-optional if specified.
|
||||
It will also abide by \fI--netrc-optional\fP if specified.
|
||||
|
||||
.IP "--netrc-optional"
|
||||
Very similar to \fI--netrc\fP, but this option makes the .netrc usage
|
||||
@@ -910,12 +908,11 @@ This option requires a library built with GSSAPI support. This is
|
||||
not very common. Use \fI-V, --version\fP to see if your version supports
|
||||
GSS-Negotiate.
|
||||
|
||||
When using this option, you must also provide a fake -u, --user option to
|
||||
When using this option, you must also provide a fake \fI-u, --user\fP option to
|
||||
activate the authentication code properly. Sending a '-u :' is enough as the
|
||||
user name and password from the -u option aren't actually used.
|
||||
user name and password from the \fI-u\fP option aren't actually used.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
If this option is used several times, only the first one is used.
|
||||
.IP "--no-keepalive"
|
||||
Disables the use of keepalive messages on the TCP connection, as by default
|
||||
curl enables them.
|
||||
@@ -952,8 +949,7 @@ If you want to enable NTLM for your proxy authentication, then use
|
||||
This option requires a library built with SSL support. Use
|
||||
\fI-V, --version\fP to see if your curl supports NTLM.
|
||||
|
||||
If this option is used several times, the following occurrences make no
|
||||
difference.
|
||||
If this option is used several times, only the first one is used.
|
||||
.IP "-o, --output <file>"
|
||||
Write output to <file> instead of stdout. If you are using {} or [] to fetch
|
||||
multiple documents, you can use '#' followed by a number in the <file>
|
||||
@@ -1021,16 +1017,16 @@ available.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--post301"
|
||||
Tells curl to respect RFC 2616/10.3.2 and not convert POST requests into GET
|
||||
requests when following a 301 redirection. The non-RFC behaviour is ubiquitous
|
||||
in web browsers, so curl does the conversion by default to maintain
|
||||
(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
|
||||
into GET requests when following a 301 redirection. The non-RFC behaviour is
|
||||
ubiquitous in web browsers, so curl does the conversion by default to maintain
|
||||
consistency. However, a server may require a POST to remain a POST after such
|
||||
a redirection. This option is meaningful only when using \fI-L, --location\fP
|
||||
(Added in 7.17.1)
|
||||
.IP "--post302"
|
||||
Tells curl to respect RFC 2616/10.3.2 and not convert POST requests into GET
|
||||
requests when following a 302 redirection. The non-RFC behaviour is ubiquitous
|
||||
in web browsers, so curl does the conversion by default to maintain
|
||||
(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
|
||||
into GET requests when following a 302 redirection. The non-RFC behaviour is
|
||||
ubiquitous in web browsers, so curl does the conversion by default to maintain
|
||||
consistency. However, a server may require a POST to remain a POST after such
|
||||
a redirection. This option is meaningful only when using \fI-L, --location\fP
|
||||
(Added in 7.19.1)
|
||||
@@ -1119,24 +1115,24 @@ default config file search path.
|
||||
commands are sent BEFORE the transfer takes place (just after the initial PWD
|
||||
command in an FTP transfer, to be exact). To make commands take place after a
|
||||
successful transfer, prefix them with a dash '-'. To make commands be sent
|
||||
after libcurl has changed the working directory, just before the transfer
|
||||
after curl has changed the working directory, just before the transfer
|
||||
command(s), prefix the command with a '+' (this is only supported for
|
||||
FTP). You may specify any number of commands. If the server returns failure
|
||||
for one of the commands, the entire operation will be aborted. You must send
|
||||
syntactically correct FTP commands as RFC 959 defines to FTP servers, or one
|
||||
of the commands listed below to SFTP servers. This option can be used
|
||||
multiple times. When speaking to a FTP server, prefix the command with an
|
||||
asterisk (*) to make libcurl continue even if the command fails as by default
|
||||
multiple times. When speaking to an FTP server, prefix the command with an
|
||||
asterisk (*) to make curl continue even if the command fails as by default
|
||||
curl will stop at first failure.
|
||||
|
||||
SFTP is a binary protocol. Unlike for FTP, libcurl interprets SFTP quote
|
||||
commands itself before sending them to the server. File names may be quoted
|
||||
SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands
|
||||
itself before sending them to the server. File names may be quoted
|
||||
shell-style to embed spaces or special characters. Following is the list of
|
||||
all supported SFTP quote commands:
|
||||
.RS
|
||||
.IP "chgrp group file"
|
||||
The chgrp command sets the group ID of the file named by the file operand to the
|
||||
group ID specified by the group operand. The group operand is a decimal
|
||||
The chgrp command sets the group ID of the file named by the file operand to
|
||||
the group ID specified by the group operand. The group operand is a decimal
|
||||
integer group ID.
|
||||
.IP "chmod mode file"
|
||||
The chmod command modifies the file mode bits of the specified file. The
|
||||
@@ -1194,9 +1190,10 @@ specifies two separate 100-byte ranges(*)(H)
|
||||
(*) = NOTE that this will cause the server to reply with a multipart
|
||||
response!
|
||||
|
||||
Only digit characters (0-9) are valid in the 'start' and 'stop' fields of
|
||||
the \&'start-stop' range syntax. If a non-digit character is given in the range, the server's
|
||||
response will be unspecified, depending on the server's configuration.
|
||||
Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the
|
||||
\&'start-stop' range syntax. If a non-digit character is given in the range,
|
||||
the server's response will be unspecified, depending on the server's
|
||||
configuration.
|
||||
|
||||
You should also be aware that many HTTP/1.1 servers do not have this feature
|
||||
enabled, so that when you attempt to get a range, you'll instead get the whole
|
||||
@@ -1208,7 +1205,7 @@ FTP command SIZE.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-R, --remote-time"
|
||||
When used, this will make libcurl attempt to figure out the timestamp of the
|
||||
When used, this will make curl attempt to figure out the timestamp of the
|
||||
remote file, and if that is available make the local file get that same
|
||||
timestamp.
|
||||
.IP "--random-file <file>"
|
||||
@@ -1216,7 +1213,7 @@ timestamp.
|
||||
random data. The data is used to seed the random engine for SSL connections.
|
||||
See also the \fI--egd-file\fP option.
|
||||
.IP "--raw"
|
||||
When used, it disables all internal HTTP decoding of content or transfer
|
||||
(HTTP) When used, it disables all internal HTTP decoding of content or transfer
|
||||
encodings and instead makes them passed on unaltered, raw. (Added in 7.16.2)
|
||||
.IP "--remote-name-all"
|
||||
This option changes the default action for all given URLs to be dealt with as
|
||||
@@ -1248,7 +1245,7 @@ using \fI--retry-delay\fP you disable this exponential backoff algorithm. See
|
||||
also \fI--retry-max-time\fP to limit the total time allowed for
|
||||
retries. (Added in 7.12.3)
|
||||
|
||||
If this option is used multiple times, the last occurrence determines the amount.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--retry-delay <seconds>"
|
||||
Make curl sleep this amount of time before each retry when a transfer has
|
||||
failed with a transient error (it changes the default backoff time algorithm
|
||||
@@ -1256,7 +1253,7 @@ between retries). This option is only interesting if \fI--retry\fP is also
|
||||
used. Setting this delay to zero will make curl use the default backoff time.
|
||||
(Added in 7.12.3)
|
||||
|
||||
If this option is used multiple times, the last occurrence determines the amount.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--retry-max-time <seconds>"
|
||||
The retry timer is reset before the first transfer attempt. Retries will be
|
||||
done as usual (see \fI--retry\fP) as long as the timer hasn't reached this
|
||||
@@ -1265,13 +1262,12 @@ will be made and while performing, it may take longer than this given time
|
||||
period. To limit a single request\'s maximum time, use \fI-m, --max-time\fP.
|
||||
Set this option to zero to not timeout retries. (Added in 7.12.3)
|
||||
|
||||
If this option is used multiple times, the last occurrence determines the
|
||||
amount.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-s, --silent"
|
||||
Silent or quiet mode. Don't show progress meter or error messages. Makes
|
||||
Curl mute.
|
||||
.IP "-S, --show-error"
|
||||
When used with -s it makes curl show an error message if it fails.
|
||||
When used with \fI-s\fP it makes curl show an error message if it fails.
|
||||
.IP "--ssl"
|
||||
(FTP, POP3, IMAP, SMTP) Try to use SSL/TLS for the connection. Reverts to a
|
||||
non-secure connection if the server doesn't support SSL/TLS. See also
|
||||
@@ -1375,7 +1371,7 @@ part in the specified URL, Curl will append the local file name. NOTE that you
|
||||
must use a trailing / on the last directory to really prove to Curl that there
|
||||
is no file name or curl will think that your last directory name is the remote
|
||||
file name to use. That will most likely cause the upload operation to fail. If
|
||||
this is used on a HTTP(S) server, the PUT command will be used.
|
||||
this is used on an HTTP(S) server, the PUT command will be used.
|
||||
|
||||
Use the file name "-" (a single dash) to use stdin instead of a given file.
|
||||
Alternately, the file name "." (a single period) may be specified instead
|
||||
@@ -1418,7 +1414,7 @@ Set password for use with the TLS authentication method specified with
|
||||
7.21.4)
|
||||
.IP "--tr-encoding"
|
||||
(HTTP) Request a compressed Transfer-Encoding response using one of the
|
||||
algorithms libcurl supports, and uncompress the data while receiving it.
|
||||
algorithms curl supports, and uncompress the data while receiving it.
|
||||
|
||||
(Added in 7.21.6)
|
||||
.IP "--trace <file>"
|
||||
@@ -1503,17 +1499,21 @@ space with \\t.
|
||||
The %-symbol is a special symbol in the win32-environment, where all
|
||||
occurrences of % must be doubled when using this option.
|
||||
|
||||
The variables available at this point are:
|
||||
The variables available are:
|
||||
.RS
|
||||
.TP 15
|
||||
.B url_effective
|
||||
The URL that was fetched last. This is most meaningful if you've told curl
|
||||
to follow location: headers.
|
||||
.B content_type
|
||||
The Content-Type of the requested document, if there was any.
|
||||
.TP
|
||||
.B filename_effective
|
||||
The ultimate filename that curl writes out to. This is only meaningful if curl
|
||||
is told to write to a file with the --remote-name or --output option. It's most
|
||||
useful in combination with the --remote-header-name option. (Added in 7.25.1)
|
||||
is told to write to a file with the \fI--remote-name\fP or \fI--output\fP
|
||||
option. It's most useful in combination with the \fI--remote-header-name\fP
|
||||
option. (Added in 7.25.1)
|
||||
.TP
|
||||
.B ftp_entry_path
|
||||
The initial path curl ended up in when logging on to the remote FTP
|
||||
server. (Added in 7.15.4)
|
||||
.TP
|
||||
.B http_code
|
||||
The numerical response code that was found in the last retrieved HTTP(S) or
|
||||
@@ -1524,21 +1524,51 @@ same info.
|
||||
The numerical code that was found in the last response (from a proxy) to a
|
||||
curl CONNECT request. (Added in 7.12.4)
|
||||
.TP
|
||||
.B time_total
|
||||
The total time, in seconds, that the full operation lasted. The time will be
|
||||
displayed with millisecond resolution.
|
||||
.B num_connects
|
||||
Number of new connects made in the recent transfer. (Added in 7.12.3)
|
||||
.TP
|
||||
.B time_namelookup
|
||||
The time, in seconds, it took from the start until the name resolving was
|
||||
completed.
|
||||
.B num_redirects
|
||||
Number of redirects that were followed in the request. (Added in 7.12.3)
|
||||
.TP
|
||||
.B redirect_url
|
||||
When an HTTP request was made without -L to follow redirects, this variable
|
||||
will show the actual URL a redirect \fIwould\fP take you to. (Added in 7.18.2)
|
||||
.TP
|
||||
.B size_download
|
||||
The total amount of bytes that were downloaded.
|
||||
.TP
|
||||
.B size_header
|
||||
The total amount of bytes of the downloaded headers.
|
||||
.TP
|
||||
.B size_request
|
||||
The total amount of bytes that were sent in the HTTP request.
|
||||
.TP
|
||||
.B size_upload
|
||||
The total amount of bytes that were uploaded.
|
||||
.TP
|
||||
.B speed_download
|
||||
The average download speed that curl measured for the complete download. Bytes
|
||||
per second.
|
||||
.TP
|
||||
.B speed_upload
|
||||
The average upload speed that curl measured for the complete upload. Bytes per
|
||||
second.
|
||||
.TP
|
||||
.B ssl_verify_result
|
||||
The result of the SSL peer certificate verification that was requested. 0
|
||||
means the verification was successful. (Added in 7.19.0)
|
||||
.TP
|
||||
.B time_appconnect
|
||||
The time, in seconds, it took from the start until the SSL/SSH/etc
|
||||
connect/handshake to the remote host was completed. (Added in 7.19.0)
|
||||
.TP
|
||||
.B time_connect
|
||||
The time, in seconds, it took from the start until the TCP connect to the
|
||||
remote host (or proxy) was completed.
|
||||
.TP
|
||||
.B time_appconnect
|
||||
The time, in seconds, it took from the start until the SSL/SSH/etc
|
||||
connect/handshake to the remote host was completed. (Added in 7.19.0)
|
||||
.B time_namelookup
|
||||
The time, in seconds, it took from the start until the name resolving was
|
||||
completed.
|
||||
.TP
|
||||
.B time_pretransfer
|
||||
The time, in seconds, it took from the start until the file transfer was just
|
||||
@@ -1552,50 +1582,17 @@ started. time_redirect shows the complete execution time for multiple
|
||||
redirections. (Added in 7.12.3)
|
||||
.TP
|
||||
.B time_starttransfer
|
||||
The time, in seconds, it took from the start until the first byte was just about
|
||||
to be transferred. This includes time_pretransfer and also the time the
|
||||
The time, in seconds, it took from the start until the first byte was just
|
||||
about to be transferred. This includes time_pretransfer and also the time the
|
||||
server needed to calculate the result.
|
||||
.TP
|
||||
.B size_download
|
||||
The total amount of bytes that were downloaded.
|
||||
.B time_total
|
||||
The total time, in seconds, that the full operation lasted. The time will be
|
||||
displayed with millisecond resolution.
|
||||
.TP
|
||||
.B size_upload
|
||||
The total amount of bytes that were uploaded.
|
||||
.TP
|
||||
.B size_header
|
||||
The total amount of bytes of the downloaded headers.
|
||||
.TP
|
||||
.B size_request
|
||||
The total amount of bytes that were sent in the HTTP request.
|
||||
.TP
|
||||
.B speed_download
|
||||
The average download speed that curl measured for the complete download. Bytes
|
||||
per second.
|
||||
.TP
|
||||
.B speed_upload
|
||||
The average upload speed that curl measured for the complete upload. Bytes per
|
||||
second.
|
||||
.TP
|
||||
.B content_type
|
||||
The Content-Type of the requested document, if there was any.
|
||||
.TP
|
||||
.B num_connects
|
||||
Number of new connects made in the recent transfer. (Added in 7.12.3)
|
||||
.TP
|
||||
.B num_redirects
|
||||
Number of redirects that were followed in the request. (Added in 7.12.3)
|
||||
.TP
|
||||
.B redirect_url
|
||||
When a HTTP request was made without -L to follow redirects, this variable
|
||||
will show the actual URL a redirect \fIwould\fP take you to. (Added in 7.18.2)
|
||||
.TP
|
||||
.B ftp_entry_path
|
||||
The initial path libcurl ended up in when logging on to the remote FTP
|
||||
server. (Added in 7.15.4)
|
||||
.TP
|
||||
.B ssl_verify_result
|
||||
The result of the SSL peer certificate verification that was requested. 0
|
||||
means the verification was successful. (Added in 7.19.0)
|
||||
.B url_effective
|
||||
The URL that was fetched last. This is most meaningful if you've told curl
|
||||
to follow location: headers.
|
||||
.RE
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
@@ -1607,14 +1604,14 @@ This option overrides existing environment variables that set the proxy to
|
||||
use. If there's an environment variable setting a proxy, you can set proxy to
|
||||
\&"" to override it.
|
||||
|
||||
All operations that are performed over a HTTP proxy will transparently be
|
||||
All operations that are performed over an HTTP proxy will transparently be
|
||||
converted to HTTP. It means that certain protocol specific operations might
|
||||
not be available. This is not the case if you can tunnel through the proxy, as
|
||||
one with the \fI-p, --proxytunnel\fP option.
|
||||
|
||||
User and password that might be provided in the proxy string are URL decoded
|
||||
by libcurl. This allows you to pass in special characters such as @ by using
|
||||
%40 or pass in a colon with %3a.
|
||||
by curl. This allows you to pass in special characters such as @ by using %40
|
||||
or pass in a colon with %3a.
|
||||
|
||||
The proxy host can be specified the exact same way as the proxy environment
|
||||
variables, including the protocol prefix (http://) and the embedded user +
|
||||
@@ -1650,7 +1647,7 @@ attributes, a warning is issued.
|
||||
.IP "-y, --speed-time <time>"
|
||||
If a download is slower than speed-limit bytes per second during a speed-time
|
||||
period, the download gets aborted. If speed-time is used, the default
|
||||
speed-limit will be 1 unless set with -Y.
|
||||
speed-limit will be 1 unless set with \fI-Y\fP.
|
||||
|
||||
This option controls transfers and thus will not affect slow connects etc. If
|
||||
this is a concern for you, try the \fI--connect-timeout\fP option.
|
||||
@@ -1658,16 +1655,17 @@ this is a concern for you, try the \fI--connect-timeout\fP option.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-Y, --speed-limit <speed>"
|
||||
If a download is slower than this given speed (in bytes per second) for
|
||||
speed-time seconds it gets aborted. speed-time is set with -y and is 30 if
|
||||
not set.
|
||||
speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
|
||||
if not set.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-z/--time-cond <date expression>|<file>"
|
||||
(HTTP/FTP) Request a file that has been modified later than the given time and
|
||||
date, or one that has been modified before that time. The <date expression> can
|
||||
be all sorts of date strings or if it doesn't match any internal ones, it is
|
||||
taken as a filename and tries to get the modification date (mtime) from <file>
|
||||
instead. See the \fIcurl_getdate(3)\fP man pages for date expression details.
|
||||
date, or one that has been modified before that time. The <date expression>
|
||||
can be all sorts of date strings or if it doesn't match any internal ones, it
|
||||
is taken as a filename and tries to get the modification date (mtime) from
|
||||
<file> instead. See the \fIcurl_getdate(3)\fP man pages for date expression
|
||||
details.
|
||||
|
||||
Start the date expression with a dash (-) to make it request for a document
|
||||
that is older than the given date/time, default is a document that is newer
|
||||
@@ -1753,7 +1751,7 @@ Since curl version 7.21.7, the proxy string may be specified with a
|
||||
protocol:// prefix to specify alternative proxy protocols.
|
||||
|
||||
If no protocol is specified in the proxy string or if the string doesn't match
|
||||
a supported one, the proxy will be treated as a HTTP proxy.
|
||||
a supported one, the proxy will be treated as an HTTP proxy.
|
||||
|
||||
The supported proxy protocol prefixes are as follows:
|
||||
.IP "socks4://"
|
||||
|
||||
2
docs/examples/.gitignore
vendored
2
docs/examples/.gitignore
vendored
@@ -11,6 +11,7 @@ ftp-wildcard
|
||||
ftpget
|
||||
ftpgetinfo
|
||||
ftpgetresp
|
||||
ftpsget
|
||||
ftpupload
|
||||
getinfo
|
||||
getinmemory
|
||||
@@ -34,6 +35,7 @@ resolve
|
||||
rtsp
|
||||
sendrecv
|
||||
sepheaders
|
||||
sftpget
|
||||
simple
|
||||
simplepost
|
||||
simplesmtp
|
||||
|
||||
@@ -34,14 +34,13 @@ EXTRA_DIST = README Makefile.example Makefile.inc Makefile.m32 \
|
||||
# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h
|
||||
# $(top_srcdir)/include is for libcurl's external include files
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-DCURL_NO_OLDIES
|
||||
|
||||
LIBDIR = $(top_builddir)/lib
|
||||
|
||||
AM_CPPFLAGS = -DCURL_NO_OLDIES
|
||||
|
||||
# Mostly for Windows build targets, when using static libcurl
|
||||
if USE_CPPFLAG_CURL_STATICLIB
|
||||
AM_CPPFLAGS += -DCURL_STATICLIB
|
||||
|
||||
@@ -5,11 +5,11 @@ 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 pop3s pop3slist imap url2file
|
||||
progressfunc pop3s pop3slist imap url2file sftpget ftpsget
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cc cacertinmem.c \
|
||||
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
|
||||
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
|
||||
smooth-gtk-thread.c version-check.pl
|
||||
smooth-gtk-thread.c version-check.pl href_extractor.c
|
||||
|
||||
@@ -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
|
||||
@@ -336,7 +336,7 @@ static void new_conn(char *url, GlobalInfo *g )
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
|
||||
101
docs/examples/ftpsget.c
Normal file
101
docs/examples/ftpsget.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTPS server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile={
|
||||
"yourfile.bin", /* name to store the file as if succesful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works! Note that we use an
|
||||
* FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if
|
||||
* you want to do the rarer kind of transfers: implicit.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://user@server/home/user/file.txt");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* We activate SSL and we require it for both control and data */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
86
docs/examples/href_extractor.c
Normal file
86
docs/examples/href_extractor.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This example uses the "Streaming HTML parser" to extract the href pieces in
|
||||
* a streaming manner from a downloaded HTML. Kindly donated by Michał
|
||||
* Kowalczyk.
|
||||
*
|
||||
* The parser is found at
|
||||
* http://code.google.com/p/htmlstreamparser/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <htmlstreamparser.h>
|
||||
|
||||
|
||||
static size_t write_callback(void *buffer, size_t size, size_t nmemb,
|
||||
void *hsp)
|
||||
{
|
||||
size_t realsize = size * nmemb, p;
|
||||
for (p = 0; p < realsize; p++) {
|
||||
html_parser_char_parse(hsp, ((char *)buffer)[p]);
|
||||
if (html_parser_cmp_tag(hsp, "a", 1))
|
||||
if (html_parser_cmp_attr(hsp, "href", 4))
|
||||
if (html_parser_is_in(hsp, HTML_VALUE_ENDED)) {
|
||||
html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0';
|
||||
printf("%s\n", html_parser_val(hsp));
|
||||
}
|
||||
}
|
||||
return realsize;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char tag[1], attr[4], val[128];
|
||||
CURL *curl;
|
||||
HTMLSTREAMPARSER *hsp;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s URL\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
hsp = html_parser_init();
|
||||
|
||||
html_parser_set_tag_to_lower(hsp, 1);
|
||||
html_parser_set_attr_to_lower(hsp, 1);
|
||||
html_parser_set_tag_buffer(hsp, tag, sizeof(tag));
|
||||
html_parser_set_attr_buffer(hsp, attr, sizeof(attr));
|
||||
html_parser_set_val_buffer(hsp, val, sizeof(val)-1);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, hsp);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
html_parser_cleanup(hsp);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -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
|
||||
@@ -53,6 +53,9 @@ int main(void)
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* free the custom headers */
|
||||
curl_slist_free_all(chunk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -27,6 +27,8 @@ int main(void)
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
@@ -45,7 +47,7 @@ int main(void)
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
#ifdef SKIP_HOSTNAME_VERFICATION
|
||||
#ifdef SKIP_HOSTNAME_VERIFICATION
|
||||
/*
|
||||
* If the site you're connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
@@ -65,5 +67,8 @@ int main(void)
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ int main(void)
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
@@ -118,7 +118,7 @@ int main(void)
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(still_running);
|
||||
|
||||
/* See how the transfers went */
|
||||
while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||
|
||||
@@ -144,7 +144,7 @@ int main(void)
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
@@ -195,7 +195,7 @@ int main(void)
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ int main(void)
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
@@ -108,7 +108,7 @@ int main(void)
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ int main(void)
|
||||
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
@@ -131,7 +131,7 @@ int main(void)
|
||||
printf("running: %d!\n", still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ int main(void)
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
do {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
@@ -106,7 +106,7 @@ int main(void)
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
106
docs/examples/sftpget.c
Normal file
106
docs/examples/sftpget.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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>
|
||||
|
||||
/* define this to switch off the use of ssh-agent in this program */
|
||||
#undef DISABLE_SSH_AGENT
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an SFTP server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it won't create an empty file in case the remote file
|
||||
* doesn't exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
struct FtpFile *out=(struct FtpFile *)stream;
|
||||
if(out && !out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream=fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, can't open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile={
|
||||
"yourfile.bin", /* name to store the file as if succesful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works!
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"sftp://user@server/home/user/file.txt");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
#ifndef DISABLE_SSH_AGENT
|
||||
/* We activate ssh agent. For this to work you need
|
||||
to have ssh-agent running (type set | grep SSH_AGENT to check) or
|
||||
pageant on Windows (there is an icon in systray if so) */
|
||||
curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT);
|
||||
#endif
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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
|
||||
@@ -38,7 +38,7 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \
|
||||
curl_easy_unescape.3 curl_multi_setopt.3 curl_multi_socket.3 \
|
||||
curl_multi_timeout.3 curl_formget.3 curl_multi_assign.3 \
|
||||
curl_easy_pause.3 curl_easy_recv.3 curl_easy_send.3 \
|
||||
curl_multi_socket_action.3
|
||||
curl_multi_socket_action.3 curl_multi_wait.3
|
||||
|
||||
HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_init.html curl_easy_perform.html curl_easy_setopt.html \
|
||||
@@ -58,7 +58,7 @@ HTMLPAGES = curl_easy_cleanup.html curl_easy_getinfo.html \
|
||||
curl_easy_unescape.html curl_multi_setopt.html curl_multi_socket.html \
|
||||
curl_multi_timeout.html curl_formget.html curl_multi_assign.html \
|
||||
curl_easy_pause.html curl_easy_recv.html curl_easy_send.html \
|
||||
curl_multi_socket_action.html
|
||||
curl_multi_socket_action.html curl_multi_wait.html
|
||||
|
||||
PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
curl_easy_init.pdf curl_easy_perform.pdf curl_easy_setopt.pdf \
|
||||
@@ -77,7 +77,7 @@ PDFPAGES = curl_easy_cleanup.pdf curl_easy_getinfo.pdf \
|
||||
curl_easy_escape.pdf curl_easy_unescape.pdf curl_multi_setopt.pdf \
|
||||
curl_multi_socket.pdf curl_multi_timeout.pdf curl_formget.pdf \
|
||||
curl_multi_assign.pdf curl_easy_pause.pdf curl_easy_recv.pdf \
|
||||
curl_easy_send.pdf curl_multi_socket_action.pdf
|
||||
curl_easy_send.pdf curl_multi_socket_action.pdf curl_multi_wait.pdf
|
||||
|
||||
CLEANFILES = $(HTMLPAGES) $(PDFPAGES)
|
||||
|
||||
|
||||
@@ -274,14 +274,18 @@ Pass a pointer to a function that matches the following prototype: \fBint
|
||||
function(void *clientp, curl_socket_t curlfd, curlsocktype purpose);\fP. This
|
||||
function gets called by libcurl after the socket() call but before the
|
||||
connect() 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 newly created socket descriptor so additional
|
||||
setsockopt() calls can be done at the user's discretion. Return 0 (zero) from
|
||||
the callback on success. Return 1 from the callback function to signal an
|
||||
unrecoverable error to the library and it will close the socket and return
|
||||
\fICURLE_COULDNT_CONNECT\fP. (Option added in 7.16.0)
|
||||
purpose for this particular socket:
|
||||
|
||||
\fICURLSOCKTYPE_IPCXN\fP for actively created connections or since 7.28.0
|
||||
\fICURLSOCKTYPE_ACCEPT\fP for FTP when the connection was setup with PORT/EPSV
|
||||
(in earlier versions these sockets weren't passed to this callback).
|
||||
|
||||
Future versions of libcurl may support more purposes. It passes the newly
|
||||
created socket descriptor so additional setsockopt() calls can be done at the
|
||||
user's discretion. Return 0 (zero) from the callback on success. Return 1
|
||||
from the callback function to signal an unrecoverable error to the library and
|
||||
it will close the socket and return \fICURLE_COULDNT_CONNECT\fP. (Option
|
||||
added in 7.16.0)
|
||||
|
||||
Added in 7.21.5, the callback function may return
|
||||
\fICURL_SOCKOPT_ALREADY_CONNECTED\fP, which tells libcurl that the socket is
|
||||
@@ -2319,8 +2323,9 @@ Curl considers the server the intended one when the Common Name field or a
|
||||
Subject Alternate Name field in the certificate matches the host name in the
|
||||
URL to which you told Curl to connect.
|
||||
|
||||
When the value is 1, the certificate must contain a Common Name field, but it
|
||||
doesn't matter what name it says. (This is not ordinarily a useful setting).
|
||||
When the value is 1, libcurl will return a failure. It was previously (in
|
||||
7.28.0 and earlier) a debug option of some sorts, but it is no longer
|
||||
supported due to frequently leading to programmer mistakes.
|
||||
|
||||
When the value is 0, the connection succeeds regardless of the names in the
|
||||
certificate.
|
||||
@@ -2367,7 +2372,7 @@ this option then all known ciphers are disabled and only those passed in
|
||||
are enabled.
|
||||
|
||||
You'll find more details about the NSS cipher lists on this URL:
|
||||
\fIhttp://directory.fedora.redhat.com/docs/mod_nss.html#Directives\fP
|
||||
\fIhttp://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html#Directives\fP
|
||||
|
||||
.IP CURLOPT_SSL_SESSIONID_CACHE
|
||||
Pass a long set to 0 to disable libcurl's use of SSL session-ID caching. Set
|
||||
@@ -2405,8 +2410,11 @@ GSS_C_DELEG_POLICY_FLAG was available at compile-time.
|
||||
.IP CURLOPT_SSH_AUTH_TYPES
|
||||
Pass a long set to a bitmask consisting of one or more of
|
||||
CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST,
|
||||
CURLSSH_AUTH_KEYBOARD. Set CURLSSH_AUTH_ANY to let libcurl pick one. Currently
|
||||
CURLSSH_AUTH_HOST has no effect. (Added in 7.16.1)
|
||||
CURLSSH_AUTH_KEYBOARD and CURLSSH_AUTH_AGENT. Set CURLSSH_AUTH_ANY to let
|
||||
libcurl pick a suitable one. Currently CURLSSH_AUTH_HOST has no effect. (Added
|
||||
in 7.16.1) If CURLSSH_AUTH_AGENT is used, libcurl attempts to connect to
|
||||
ssh-agent or pageant and let the agent attempt the authentication. (Added in
|
||||
7.28.0)
|
||||
.IP CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
|
||||
Pass a char * pointing to a string containing 32 hexadecimal digits. The
|
||||
string should be the 128 bit MD5 checksum of the remote host's public key, and
|
||||
|
||||
@@ -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
|
||||
@@ -28,21 +28,24 @@ curl_multi_perform - reads/writes available data from each easy handle
|
||||
CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles);
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
When the app thinks there's data available for the multi_handle, it should
|
||||
call this function to read/write whatever there is to read or write right
|
||||
now. curl_multi_perform() returns as soon as the reads/writes are done. This
|
||||
This function handles transfers on all the added handles that need attention
|
||||
in an non-blocking fashion.
|
||||
|
||||
When an application has found out there's data available for the multi_handle
|
||||
or a timeout has elapsed, the application should call this function to
|
||||
read/write whatever there is to read or write right now etc.
|
||||
curl_multi_perform() returns as soon as the reads/writes are done. This
|
||||
function does not require that there actually is any data available for
|
||||
reading or that data can be written, it can be called just in case. It will
|
||||
write the number of handles that still transfer data in the second argument's
|
||||
integer-pointer.
|
||||
|
||||
When you call curl_multi_perform() and the amount of \fIrunning_handles\fP is
|
||||
changed from the previous call (or is less than the amount of easy handles
|
||||
you've added to the multi handle), you know that there is one or more
|
||||
transfers less "running". You can then call \fIcurl_multi_info_read(3)\fP to
|
||||
get information about each individual completed transfer, and that returned
|
||||
info includes CURLcode and more. If an added handle fails very quickly, it may
|
||||
never be counted as a running_handle.
|
||||
If the amount of \fIrunning_handles\fP is changed from the previous call (or
|
||||
is less than the amount of easy handles you've added to the multi handle), you
|
||||
know that there is one or more transfers less "running". You can then call
|
||||
\fIcurl_multi_info_read(3)\fP to get information about each individual
|
||||
completed transfer, and that returned info includes CURLcode and more. If an
|
||||
added handle fails very quickly, it may never be counted as a running_handle.
|
||||
|
||||
When \fIrunning_handles\fP is set to zero (0) on the return of this function,
|
||||
there is no longer any transfers in progress.
|
||||
@@ -61,12 +64,14 @@ need to wait for \&"action" and then call this function again.
|
||||
|
||||
This function only returns errors etc regarding the whole multi stack.
|
||||
Problems still might have occurred on individual transfers even when this
|
||||
function returns \fICURLM_OK\fP.
|
||||
function returns \fICURLM_OK\fP. Use \fIcurl_multi_info_read(3)\fP to figure
|
||||
out how individual transfers did.
|
||||
.SH "TYPICAL USAGE"
|
||||
Most applications will use \fIcurl_multi_fdset(3)\fP to get the multi_handle's
|
||||
file descriptors, then it'll wait for action on them using \fBselect(3)\fP and
|
||||
as soon as one or more of them are ready, \fIcurl_multi_perform(3)\fP gets
|
||||
called.
|
||||
file descriptors, and \fIcurl_multi_timeout(3)\fP to get a suitable timeout
|
||||
period, then it'll wait for action on the file descriptors using
|
||||
\fBselect(3)\fP. As soon as one or more file descriptor is ready,
|
||||
\fIcurl_multi_perform(3)\fP gets called.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_cleanup "(3), " curl_multi_init "(3), "
|
||||
.BR curl_multi_fdset "(3), " curl_multi_info_read "(3), "
|
||||
|
||||
75
docs/libcurl/curl_multi_wait.3
Normal file
75
docs/libcurl/curl_multi_wait.3
Normal file
@@ -0,0 +1,75 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * 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.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.TH curl_multi_wait 3 "12 Jul 2012" "libcurl 7.28.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_multi_wait - polls on all easy handles in a multi handle
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *numfds);
|
||||
.ad
|
||||
.SH DESCRIPTION
|
||||
This function polls on all file descriptors used by the curl easy handles
|
||||
contained in the given multi handle set. It will block until activity is
|
||||
detected on at least one of the handles or \fItimeout_ms\fP has passed.
|
||||
|
||||
The calling application may pass additional curl_waitfd structures which are
|
||||
similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call.
|
||||
|
||||
On completion, if \fInumfds\fP is supplied, it will be populated with the
|
||||
number of file descriptors on which interesting events occured.
|
||||
|
||||
If no extra file descriptors are provided and libcurl has no file descriptor
|
||||
to offer to wait for, this function will return immediately.
|
||||
|
||||
This function is encouraged to be used instead of select(3) when using the
|
||||
multi interface to allow applications to easier circumvent the common problem
|
||||
with 1024 maximum file descriptors.
|
||||
.SH curl_waitfd
|
||||
.nf
|
||||
struct curl_waitfd {
|
||||
curl_socket_t fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
.fi
|
||||
.IP CURL_WAIT_POLLIN
|
||||
Bit flag to curl_waitfd.events indicating the socket should poll on read
|
||||
events such as new data received.
|
||||
.IP CURL_WAIT_POLLPRI
|
||||
Bit flag to curl_waitfd.events indicating the socket should poll on high
|
||||
priority read events such as out of band data.
|
||||
.IP CURL_WAIT_POLLOUT
|
||||
Bit flag to curl_waitfd.events indicating the socket should poll on write
|
||||
events such as the socket being clear to write without blocking.
|
||||
.SH RETURN VALUE
|
||||
CURLMcode type, general libcurl multi interface error code. See
|
||||
\fIlibcurl-errors(3)\fP
|
||||
.SH AVAILABILITY
|
||||
This function was added in libcurl 7.28.0.
|
||||
.SH "SEE ALSO"
|
||||
.BR curl_multi_fdset "(3), " curl_multi_perform "(3)"
|
||||
@@ -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
|
||||
@@ -41,8 +41,7 @@ You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
|
||||
for a newly created one.
|
||||
|
||||
You tell the shared object what data you want it to share by using
|
||||
\fIcurl_share_setopt(3)\fP. Currently you can only share DNS and/or COOKIE
|
||||
data.
|
||||
\fIcurl_share_setopt(3)\fP.
|
||||
|
||||
Since you can use this share from multiple threads, and libcurl has no
|
||||
internal thread synchronization, you must provide mutex callbacks if you're
|
||||
|
||||
@@ -567,7 +567,9 @@ CURLSHOPT_SHARE 7.10.3
|
||||
CURLSHOPT_UNLOCKFUNC 7.10.3
|
||||
CURLSHOPT_UNSHARE 7.10.3
|
||||
CURLSHOPT_USERDATA 7.10.3
|
||||
CURLSOCKTYPE_ACCEPT 7.28.0
|
||||
CURLSOCKTYPE_IPCXN 7.16.0
|
||||
CURLSSH_AUTH_AGENT 7.28.0
|
||||
CURLSSH_AUTH_ANY 7.16.1
|
||||
CURLSSH_AUTH_DEFAULT 7.16.1
|
||||
CURLSSH_AUTH_HOST 7.16.1
|
||||
@@ -697,4 +699,7 @@ CURL_VERSION_SPNEGO 7.10.8
|
||||
CURL_VERSION_SSL 7.10
|
||||
CURL_VERSION_SSPI 7.13.2
|
||||
CURL_VERSION_TLSAUTH_SRP 7.21.4
|
||||
CURL_WAIT_POLLIN 7.28.0
|
||||
CURL_WAIT_POLLOUT 7.28.0
|
||||
CURL_WAIT_POLLPRI 7.28.0
|
||||
CURL_WRITEFUNC_PAUSE 7.18.0
|
||||
|
||||
@@ -309,8 +309,9 @@ typedef size_t (*curl_read_callback)(char *buffer,
|
||||
void *instream);
|
||||
|
||||
typedef enum {
|
||||
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
|
||||
CURLSOCKTYPE_LAST /* never use */
|
||||
CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */
|
||||
CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
|
||||
CURLSOCKTYPE_LAST /* never use */
|
||||
} curlsocktype;
|
||||
|
||||
/* The return code from the sockopt_callback can signal information back
|
||||
@@ -631,6 +632,7 @@ typedef enum {
|
||||
#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */
|
||||
#define CURLSSH_AUTH_HOST (1<<2) /* host key files */
|
||||
#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
|
||||
#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */
|
||||
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
|
||||
|
||||
#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
|
||||
@@ -1045,9 +1047,8 @@ typedef enum {
|
||||
/* Set to the Entropy Gathering Daemon socket pathname */
|
||||
CINIT(EGDSOCKET, OBJECTPOINT, 77),
|
||||
|
||||
/* Time-out connect operations after this amount of seconds, if connects
|
||||
are OK within this time, then fine... This only aborts the connect
|
||||
phase. [Only works on unix-style/SIGALRM operating systems] */
|
||||
/* Time-out connect operations after this amount of seconds, if connects are
|
||||
OK within this time, then fine... This only aborts the connect phase. */
|
||||
CINIT(CONNECTTIMEOUT, LONG, 78),
|
||||
|
||||
/* Function that will be called to store headers (instead of fwrite). The
|
||||
@@ -1221,9 +1222,9 @@ typedef enum {
|
||||
CINIT(NETRC_FILE, OBJECTPOINT, 118),
|
||||
|
||||
/* Enable SSL/TLS for FTP, pick one of:
|
||||
CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise
|
||||
CURLFTPSSL_CONTROL - SSL for the control connection or fail
|
||||
CURLFTPSSL_ALL - SSL for all communication or fail
|
||||
CURLUSESSL_TRY - try using SSL, proceed anyway otherwise
|
||||
CURLUSESSL_CONTROL - SSL for the control connection or fail
|
||||
CURLUSESSL_ALL - SSL for all communication or fail
|
||||
*/
|
||||
CINIT(USE_SSL, LONG, 119),
|
||||
|
||||
|
||||
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.27.0-DEV"
|
||||
#define LIBCURL_VERSION "7.28.1-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 27
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
#define LIBCURL_VERSION_MINOR 28
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -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 0x071B00
|
||||
#define LIBCURL_VERSION_NUM 0x071c01
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, 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,6 +89,19 @@ struct CURLMsg {
|
||||
};
|
||||
typedef struct CURLMsg CURLMsg;
|
||||
|
||||
/* Based on poll(2) structure and values.
|
||||
* We don't use pollfd and POLL* constants explicitly
|
||||
* to cover platforms without poll(). */
|
||||
#define CURL_WAIT_POLLIN 0x0001
|
||||
#define CURL_WAIT_POLLPRI 0x0002
|
||||
#define CURL_WAIT_POLLOUT 0x0004
|
||||
|
||||
struct curl_waitfd {
|
||||
curl_socket_t fd;
|
||||
short events;
|
||||
short revents; /* not supported yet */
|
||||
};
|
||||
|
||||
/*
|
||||
* Name: curl_multi_init()
|
||||
*
|
||||
@@ -133,6 +146,20 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
fd_set *exc_fd_set,
|
||||
int *max_fd);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_wait()
|
||||
*
|
||||
* Desc: Poll on all fds within a CURLM set as well as any
|
||||
* additional fds passed to the function.
|
||||
*
|
||||
* Returns: CURLMcode type, general multi error code.
|
||||
*/
|
||||
CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret);
|
||||
|
||||
/*
|
||||
* Name: curl_multi_perform()
|
||||
*
|
||||
|
||||
@@ -64,23 +64,21 @@ CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
|
||||
# $(top_srcdir)/ares is for in-tree c-ares's external include files
|
||||
|
||||
if USE_EMBEDDED_ARES
|
||||
INCLUDES = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_builddir)/ares \
|
||||
-I$(top_srcdir)/ares
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_builddir)/ares \
|
||||
-I$(top_srcdir)/ares
|
||||
else
|
||||
INCLUDES = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include/curl \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS =
|
||||
|
||||
# Mostly for Windows build targets, when building libcurl library
|
||||
if USE_CPPFLAG_BUILDING_LIBCURL
|
||||
AM_CPPFLAGS += -DBUILDING_LIBCURL
|
||||
@@ -101,9 +99,9 @@ if SONAME_BUMP
|
||||
#
|
||||
# This conditional soname bump SHOULD be removed at next "proper" bump.
|
||||
#
|
||||
VERSIONINFO=-version-info 7:0:2
|
||||
VERSIONINFO=-version-info 8:0:3
|
||||
else
|
||||
VERSIONINFO=-version-info 6:0:2
|
||||
VERSIONINFO=-version-info 7:0:3
|
||||
endif
|
||||
|
||||
# This flag accepts an argument of the form current[:revision[:age]]. So,
|
||||
|
||||
@@ -24,7 +24,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
|
||||
asyn-ares.c asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c \
|
||||
curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_schannel.c \
|
||||
curl_multibyte.c curl_darwinssl.c
|
||||
curl_multibyte.c curl_darwinssl.c hostcheck.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -41,4 +41,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
|
||||
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h curl_ntlm.h \
|
||||
curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h curl_ntlm_msgs.h \
|
||||
curl_sasl.h curl_schannel.h curl_multibyte.h curl_darwinssl.h
|
||||
curl_sasl.h curl_schannel.h curl_multibyte.h curl_darwinssl.h \
|
||||
hostcheck.h
|
||||
|
||||
@@ -273,8 +273,9 @@ $(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES)
|
||||
|
||||
$(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENCIES)
|
||||
@$(call DEL, $@)
|
||||
$(CC) $(LDFLAGS) -shared -Wl,--out-implib,$(libcurl_dll_a_LIBRARY) \
|
||||
-o $@ $(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS)
|
||||
$(CC) $(LDFLAGS) -shared -o $@ \
|
||||
-Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY) \
|
||||
$(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS)
|
||||
|
||||
%.o: %.c $(PROOT)/include/curl/curlbuild.h
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
@@ -289,7 +290,7 @@ endif
|
||||
@$(call DEL, $(libcurl_a_OBJECTS) $(RESOURCE))
|
||||
|
||||
distclean vclean: clean
|
||||
@$(call DEL, $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_a_LIBRARY))
|
||||
@$(call DEL, $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY))
|
||||
|
||||
$(PROOT)/include/curl/curlbuild.h:
|
||||
@echo Creating $@
|
||||
|
||||
@@ -105,7 +105,7 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
@@ -116,7 +116,7 @@ LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
ZLIBLIBSDLL= zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
@@ -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
|
||||
@@ -83,6 +83,8 @@
|
||||
# define CARES_STATICLIB
|
||||
# endif
|
||||
# include <ares.h>
|
||||
# include <ares_version.h> /* really old c-ares didn't include this by
|
||||
itself */
|
||||
|
||||
#if ARES_VERSION >= 0x010500
|
||||
/* c-ares 1.5.0 or later, the callback proto is modified */
|
||||
|
||||
66
lib/axtls.c
66
lib/axtls.c
@@ -47,6 +47,8 @@
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
#include "hostcheck.h"
|
||||
|
||||
|
||||
/* SSL_read is opied from axTLS compat layer */
|
||||
static int SSL_read(SSL *ssl, void *buf, int num)
|
||||
@@ -150,7 +152,11 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
int i, ssl_fcn_return;
|
||||
const uint8_t *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
const char *x509;
|
||||
const char *peer_CN;
|
||||
uint32_t dns_altname_index;
|
||||
const char *dns_altname;
|
||||
int8_t found_subject_alt_names = 0;
|
||||
int8_t found_subject_alt_name_matching_conn = 0;
|
||||
|
||||
/* Assuming users will not compile in custom key/cert to axTLS */
|
||||
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
|
||||
@@ -296,19 +302,65 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
/* Here, gtls.c does issuer verification. axTLS has no straightforward
|
||||
* equivalent, so omitting for now.*/
|
||||
|
||||
/* See if common name was set in server certificate */
|
||||
x509 = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
|
||||
if(x509 == NULL)
|
||||
infof(data, "error fetching CN from cert\n");
|
||||
|
||||
/* Here, gtls.c does the following
|
||||
* 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
|
||||
* it seems useful. Omitting for now.
|
||||
* it seems useful. This is now implemented, by Oscar Koeroo
|
||||
* 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
|
||||
* 3) displays a bunch of cert information. axTLS doesn't support most of
|
||||
* this, but a couple fields are available.
|
||||
*/
|
||||
|
||||
|
||||
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
|
||||
risk of an inifite loop */
|
||||
for(dns_altname_index = 0; ; dns_altname_index++) {
|
||||
dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
|
||||
if(dns_altname == NULL) {
|
||||
break;
|
||||
}
|
||||
found_subject_alt_names = 1;
|
||||
|
||||
infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
|
||||
dns_altname, conn->host.name);
|
||||
if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
|
||||
found_subject_alt_name_matching_conn = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC2818 checks */
|
||||
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
|
||||
/* Break connection ! */
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else if(found_subject_alt_names == 0) {
|
||||
/* Per RFC2818, when no Subject Alt Names were available, examine the peer
|
||||
CN as a legacy fallback */
|
||||
peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
|
||||
if(peer_CN == NULL) {
|
||||
/* Similar behaviour to the OpenSSL interface */
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "unable to obtain common name from peer certificate");
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
/* Break connection ! */
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
|
||||
peer_CN, conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else
|
||||
infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
|
||||
peer_CN, conn->host.dispname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* General housekeeping */
|
||||
conn->ssl[sockindex].state = ssl_connection_complete;
|
||||
conn->ssl[sockindex].ssl = ssl;
|
||||
|
||||
@@ -1101,7 +1101,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
|
||||
if(sockfd == CURL_SOCKET_BAD) {
|
||||
/* no good connect was made */
|
||||
failf(data, "couldn't connect to host");
|
||||
failf(data, "couldn't connect to %s at %s:%d",
|
||||
conn->bits.proxy?"proxy":"host",
|
||||
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,16 @@
|
||||
/* From MacTypes.h (which we can't include because it isn't present in iOS: */
|
||||
#define ioErr -36
|
||||
|
||||
/* In Mountain Lion and iOS 5, Apple made some changes to the API. They
|
||||
added TLS 1.1 and 1.2 support, and deprecated and replaced some
|
||||
functions. You need to build against the Mountain Lion or iOS 5 SDK
|
||||
or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link
|
||||
to the newer functions and use them if present in the user's OS.
|
||||
|
||||
Builders: If you want TLS 1.1 and 1.2 but still want to retain support
|
||||
for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET
|
||||
environmental variable prior to building cURL. */
|
||||
|
||||
/* The following two functions were ripped from Apple sample code,
|
||||
* with some modifications: */
|
||||
static OSStatus SocketRead(SSLConnectionRef connection,
|
||||
@@ -166,8 +176,9 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
|
||||
return ortn;
|
||||
}
|
||||
|
||||
CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) {
|
||||
CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
|
||||
switch (cipher) {
|
||||
/* SSL version 3.0 */
|
||||
case SSL_RSA_WITH_NULL_MD5:
|
||||
return "SSL_RSA_WITH_NULL_MD5";
|
||||
break;
|
||||
@@ -255,6 +266,8 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) {
|
||||
case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
|
||||
return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
|
||||
break;
|
||||
/* TLS 1.0 with AES (RFC 3268)
|
||||
(Apparently these are used in SSLv3 implementations as well.) */
|
||||
case TLS_RSA_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_RSA_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
@@ -291,6 +304,63 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) {
|
||||
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
/* SSL version 2.0 */
|
||||
case SSL_RSA_WITH_RC2_CBC_MD5:
|
||||
return "SSL_RSA_WITH_RC2_CBC_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_IDEA_CBC_MD5:
|
||||
return "SSL_RSA_WITH_IDEA_CBC_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_DES_CBC_MD5:
|
||||
return "SSL_RSA_WITH_DES_CBC_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
|
||||
return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
|
||||
break;
|
||||
}
|
||||
return "SSL_NULL_WITH_NULL_NULL";
|
||||
}
|
||||
|
||||
CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
|
||||
switch(cipher) {
|
||||
/* TLS 1.0 with AES (RFC 3268) */
|
||||
case TLS_RSA_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_RSA_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_128_CBC_SHA:
|
||||
return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
|
||||
break;
|
||||
case TLS_RSA_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_RSA_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
/* TLS 1.0 with ECDSA (RFC 4492) */
|
||||
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
|
||||
return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
|
||||
break;
|
||||
@@ -366,20 +436,194 @@ CF_INLINE const char *CipherNameForNumber(SSLCipherSuite cipher) {
|
||||
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
|
||||
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
|
||||
break;
|
||||
case SSL_RSA_WITH_RC2_CBC_MD5:
|
||||
return "SSL_RSA_WITH_RC2_CBC_MD5";
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
/* TLS 1.2 (RFC 5246) */
|
||||
case TLS_RSA_WITH_NULL_MD5:
|
||||
return "TLS_RSA_WITH_NULL_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_IDEA_CBC_MD5:
|
||||
return "SSL_RSA_WITH_IDEA_CBC_MD5";
|
||||
case TLS_RSA_WITH_NULL_SHA:
|
||||
return "TLS_RSA_WITH_NULL_SHA";
|
||||
break;
|
||||
case SSL_RSA_WITH_DES_CBC_MD5:
|
||||
return "SSL_RSA_WITH_DES_CBC_MD5";
|
||||
case TLS_RSA_WITH_RC4_128_MD5:
|
||||
return "TLS_RSA_WITH_RC4_128_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
|
||||
return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
|
||||
case TLS_RSA_WITH_RC4_128_SHA:
|
||||
return "TLS_RSA_WITH_RC4_128_SHA";
|
||||
break;
|
||||
case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_RSA_WITH_NULL_SHA256:
|
||||
return "TLS_RSA_WITH_NULL_SHA256";
|
||||
break;
|
||||
case TLS_RSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_RSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_RSA_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_RSA_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_RC4_128_MD5:
|
||||
return "TLS_DH_anon_WITH_RC4_128_MD5";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
|
||||
return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
|
||||
break;
|
||||
/* TLS 1.2 with AES GCM (RFC 5288) */
|
||||
case TLS_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_RSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_RSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
/* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
|
||||
break;
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
|
||||
break;
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
|
||||
return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
|
||||
break;
|
||||
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
|
||||
return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
|
||||
break;
|
||||
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
|
||||
return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
|
||||
break;
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
|
||||
return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
|
||||
break;
|
||||
case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
|
||||
return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
|
||||
break;
|
||||
case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
|
||||
return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
|
||||
break;
|
||||
#else
|
||||
case SSL_RSA_WITH_NULL_MD5:
|
||||
return "TLS_RSA_WITH_NULL_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_NULL_SHA:
|
||||
return "TLS_RSA_WITH_NULL_SHA";
|
||||
break;
|
||||
case SSL_RSA_WITH_RC4_128_MD5:
|
||||
return "TLS_RSA_WITH_RC4_128_MD5";
|
||||
break;
|
||||
case SSL_RSA_WITH_RC4_128_SHA:
|
||||
return "TLS_RSA_WITH_RC4_128_SHA";
|
||||
break;
|
||||
case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
case SSL_DH_anon_WITH_RC4_128_MD5:
|
||||
return "TLS_DH_anon_WITH_RC4_128_MD5";
|
||||
break;
|
||||
case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
|
||||
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
|
||||
break;
|
||||
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
||||
}
|
||||
return "(NONE)";
|
||||
return "TLS_NULL_WITH_NULL_NULL";
|
||||
}
|
||||
|
||||
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
@@ -388,7 +632,6 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
bool sni = true;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr;
|
||||
#else
|
||||
@@ -397,6 +640,29 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
/*SSLConnectionRef ssl_connection;*/
|
||||
OSStatus err = noErr;
|
||||
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
|
||||
if(connssl->ssl_ctx)
|
||||
CFRelease(connssl->ssl_ctx);
|
||||
connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
|
||||
if(!connssl->ssl_ctx) {
|
||||
failf(data, "SSL: couldn't create a context!");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* The old ST API does not exist under iOS, so don't compile it: */
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
if(connssl->ssl_ctx)
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
}
|
||||
#else
|
||||
if(connssl->ssl_ctx)
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||
@@ -404,8 +670,74 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
if(SSLSetProtocolVersionMax != NULL) {
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT: default:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
|
||||
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocolAll,
|
||||
false);
|
||||
switch (data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT: default:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocol3,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol1,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol11,
|
||||
true);
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kTLSProtocol12,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocol3,
|
||||
true);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocol2,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
}
|
||||
#else
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
@@ -433,6 +765,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
true);
|
||||
break;
|
||||
}
|
||||
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
||||
|
||||
/* No need to load certificates here. SecureTransport uses the Keychain
|
||||
* (which is also part of the Security framework) to evaluate trust. */
|
||||
@@ -441,19 +774,43 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
* fail to connect if the verification fails, or if it should continue
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
* SSL_get_verify_result() below. */
|
||||
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
|
||||
if(SSLSetSessionOption != NULL) {
|
||||
err = SSLSetSessionOption(connssl->ssl_ctx,
|
||||
kSSLSessionOptionBreakOnServerAuth,
|
||||
data->set.ssl.verifypeer?false:true);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
data->set.ssl.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
}
|
||||
#else
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
data->set.ssl.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
|
||||
|
||||
/* If this is a domain name and not an IP address, then configure SNI.
|
||||
* Also: the verifyhost setting influences SNI usage */
|
||||
/* If this is a domain name and not an IP address, then configure SNI: */
|
||||
if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||
#endif
|
||||
sni) {
|
||||
data->set.ssl.verifyhost) {
|
||||
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
|
||||
strlen(conn->host.name));
|
||||
if(err != noErr) {
|
||||
@@ -492,6 +849,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
OSStatus err;
|
||||
SSLCipherSuite cipher;
|
||||
SSLProtocol protocol = 0;
|
||||
|
||||
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|
||||
|| ssl_connect_2_reading == connssl->connecting_state
|
||||
@@ -506,7 +864,6 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
connssl->connecting_state = connssl->ssl_direction ?
|
||||
ssl_connect_2_writing : ssl_connect_2_reading;
|
||||
return CURLE_OK;
|
||||
break;
|
||||
|
||||
case errSSLServerAuthCompleted:
|
||||
/* the documentation says we need to call SSLHandshake() again */
|
||||
@@ -518,13 +875,16 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
case errSSLCertExpired:
|
||||
failf(data, "SSL certificate problem: OSStatus %d", err);
|
||||
return CURLE_SSL_CACERT;
|
||||
break;
|
||||
|
||||
case errSSLHostNameMismatch:
|
||||
failf(data, "SSL certificate peer verification failed, the "
|
||||
"certificate did not match \"%s\"\n", conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
|
||||
default:
|
||||
failf(data, "Unknown SSL protocol error in connection to %s:%d",
|
||||
conn->host.name, err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -533,7 +893,34 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* Informational message */
|
||||
(void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
|
||||
infof (data, "SSL connection using %s\n", CipherNameForNumber(cipher));
|
||||
(void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
|
||||
switch (protocol) {
|
||||
case kSSLProtocol2:
|
||||
infof(data, "SSL 2.0 connection using %s\n",
|
||||
SSLCipherNameForNumber(cipher));
|
||||
break;
|
||||
case kSSLProtocol3:
|
||||
infof(data, "SSL 3.0 connection using %s\n",
|
||||
SSLCipherNameForNumber(cipher));
|
||||
break;
|
||||
case kTLSProtocol1:
|
||||
infof(data, "TLS 1.0 connection using %s\n",
|
||||
TLSCipherNameForNumber(cipher));
|
||||
break;
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
case kTLSProtocol11:
|
||||
infof(data, "TLS 1.1 connection using %s\n",
|
||||
TLSCipherNameForNumber(cipher));
|
||||
break;
|
||||
case kTLSProtocol12:
|
||||
infof(data, "TLS 1.2 connection using %s\n",
|
||||
TLSCipherNameForNumber(cipher));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
infof(data, "Unknown protocol connection\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -551,10 +938,83 @@ darwinssl_connect_step3(struct connectdata *conn,
|
||||
SecCertificateRef server_cert;
|
||||
OSStatus err;
|
||||
CFIndex i, count;
|
||||
SecTrustRef trust;
|
||||
|
||||
/* There is no step 3!
|
||||
* Well, okay, if verbose mode is on, let's print the details of the
|
||||
* server certificates. */
|
||||
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
|
||||
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
|
||||
#pragma unused(server_certs)
|
||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
||||
if(err == noErr) {
|
||||
count = SecTrustGetCertificateCount(trust);
|
||||
for(i = 0L ; i < count ; i++) {
|
||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||
server_cert_summary = SecCertificateCopySubjectSummary(server_cert);
|
||||
memset(server_cert_summary_c, 0, 128);
|
||||
if(CFStringGetCString(server_cert_summary,
|
||||
server_cert_summary_c,
|
||||
128,
|
||||
kCFStringEncodingUTF8)) {
|
||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
||||
}
|
||||
CFRelease(server_cert_summary);
|
||||
}
|
||||
CFRelease(trust);
|
||||
}
|
||||
#else
|
||||
/* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
|
||||
The function SecTrustGetCertificateAtIndex() is officially present
|
||||
in Lion, but it is unfortunately also present in Snow Leopard as
|
||||
private API and doesn't work as expected. So we have to look for
|
||||
a different symbol to make sure this code is only executed under
|
||||
Lion or later. */
|
||||
if(SecTrustEvaluateAsync != NULL) {
|
||||
#pragma unused(server_certs)
|
||||
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
||||
if(err == noErr) {
|
||||
count = SecTrustGetCertificateCount(trust);
|
||||
for(i = 0L ; i < count ; i++) {
|
||||
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||
server_cert_summary =
|
||||
SecCertificateCopyLongDescription(NULL, server_cert, NULL);
|
||||
memset(server_cert_summary_c, 0, 128);
|
||||
if(CFStringGetCString(server_cert_summary,
|
||||
server_cert_summary_c,
|
||||
128,
|
||||
kCFStringEncodingUTF8)) {
|
||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
||||
}
|
||||
CFRelease(server_cert_summary);
|
||||
}
|
||||
CFRelease(trust);
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||
if(err == noErr) {
|
||||
count = CFArrayGetCount(server_certs);
|
||||
for(i = 0L ; i < count ; i++) {
|
||||
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
|
||||
i);
|
||||
|
||||
server_cert_summary = SecCertificateCopySubjectSummary(server_cert);
|
||||
memset(server_cert_summary_c, 0, 128);
|
||||
if(CFStringGetCString(server_cert_summary,
|
||||
server_cert_summary_c,
|
||||
128,
|
||||
kCFStringEncodingUTF8)) {
|
||||
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
||||
}
|
||||
CFRelease(server_cert_summary);
|
||||
}
|
||||
CFRelease(server_certs);
|
||||
}
|
||||
}
|
||||
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
|
||||
#else
|
||||
#pragma unused(trust)
|
||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||
if(err == noErr) {
|
||||
count = CFArrayGetCount(server_certs);
|
||||
@@ -573,6 +1033,7 @@ darwinssl_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
CFRelease(server_certs);
|
||||
}
|
||||
#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */
|
||||
|
||||
connssl->connecting_state = ssl_connect_done;
|
||||
return CURLE_OK;
|
||||
@@ -722,9 +1183,20 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
(void)SSLClose(connssl->ssl_ctx);
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
connssl->ssl_ctx = NULL;
|
||||
if(connssl->ssl_ctx) {
|
||||
(void)SSLClose(connssl->ssl_ctx);
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
if(SSLCreateContext != NULL)
|
||||
CFRelease(connssl->ssl_ctx);
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
else
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
#else
|
||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
||||
connssl->ssl_ctx = NULL;
|
||||
}
|
||||
connssl->ssl_sockfd = 0;
|
||||
}
|
||||
|
||||
@@ -840,15 +1312,15 @@ void Curl_darwinssl_random(struct SessionHandle *data,
|
||||
/* arc4random_buf() isn't available on cats older than Lion, so let's
|
||||
do this manually for the benefit of the older cats. */
|
||||
size_t i;
|
||||
u_int32_t random = 0;
|
||||
u_int32_t random_number = 0;
|
||||
|
||||
for(i = 0 ; i < length ; i++) {
|
||||
if(i % sizeof(u_int32_t) == 0)
|
||||
random = arc4random();
|
||||
entropy[i] = random & 0xFF;
|
||||
random >>= 8;
|
||||
random_number = arc4random();
|
||||
entropy[i] = random_number & 0xFF;
|
||||
random_number >>= 8;
|
||||
}
|
||||
i = random = 0;
|
||||
i = random_number = 0;
|
||||
(void)data;
|
||||
}
|
||||
|
||||
@@ -907,6 +1379,11 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case errSSLClosedGraceful: /* they're done; fail gracefully */
|
||||
*curlcode = CURLE_OK;
|
||||
return -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
failf(conn->data, "SSLRead() return error %d", err);
|
||||
*curlcode = CURLE_RECV_ERROR;
|
||||
|
||||
@@ -95,7 +95,13 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(ntlm->state >= NTLMSTATE_TYPE1) {
|
||||
if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
ntlm->state = NTLMSTATE_NONE;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
else if(ntlm->state >= NTLMSTATE_TYPE1) {
|
||||
infof(conn->data, "NTLM handshake failure (internal error)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "nonblock.h" /* for curlx_nonblock */
|
||||
#include "progress.h" /* for Curl_pgrsSetUploadSize */
|
||||
#include "transfer.h"
|
||||
#include "warnless.h"
|
||||
#include <curl/curl.h>
|
||||
#include <librtmp/rtmp.h>
|
||||
|
||||
@@ -279,7 +280,7 @@ static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
nread = RTMP_Read(r, buf, len);
|
||||
nread = RTMP_Read(r, buf, curlx_uztosi(len));
|
||||
if(nread < 0) {
|
||||
if(r->m_read.status == RTMP_READ_COMPLETE ||
|
||||
r->m_read.status == RTMP_READ_EOF) {
|
||||
@@ -300,7 +301,7 @@ static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
num = RTMP_Write(r, (char *)buf, len);
|
||||
num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
|
||||
if(num < 0)
|
||||
*err = CURLE_SEND_ERROR;
|
||||
|
||||
|
||||
@@ -156,14 +156,22 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: disable server certificate revocation checks\n");
|
||||
}
|
||||
|
||||
if(Curl_inet_pton(AF_INET, conn->host.name, &addr) ||
|
||||
if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
|
||||
#ifdef ENABLE_IPV6
|
||||
Curl_inet_pton(AF_INET6, conn->host.name, &addr6) ||
|
||||
|| Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
|
||||
#endif
|
||||
data->set.ssl.verifyhost < 2) {
|
||||
) {
|
||||
schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
|
||||
infof(data, "schannel: using IP address, disable SNI servername "
|
||||
"check\n");
|
||||
infof(data, "schannel: using IP address, SNI is being disabled by "
|
||||
"disabling the servername check against the "
|
||||
"subject names in server certificates.\n");
|
||||
}
|
||||
|
||||
if(!data->set.ssl.verifyhost) {
|
||||
schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
|
||||
infof(data, "schannel: verifyhost setting prevents Schannel from "
|
||||
"comparing the supplied target name with the subject "
|
||||
"names in server certificates. Also disables SNI.\n");
|
||||
}
|
||||
|
||||
switch(data->set.ssl.version) {
|
||||
@@ -284,7 +292,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
CURLcode code;
|
||||
bool doread;
|
||||
|
||||
doread = (connssl->connecting_state != ssl_connect_2_writing)?TRUE:FALSE;
|
||||
doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
|
||||
|
||||
infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
@@ -303,11 +311,6 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
/* if we need a bigger buffer to read a full message, increase buffer now */
|
||||
if(connssl->encdata_length - connssl->encdata_offset <
|
||||
CURL_SCHANNEL_BUFFER_FREE_SIZE) {
|
||||
if(connssl->encdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) {
|
||||
failf(data, "schannel: memory buffer size limit reached");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* increase internal encrypted data buffer */
|
||||
connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
|
||||
connssl->encdata_buffer = realloc(connssl->encdata_buffer,
|
||||
@@ -509,6 +512,13 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* increment the reference counter of the credential/session handle */
|
||||
if(connssl->cred && connssl->ctxt) {
|
||||
connssl->cred->refcount++;
|
||||
infof(data, "schannel: incremented credential handle refcount = %d\n",
|
||||
connssl->cred->refcount);
|
||||
}
|
||||
|
||||
/* save the current session data for possible re-use */
|
||||
incache = !(Curl_ssl_getsessionid(conn, (void**)&old_cred, NULL));
|
||||
if(incache) {
|
||||
@@ -526,7 +536,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
return retcode;
|
||||
}
|
||||
else {
|
||||
infof(data, "schannel: stored crendential handle\n");
|
||||
infof(data, "schannel: stored credential handle in session cache\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +700,7 @@ schannel_send(struct connectdata *conn, int sockindex,
|
||||
InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
|
||||
data, connssl->stream_sizes.cbHeader);
|
||||
InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
|
||||
data + connssl->stream_sizes.cbHeader, len);
|
||||
data + connssl->stream_sizes.cbHeader, curlx_uztoul(len));
|
||||
InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
|
||||
data + connssl->stream_sizes.cbHeader + len,
|
||||
connssl->stream_sizes.cbTrailer);
|
||||
@@ -825,12 +835,6 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
/* increase buffer in order to fit the requested amount of data */
|
||||
while(connssl->encdata_length - connssl->encdata_offset <
|
||||
CURL_SCHANNEL_BUFFER_FREE_SIZE || connssl->encdata_length < len) {
|
||||
if(connssl->encdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) {
|
||||
failf(data, "schannel: memory buffer size limit reached");
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* increase internal encrypted data buffer */
|
||||
connssl->encdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
|
||||
connssl->encdata_buffer = realloc(connssl->encdata_buffer,
|
||||
@@ -867,7 +871,8 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
connssl->encdata_offset, connssl->encdata_length);
|
||||
|
||||
/* check if we still have some data in our buffers */
|
||||
while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK) {
|
||||
while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK &&
|
||||
connssl->decdata_offset < len) {
|
||||
/* prepare data buffer for DecryptMessage call */
|
||||
InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer,
|
||||
curlx_uztoul(connssl->encdata_offset));
|
||||
@@ -904,12 +909,6 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
|
||||
while(connssl->decdata_length - connssl->decdata_offset < size ||
|
||||
connssl->decdata_length < len) {
|
||||
if(connssl->decdata_length >= CURL_SCHANNEL_BUFFER_MAX_SIZE) {
|
||||
failf(data, "schannel: memory buffer size limit reached");
|
||||
*err = CURLE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* increase internal decrypted data buffer */
|
||||
connssl->decdata_length *= CURL_SCHANNEL_BUFFER_STEP_FACTOR;
|
||||
connssl->decdata_buffer = realloc(connssl->decdata_buffer,
|
||||
@@ -980,6 +979,9 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->decdata_offset, connssl->decdata_length);
|
||||
|
||||
/* copy requested decrypted data to supplied buffer */
|
||||
size = len < connssl->decdata_offset ? len : connssl->decdata_offset;
|
||||
if(size > 0) {
|
||||
@@ -990,6 +992,10 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
memmove(connssl->decdata_buffer, connssl->decdata_buffer + size,
|
||||
connssl->decdata_offset - size);
|
||||
connssl->decdata_offset -= size;
|
||||
|
||||
infof(data, "schannel: decrypted data returned %zd\n", size);
|
||||
infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
|
||||
connssl->decdata_offset, connssl->decdata_length);
|
||||
}
|
||||
|
||||
/* check if the server closed the connection */
|
||||
@@ -1063,7 +1069,7 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
|
||||
if(connssl->ctxt) {
|
||||
if(connssl->cred && connssl->ctxt) {
|
||||
SecBufferDesc BuffDesc;
|
||||
SecBuffer Buffer;
|
||||
SECURITY_STATUS sspi_status;
|
||||
@@ -1125,6 +1131,13 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
|
||||
s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
|
||||
Curl_safefree(connssl->ctxt);
|
||||
}
|
||||
|
||||
/* decrement the reference counter of the credential/session handle */
|
||||
if(connssl->cred && connssl->cred->refcount > 0) {
|
||||
connssl->cred->refcount--;
|
||||
infof(data, "schannel: decremented credential handle refcount = %d\n",
|
||||
connssl->cred->refcount);
|
||||
}
|
||||
}
|
||||
|
||||
/* free internal buffer for received encrypted data */
|
||||
@@ -1148,7 +1161,7 @@ void Curl_schannel_session_free(void *ptr)
|
||||
{
|
||||
struct curl_schannel_cred *cred = ptr;
|
||||
|
||||
if(cred) {
|
||||
if(cred && cred->refcount == 0) {
|
||||
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
|
||||
Curl_safefree(cred);
|
||||
}
|
||||
@@ -1233,10 +1246,7 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
if(result == CURLE_OK) {
|
||||
if(data->set.ssl.verifyhost == 1) {
|
||||
infof(data, "warning: ignoring unsupported value (1) ssl.verifyhost\n");
|
||||
}
|
||||
else if(data->set.ssl.verifyhost == 2) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
TCHAR cert_hostname_buff[128];
|
||||
xcharp_u hostname;
|
||||
xcharp_u cert_hostname;
|
||||
|
||||
@@ -93,16 +93,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BUFSIZE
|
||||
#define CURL_SCHANNEL_BUFFER_INIT_SIZE BUFSIZE
|
||||
#define CURL_SCHANNEL_BUFFER_FREE_SIZE BUFSIZE/2
|
||||
#else
|
||||
#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096
|
||||
#define CURL_SCHANNEL_BUFFER_FREE_SIZE 2048
|
||||
#endif
|
||||
|
||||
#define CURL_SCHANNEL_BUFFER_MAX_SIZE CURL_SCHANNEL_BUFFER_INIT_SIZE*16
|
||||
#define CURL_SCHANNEL_BUFFER_STEP_FACTOR 2
|
||||
#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096
|
||||
#define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024
|
||||
#define CURL_SCHANNEL_BUFFER_STEP_FACTOR 2
|
||||
|
||||
|
||||
CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex);
|
||||
|
||||
47
lib/cyassl.c
47
lib/cyassl.c
@@ -53,6 +53,8 @@
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
#include <cyassl/ssl.h>
|
||||
#include <cyassl/error.h>
|
||||
|
||||
|
||||
static Curl_recv cyassl_recv;
|
||||
@@ -237,6 +239,13 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
conn->recv[sockindex] = cyassl_recv;
|
||||
conn->send[sockindex] = cyassl_send;
|
||||
|
||||
/* Enable RFC2818 checks */
|
||||
if(data->set.ssl.verifyhost) {
|
||||
ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
|
||||
if(ret == SSL_FAILURE)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ret = SSL_connect(conssl->handle);
|
||||
if(ret != 1) {
|
||||
char error_buffer[80];
|
||||
@@ -246,15 +255,43 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
conssl->connecting_state = ssl_connect_2_reading;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(SSL_ERROR_WANT_WRITE == detail) {
|
||||
else if(SSL_ERROR_WANT_WRITE == detail) {
|
||||
conssl->connecting_state = ssl_connect_2_writing;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
failf(data, "SSL_connect failed with error %d: %s", detail,
|
||||
/* There is no easy way to override only the CN matching.
|
||||
* This will enable the override of both mismatching SubjectAltNames
|
||||
* as also mismatching CN fields */
|
||||
else if(DOMAIN_NAME_MISMATCH == detail) {
|
||||
#if 1
|
||||
failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
|
||||
conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
#else
|
||||
/* When the CyaSSL_check_domain_name() is used and you desire to continue
|
||||
* on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0',
|
||||
* CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
|
||||
* way to do this is currently to switch the CyaSSL_check_domain_name()
|
||||
* in and out based on the 'data->set.ssl.verifyhost' value. */
|
||||
if(data->set.ssl.verifyhost) {
|
||||
failf(data,
|
||||
"\tsubject alt name(s) or common name do not match \"%s\"\n",
|
||||
conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
infof(data,
|
||||
"\tsubject alt name(s) and/or common name do not match \"%s\"\n",
|
||||
conn->host.dispname);
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
failf(data, "SSL_connect failed with error %d: %s", detail,
|
||||
ERR_error_string(detail, error_buffer));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
conssl->connecting_state = ssl_connect_3;
|
||||
|
||||
@@ -67,10 +67,10 @@
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
45
lib/file.c
45
lib/file.c
@@ -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
|
||||
@@ -310,7 +310,8 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
{
|
||||
struct FILEPROTO *file = conn->data->state.proto.file;
|
||||
const char *dir = strchr(file->path, DIRSEP);
|
||||
FILE *fp;
|
||||
int fd;
|
||||
int mode;
|
||||
CURLcode res=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
@@ -333,29 +334,21 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
|
||||
if(!dir[1])
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
|
||||
|
||||
#ifdef O_BINARY
|
||||
#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
|
||||
#else
|
||||
#define MODE_DEFAULT O_WRONLY|O_CREAT
|
||||
#endif
|
||||
|
||||
if(data->state.resume_from)
|
||||
fp = fopen( file->path, "ab" );
|
||||
else {
|
||||
int fd;
|
||||
mode = MODE_DEFAULT|O_APPEND;
|
||||
else
|
||||
mode = MODE_DEFAULT|O_TRUNC;
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
|
||||
conn->data->set.new_file_perms);
|
||||
#else
|
||||
fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC,
|
||||
conn->data->set.new_file_perms);
|
||||
#endif
|
||||
if(fd < 0) {
|
||||
failf(data, "Can't open %s for writing", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
fp = fopen(file->path, "wb");
|
||||
}
|
||||
|
||||
if(!fp) {
|
||||
fd = open(file->path, mode, conn->data->set.new_file_perms);
|
||||
if(fd < 0) {
|
||||
failf(data, "Can't open %s for writing", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
@@ -366,8 +359,8 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
|
||||
/* treat the negative resume offset value as the case of "-" */
|
||||
if(data->state.resume_from < 0) {
|
||||
if(fstat(fileno(fp), &file_stat)) {
|
||||
fclose(fp);
|
||||
if(fstat(fd, &file_stat)) {
|
||||
close(fd);
|
||||
failf(data, "Can't get the size of %s", file->path);
|
||||
return CURLE_WRITE_ERROR;
|
||||
}
|
||||
@@ -403,7 +396,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
buf2 = buf;
|
||||
|
||||
/* write the data to the target */
|
||||
nwrite = fwrite(buf2, 1, nread, fp);
|
||||
nwrite = write(fd, buf2, nread);
|
||||
if(nwrite != nread) {
|
||||
res = CURLE_SEND_ERROR;
|
||||
break;
|
||||
@@ -421,7 +414,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
if(!res && Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
fclose(fp);
|
||||
close(fd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
114
lib/ftp.c
114
lib/ftp.c
@@ -351,6 +351,22 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
|
||||
conn->sock[SECONDARYSOCKET] = s;
|
||||
curlx_nonblock(s, TRUE); /* enable non-blocking */
|
||||
conn->sock_accepted[SECONDARYSOCKET] = TRUE;
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
int error = 0;
|
||||
|
||||
/* activate callback for setting socket options */
|
||||
error = data->set.fsockopt(data->set.sockopt_client,
|
||||
s,
|
||||
CURLSOCKTYPE_ACCEPT);
|
||||
|
||||
if(error) {
|
||||
Curl_closesocket(conn, s); /* close the socket and bail out */
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
||||
}
|
||||
@@ -616,8 +632,8 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
size_t *size) /* size of the response */
|
||||
{
|
||||
struct connectdata *conn = pp->conn;
|
||||
#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI)
|
||||
struct SessionHandle *data = conn->data;
|
||||
#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI)
|
||||
char * const buf = data->state.buffer;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
@@ -645,16 +661,23 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
#endif
|
||||
|
||||
/* store the latest code for later retrieval */
|
||||
conn->data->info.httpcode=code;
|
||||
data->info.httpcode=code;
|
||||
|
||||
if(ftpcode)
|
||||
*ftpcode = code;
|
||||
|
||||
if(421 == code)
|
||||
if(421 == code) {
|
||||
/* 421 means "Service not available, closing control connection." and FTP
|
||||
* servers use it to signal that idle session timeout has been exceeded.
|
||||
* If we ignored the response, it could end up hanging in some cases. */
|
||||
* If we ignored the response, it could end up hanging in some cases.
|
||||
*
|
||||
* This response code can come at any point so having it treated
|
||||
* generically is a good idea.
|
||||
*/
|
||||
infof(data, "We got a 421 - timeout!\n");
|
||||
state(conn, FTP_STOP);
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1777,6 +1800,23 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
|
||||
problems */
|
||||
static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
infof(conn->data, "got positive EPSV response, but can't connect. "
|
||||
"Disabling EPSV\n");
|
||||
/* disable it for next transfer */
|
||||
conn->bits.ftp_use_epsv = FALSE;
|
||||
conn->data->state.errorbuf = FALSE; /* allow error message to get
|
||||
rewritten */
|
||||
PPSENDF(&conn->proto.ftpc.pp, "PASV", NULL);
|
||||
conn->proto.ftpc.count1++;
|
||||
/* remain in the FTP_PASV state */
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
int ftpcode)
|
||||
{
|
||||
@@ -1959,20 +1999,12 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
|
||||
if(result && ftpc->count1 == 0 && ftpcode == 229) {
|
||||
infof(data, "got positive EPSV response, but can't connect. "
|
||||
"Disabling EPSV\n");
|
||||
/* disable it for next transfer */
|
||||
conn->bits.ftp_use_epsv = FALSE;
|
||||
data->state.errorbuf = FALSE; /* allow error message to get rewritten */
|
||||
PPSENDF(&ftpc->pp, "PASV", NULL);
|
||||
ftpc->count1++;
|
||||
/* remain in the FTP_PASV state */
|
||||
return result;
|
||||
}
|
||||
if(result) {
|
||||
if(ftpc->count1 == 0 && ftpcode == 229)
|
||||
return ftp_epsv_disable(conn);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
|
||||
|
||||
@@ -2012,8 +2044,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
if(result)
|
||||
if(result) {
|
||||
if(ftpc->count1 == 0 && ftpcode == 229)
|
||||
return ftp_epsv_disable(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||
@@ -2378,6 +2413,7 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
|
||||
if(ftpcode>=400) {
|
||||
failf(data, "Failed FTP upload: %0d", ftpcode);
|
||||
state(conn, FTP_STOP);
|
||||
/* oops, we never close the sockets! */
|
||||
return CURLE_UPLOAD_FAILED;
|
||||
}
|
||||
@@ -2395,9 +2431,6 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3647,6 +3680,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
|
||||
/* the ftp struct is inited in ftp_connect() */
|
||||
struct FTP *ftp = data->state.proto.ftp;
|
||||
|
||||
*complete = FALSE;
|
||||
|
||||
/* if the second connection isn't done yet, wait for it */
|
||||
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
|
||||
result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
|
||||
@@ -3659,6 +3694,18 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
|
||||
return result;
|
||||
}
|
||||
|
||||
if((data->state.used_interface == Curl_if_multi) &&
|
||||
ftpc->state) {
|
||||
/* multi interface and already in a state so skip the intial commands.
|
||||
They are only done to kickstart the do_more state */
|
||||
result = ftp_multi_statemach(conn, complete);
|
||||
|
||||
/* if we got an error or if we don't wait for a data connection return
|
||||
immediately */
|
||||
if(result || (ftpc->wait_data_conn != TRUE))
|
||||
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 */
|
||||
@@ -3712,7 +3759,13 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = ftp_easy_statemach(conn);
|
||||
if(data->state.used_interface == Curl_if_multi) {
|
||||
result = ftp_multi_statemach(conn, complete);
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
result = ftp_easy_statemach(conn);
|
||||
}
|
||||
|
||||
if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
|
||||
@@ -4386,20 +4439,21 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
bool connected)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct FTP *ftp = conn->data->state.proto.ftp;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
if(connected) {
|
||||
bool completed;
|
||||
result = ftp_do_more(conn, &completed);
|
||||
}
|
||||
CURLcode 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 */
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
return result;
|
||||
if(result) {
|
||||
if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
|
||||
/* close the second socket if it was created already */
|
||||
Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if(ftp->transfer != FTPTRANSFER_BODY)
|
||||
@@ -4411,7 +4465,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
|
||||
ftpc->ctl_valid = TRUE; /* seems good */
|
||||
|
||||
return result;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
|
||||
@@ -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
|
||||
@@ -70,10 +70,10 @@
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
42
lib/gtls.c
42
lib/gtls.c
@@ -34,7 +34,10 @@
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
#ifndef USE_GNUTLS_NETTLE
|
||||
#ifdef USE_GNUTLS_NETTLE
|
||||
#include <gnutls/crypto.h>
|
||||
#include <nettle/md5.h>
|
||||
#else
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
|
||||
@@ -296,18 +299,41 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
connssl->connecting_state =
|
||||
gnutls_record_get_direction(session)?
|
||||
ssl_connect_2_writing:ssl_connect_2_reading;
|
||||
continue;
|
||||
if(nonblocking)
|
||||
return CURLE_OK;
|
||||
}
|
||||
else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
|
||||
const char *strerr = NULL;
|
||||
|
||||
if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
|
||||
int alert = gnutls_alert_get(session);
|
||||
strerr = gnutls_alert_get_name(alert);
|
||||
}
|
||||
|
||||
if(strerr == NULL)
|
||||
strerr = gnutls_strerror(rc);
|
||||
|
||||
failf(data, "gnutls_handshake() warning: %s", strerr);
|
||||
}
|
||||
else if(rc < 0) {
|
||||
failf(data, "gnutls_handshake() failed: %s", gnutls_strerror(rc));
|
||||
const char *strerr = NULL;
|
||||
|
||||
if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
|
||||
int alert = gnutls_alert_get(session);
|
||||
strerr = gnutls_alert_get_name(alert);
|
||||
}
|
||||
|
||||
if(strerr == NULL)
|
||||
strerr = gnutls_strerror(rc);
|
||||
|
||||
failf(data, "gnutls_handshake() failed: %s", strerr);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
else {
|
||||
/* Reset our connect state machine */
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Reset our connect state machine */
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,7 +681,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
|
||||
|
||||
if(!rc) {
|
||||
if(data->set.ssl.verifyhost > 1) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
failf(data, "SSL: certificate subject name (%s) does not match "
|
||||
"target host name '%s'", certbuf, conn->host.dispname);
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
|
||||
96
lib/hostcheck.c
Normal file
96
lib/hostcheck.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 "setup.h"
|
||||
|
||||
#if defined(USE_SSLEAY) || defined(USE_AXTLS)
|
||||
/* these two backends use functions from this file */
|
||||
|
||||
#include "hostcheck.h"
|
||||
#include "rawstr.h"
|
||||
|
||||
/*
|
||||
* Match a hostname against a wildcard pattern.
|
||||
* E.g.
|
||||
* "foo.host.com" matches "*.host.com".
|
||||
*
|
||||
* We use the matching rule described in RFC6125, section 6.4.3.
|
||||
* http://tools.ietf.org/html/rfc6125#section-6.4.3
|
||||
*/
|
||||
|
||||
static int hostmatch(const char *hostname, const char *pattern)
|
||||
{
|
||||
const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
|
||||
int wildcard_enabled;
|
||||
size_t prefixlen, suffixlen;
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* We require at least 2 dots in pattern to avoid too wide wildcard
|
||||
match. */
|
||||
wildcard_enabled = 1;
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end))
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
label of the hostname is at least as large as the left-most label
|
||||
of the pattern. */
|
||||
if(hostname_label_end - hostname < pattern_label_end - pattern)
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
}
|
||||
|
||||
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
{
|
||||
if(!match_pattern || !*match_pattern ||
|
||||
!hostname || !*hostname) /* sanity check */
|
||||
return 0;
|
||||
|
||||
if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
|
||||
return 1;
|
||||
|
||||
if(hostmatch(hostname,match_pattern) == CURL_HOST_MATCH)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SSLEAY or AXTLS */
|
||||
31
lib/hostcheck.h
Normal file
31
lib/hostcheck.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef __HOSTCHECK_H
|
||||
#define __HOSTCHECK_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* 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 <curl/curl.h>
|
||||
|
||||
#define CURL_HOST_NOMATCH 0
|
||||
#define CURL_HOST_MATCH 1
|
||||
int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -740,14 +740,18 @@ static int hostcache_inuse(void *data, void *hc)
|
||||
return 1; /* free all entries */
|
||||
}
|
||||
|
||||
void Curl_hostcache_destroy(struct SessionHandle *data)
|
||||
void Curl_hostcache_clean(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);
|
||||
}
|
||||
|
||||
void Curl_hostcache_destroy(struct SessionHandle *data)
|
||||
{
|
||||
Curl_hostcache_clean(data);
|
||||
Curl_hash_destroy(data->dns.hostcache);
|
||||
data->dns.hostcachetype = HCACHE_NONE;
|
||||
data->dns.hostcache = NULL;
|
||||
|
||||
10
lib/hostip.h
10
lib/hostip.h
@@ -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
|
||||
@@ -200,11 +200,19 @@ extern sigjmp_buf curl_jmpenv;
|
||||
*/
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
|
||||
|
||||
/*
|
||||
* Clean off entries from the cache
|
||||
*/
|
||||
void Curl_hostcache_clean(struct SessionHandle *data);
|
||||
|
||||
/*
|
||||
* Destroy the hostcache of this handle.
|
||||
*/
|
||||
void Curl_hostcache_destroy(struct SessionHandle *data);
|
||||
|
||||
/*
|
||||
* Populate the cache with specified entries from CURLOPT_RESOLVE.
|
||||
*/
|
||||
CURLcode Curl_loadhostpairs(struct SessionHandle *data);
|
||||
|
||||
#endif /* HEADER_CURL_HOSTIP_H */
|
||||
|
||||
@@ -387,7 +387,8 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
(data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->ntlm.state != NTLMSTATE_NONE)) {
|
||||
(conn->ntlm.state != NTLMSTATE_NONE) ||
|
||||
(conn->proxyntlm.state != NTLMSTATE_NONE)) {
|
||||
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
|
||||
data left to send, keep on sending. */
|
||||
|
||||
@@ -407,7 +408,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
" bytes\n", (curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
|
||||
/* This is not NTLM or NTLM with many bytes left to send: close
|
||||
/* This is not NTLM or many bytes left to send: close
|
||||
*/
|
||||
conn->bits.close = TRUE;
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
@@ -280,7 +280,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
unsigned char *md5this;
|
||||
unsigned char *ha1;
|
||||
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
||||
char cnoncebuf[7];
|
||||
char cnoncebuf[33];
|
||||
char *cnonce = NULL;
|
||||
size_t cnonce_sz = 0;
|
||||
char *tmp = NULL;
|
||||
@@ -344,7 +344,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
if(!d->cnonce) {
|
||||
/* Generate a cnonce */
|
||||
now = Curl_tvnow();
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", (long)now.tv_sec);
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%32ld",
|
||||
(long)now.tv_sec + now.tv_usec);
|
||||
|
||||
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||
&cnonce, &cnonce_sz);
|
||||
|
||||
@@ -195,7 +195,6 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", header)) {
|
||||
ASN1_OBJECT * object = NULL;
|
||||
int rc = 1;
|
||||
unsigned char * spnegoToken = NULL;
|
||||
size_t spnegoTokenLength = 0;
|
||||
unsigned char * mechToken = NULL;
|
||||
@@ -280,7 +279,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", neg_ctx->protocol)) {
|
||||
ASN1_OBJECT * object = NULL;
|
||||
int rc = 1;
|
||||
unsigned char * spnegoToken = NULL;
|
||||
size_t spnegoTokenLength = 0;
|
||||
unsigned char * responseToken = NULL;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
#include "curlx.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef WANT_IDN_PROTOTYPES
|
||||
WINBASEAPI int WINAPI IdnToAscii(DWORD, const WCHAR *, int, WCHAR *, int);
|
||||
WINBASEAPI int WINAPI IdnToUnicode(DWORD, const WCHAR *, int, WCHAR *, int);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "sendf.h"
|
||||
#include "krb4.h"
|
||||
#include "curl_memory.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -103,7 +104,7 @@ krb5_decode(void *app_data, void *buf, int len,
|
||||
}
|
||||
|
||||
memcpy(buf, dec.value, dec.length);
|
||||
len = dec.length;
|
||||
len = curlx_uztosi(dec.length);
|
||||
gss_release_buffer(&min, &dec);
|
||||
|
||||
return len;
|
||||
@@ -151,7 +152,7 @@ krb5_encode(void *app_data, const void *from, int length, int level, void **to,
|
||||
if(!*to)
|
||||
return -1;
|
||||
memcpy(*to, enc.value, enc.length);
|
||||
len = enc.length;
|
||||
len = curlx_uztosi(enc.length);
|
||||
gss_release_buffer(&min, &enc);
|
||||
return len;
|
||||
}
|
||||
|
||||
73
lib/md5.c
73
lib/md5.c
@@ -28,9 +28,13 @@
|
||||
#include "curl_hmac.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#ifdef USE_GNUTLS_NETTLE
|
||||
#include "curl_memory.h"
|
||||
|
||||
#if defined(USE_GNUTLS_NETTLE)
|
||||
|
||||
#include <nettle/md5.h>
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct md5_ctx MD5_CTX;
|
||||
|
||||
@@ -50,11 +54,12 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
{
|
||||
md5_digest(ctx, 16, digest);
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef USE_GNUTLS
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
#include <gcrypt.h>
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef gcry_md_hd_t MD5_CTX;
|
||||
|
||||
@@ -76,9 +81,7 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
gcry_md_close(*ctx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
#elif defined(USE_SSLEAY)
|
||||
/* When OpenSSL is available we use the MD5-function from OpenSSL */
|
||||
|
||||
# ifdef USE_OPENSSL
|
||||
@@ -87,8 +90,55 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
|
||||
# include <md5.h>
|
||||
# endif
|
||||
|
||||
#else /* USE_SSLEAY */
|
||||
/* When OpenSSL is not available we use this code segment */
|
||||
#elif defined(__MAC_10_4) || defined(__IPHONE_5_0)
|
||||
|
||||
/* For Apple operating systems: CommonCrypto has the functions we need.
|
||||
The library's headers are even backward-compatible with OpenSSL's
|
||||
headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
|
||||
|
||||
These functions are available on Tiger and later, as well as iOS 5.0
|
||||
and later. If you're building for an older cat, well, sorry. */
|
||||
# define COMMON_DIGEST_FOR_OPENSSL
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
#include <wincrypt.h>
|
||||
|
||||
typedef struct {
|
||||
HCRYPTPROV hCryptProv;
|
||||
HCRYPTHASH hHash;
|
||||
} MD5_CTX;
|
||||
|
||||
static void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
|
||||
}
|
||||
}
|
||||
|
||||
static void MD5_Update(MD5_CTX *ctx,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
|
||||
}
|
||||
|
||||
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
|
||||
{
|
||||
unsigned long length;
|
||||
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
|
||||
if(length == 16)
|
||||
CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
|
||||
if(ctx->hHash)
|
||||
CryptDestroyHash(ctx->hHash);
|
||||
if(ctx->hCryptProv)
|
||||
CryptReleaseContext(ctx->hCryptProv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* When no other crypto library is available we use this code segment */
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
@@ -390,11 +440,10 @@ static void Decode (UINT4 *output,
|
||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
#endif /* USE_SSLEAY */
|
||||
#endif /* CRYPTO LIBS */
|
||||
|
||||
#endif /* USE_GNUTLS */
|
||||
|
||||
#endif /* USE_GNUTLS_NETTLE */
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
const HMAC_params Curl_HMAC_MD5[] = {
|
||||
{
|
||||
|
||||
@@ -6,7 +6,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
|
||||
@@ -123,6 +123,8 @@ print "Processing '$txt' ...\n" if (!$opt_q);
|
||||
my $caname;
|
||||
my $certnum = 0;
|
||||
my $skipnum = 0;
|
||||
my $start_of_cert = 0;
|
||||
|
||||
open(TXT,"$txt") or die "Couldn't open $txt: $!";
|
||||
while (<TXT>) {
|
||||
if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) {
|
||||
@@ -143,11 +145,16 @@ while (<TXT>) {
|
||||
print CRT "# $1\n";
|
||||
close(CRT) or die "Couldn't close $crt: $!";
|
||||
}
|
||||
if (/^CKA_LABEL\s+[A-Z0-9]+\s+\"(.*)\"/) {
|
||||
|
||||
# this is a match for the start of a certificate
|
||||
if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
|
||||
$start_of_cert = 1
|
||||
}
|
||||
if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) {
|
||||
$caname = $1;
|
||||
}
|
||||
my $untrusted = 0;
|
||||
if (/^CKA_VALUE MULTILINE_OCTAL/) {
|
||||
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
|
||||
my $data;
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
@@ -158,10 +165,18 @@ while (<TXT>) {
|
||||
$data .= chr(oct);
|
||||
}
|
||||
}
|
||||
# scan forwards until the trust part
|
||||
while (<TXT>) {
|
||||
last if (/^#$/);
|
||||
$untrusted = 1 if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/
|
||||
or /^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/);
|
||||
last if (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/);
|
||||
chomp;
|
||||
}
|
||||
# now scan the trust part for untrusted certs
|
||||
while (<TXT>) {
|
||||
last if (/^#/);
|
||||
if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/
|
||||
or /^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/) {
|
||||
$untrusted = 1;
|
||||
}
|
||||
}
|
||||
if ($untrusted) {
|
||||
$skipnum ++;
|
||||
@@ -183,6 +198,7 @@ while (<TXT>) {
|
||||
}
|
||||
print "Parsing: $caname\n" if ($opt_v);
|
||||
$certnum ++;
|
||||
$start_of_cert = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
118
lib/multi.c
118
lib/multi.c
@@ -43,6 +43,7 @@
|
||||
#include "http.h"
|
||||
#include "select.h"
|
||||
#include "warnless.h"
|
||||
#include "speedcheck.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -941,6 +942,100 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_wait(CURLM *multi_handle,
|
||||
struct curl_waitfd extra_fds[],
|
||||
unsigned int extra_nfds,
|
||||
int timeout_ms,
|
||||
int *ret)
|
||||
{
|
||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||
struct Curl_one_easy *easy;
|
||||
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
|
||||
int bitmap;
|
||||
unsigned int i;
|
||||
unsigned int nfds = extra_nfds;
|
||||
struct pollfd *ufds;
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
|
||||
/* Count up how many fds we have from the multi handle */
|
||||
easy=multi->easy.next;
|
||||
while(easy != &multi->easy) {
|
||||
bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
|
||||
|
||||
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
++nfds;
|
||||
s = sockbunch[i];
|
||||
}
|
||||
if(bitmap & GETSOCK_WRITESOCK(i)) {
|
||||
++nfds;
|
||||
s = sockbunch[i];
|
||||
}
|
||||
if(s == CURL_SOCKET_BAD) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
easy = easy->next; /* check next handle */
|
||||
}
|
||||
|
||||
ufds = (struct pollfd *)malloc(nfds * sizeof(struct pollfd));
|
||||
nfds = 0;
|
||||
|
||||
/* Add the curl handles to our pollfds first */
|
||||
easy=multi->easy.next;
|
||||
while(easy != &multi->easy) {
|
||||
bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
|
||||
|
||||
for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
|
||||
curl_socket_t s = CURL_SOCKET_BAD;
|
||||
|
||||
if(bitmap & GETSOCK_READSOCK(i)) {
|
||||
ufds[nfds].fd = sockbunch[i];
|
||||
ufds[nfds].events = POLLIN;
|
||||
++nfds;
|
||||
s = sockbunch[i];
|
||||
}
|
||||
if(bitmap & GETSOCK_WRITESOCK(i)) {
|
||||
ufds[nfds].fd = sockbunch[i];
|
||||
ufds[nfds].events = POLLOUT;
|
||||
++nfds;
|
||||
s = sockbunch[i];
|
||||
}
|
||||
if(s == CURL_SOCKET_BAD) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
easy = easy->next; /* check next handle */
|
||||
}
|
||||
|
||||
/* Add external file descriptions from poll-like struct curl_waitfd */
|
||||
for(i = 0; i < extra_nfds; i++) {
|
||||
ufds[nfds].fd = extra_fds[i].fd;
|
||||
ufds[nfds].events = (short) (
|
||||
((extra_fds[i].events & CURL_WAIT_POLLIN) ? POLLIN : 0) |
|
||||
((extra_fds[i].events & CURL_WAIT_POLLPRI) ? POLLPRI : 0) |
|
||||
((extra_fds[i].events & CURL_WAIT_POLLOUT) ? POLLOUT : 0) );
|
||||
++nfds;
|
||||
}
|
||||
|
||||
if(nfds)
|
||||
/* wait... */
|
||||
i = Curl_poll(ufds, nfds, timeout_ms);
|
||||
else
|
||||
i = 0;
|
||||
|
||||
free(ufds);
|
||||
if(ret)
|
||||
*ret = i;
|
||||
return CURLM_OK;
|
||||
}
|
||||
|
||||
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
struct timeval now,
|
||||
struct Curl_one_easy *easy)
|
||||
@@ -1428,7 +1523,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
|
||||
/* if both rates are within spec, resume transfer */
|
||||
Curl_pgrsUpdate(easy->easy_conn);
|
||||
if(Curl_pgrsUpdate(easy->easy_conn))
|
||||
easy->result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
easy->result = Curl_speedcheck(data, now);
|
||||
|
||||
if(( (data->set.max_send_speed == 0) ||
|
||||
(data->progress.ulspeed < data->set.max_send_speed )) &&
|
||||
( (data->set.max_recv_speed == 0) ||
|
||||
@@ -1690,12 +1789,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
} WHILE_FALSE; /* just to break out from! */
|
||||
|
||||
if(CURLM_STATE_COMPLETED == easy->state) {
|
||||
if(data->dns.hostcachetype == HCACHE_MULTI) {
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
data->dns.hostcache = NULL;
|
||||
data->dns.hostcachetype = HCACHE_NONE;
|
||||
}
|
||||
|
||||
/* now fill in the Curl_message with this info */
|
||||
msg = &easy->msg;
|
||||
|
||||
@@ -1812,9 +1905,6 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
cl= n;
|
||||
}
|
||||
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
multi->hostcache = NULL;
|
||||
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
multi->sockhash = NULL;
|
||||
|
||||
@@ -1831,6 +1921,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
nexteasy=easy->next;
|
||||
if(easy->easy_handle->dns.hostcachetype == HCACHE_MULTI) {
|
||||
/* clear out the usage of the shared DNS cache */
|
||||
Curl_hostcache_clean(easy->easy_handle);
|
||||
easy->easy_handle->dns.hostcache = NULL;
|
||||
easy->easy_handle->dns.hostcachetype = HCACHE_NONE;
|
||||
}
|
||||
@@ -1844,6 +1935,9 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
easy = nexteasy;
|
||||
}
|
||||
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
multi->hostcache = NULL;
|
||||
|
||||
free(multi);
|
||||
|
||||
return CURLM_OK;
|
||||
@@ -2079,14 +2173,14 @@ static CURLMcode add_next_timeout(struct timeval now,
|
||||
break;
|
||||
e = n;
|
||||
}
|
||||
if(!list->size) {
|
||||
e = list->head;
|
||||
if(!e) {
|
||||
/* clear the expire times within the handles that we remove from the
|
||||
splay tree */
|
||||
tv->tv_sec = 0;
|
||||
tv->tv_usec = 0;
|
||||
}
|
||||
else {
|
||||
e = list->head;
|
||||
/* copy the first entry to 'tv' */
|
||||
memcpy(tv, e->ptr, sizeof(*tv));
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -24,12 +24,16 @@
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "non-ascii.h"
|
||||
#include "formdata.h"
|
||||
#include "sendf.h"
|
||||
#include "urldata.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
#include <iconv.h>
|
||||
|
||||
150
lib/nss.c
150
lib/nss.c
@@ -89,7 +89,6 @@ volatile int initialized = 0;
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int num;
|
||||
PRInt32 version; /* protocol version valid for this cipher */
|
||||
} cipher_s;
|
||||
|
||||
#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \
|
||||
@@ -101,65 +100,63 @@ typedef struct {
|
||||
|
||||
#define CERT_NewTempCertificate __CERT_NewTempCertificate
|
||||
|
||||
enum sslversion { SSL2 = 1, SSL3 = 2, TLS = 4 };
|
||||
|
||||
#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
|
||||
static const cipher_s cipherlist[] = {
|
||||
/* SSL2 cipher suites */
|
||||
{"rc4", SSL_EN_RC4_128_WITH_MD5, SSL2},
|
||||
{"rc4-md5", SSL_EN_RC4_128_WITH_MD5, SSL2},
|
||||
{"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL2},
|
||||
{"rc2", SSL_EN_RC2_128_CBC_WITH_MD5, SSL2},
|
||||
{"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL2},
|
||||
{"des", SSL_EN_DES_64_CBC_WITH_MD5, SSL2},
|
||||
{"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL2},
|
||||
{"rc4", SSL_EN_RC4_128_WITH_MD5},
|
||||
{"rc4-md5", SSL_EN_RC4_128_WITH_MD5},
|
||||
{"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5},
|
||||
{"rc2", SSL_EN_RC2_128_CBC_WITH_MD5},
|
||||
{"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
|
||||
{"des", SSL_EN_DES_64_CBC_WITH_MD5},
|
||||
{"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
|
||||
/* SSL3/TLS cipher suites */
|
||||
{"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, SSL3 | TLS},
|
||||
{"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, SSL3 | TLS},
|
||||
{"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL3 | TLS},
|
||||
{"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA, SSL3 | TLS},
|
||||
{"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL3 | TLS},
|
||||
{"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL3 | TLS},
|
||||
{"rsa_null_md5", SSL_RSA_WITH_NULL_MD5, SSL3 | TLS},
|
||||
{"rsa_null_sha", SSL_RSA_WITH_NULL_SHA, SSL3 | TLS},
|
||||
{"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL3 | TLS},
|
||||
{"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL3 | TLS},
|
||||
{"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL3 | TLS},
|
||||
{"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL3 | TLS},
|
||||
{"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL3 | TLS},
|
||||
{"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5},
|
||||
{"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA},
|
||||
{"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA},
|
||||
{"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5},
|
||||
{"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
|
||||
{"rsa_null_md5", SSL_RSA_WITH_NULL_MD5},
|
||||
{"rsa_null_sha", SSL_RSA_WITH_NULL_SHA},
|
||||
{"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
|
||||
{"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA},
|
||||
{"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
|
||||
{"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
|
||||
{"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
|
||||
/* TLS 1.0: Exportable 56-bit Cipher Suites. */
|
||||
{"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL3 | TLS},
|
||||
{"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL3 | TLS},
|
||||
{"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
|
||||
{"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
|
||||
/* AES ciphers. */
|
||||
{"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, SSL3 | TLS},
|
||||
{"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, SSL3 | TLS},
|
||||
{"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA},
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
/* ECC ciphers. */
|
||||
{"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS},
|
||||
{"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS},
|
||||
{"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS},
|
||||
{"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS},
|
||||
{"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS},
|
||||
{"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLS},
|
||||
{"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS},
|
||||
{"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS},
|
||||
{"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS},
|
||||
{"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS},
|
||||
{"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA, TLS},
|
||||
{"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS},
|
||||
{"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS},
|
||||
{"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS},
|
||||
{"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS},
|
||||
{"echde_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA, TLS},
|
||||
{"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS},
|
||||
{"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS},
|
||||
{"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS},
|
||||
{"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS},
|
||||
{"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA, TLS},
|
||||
{"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA, TLS},
|
||||
{"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, TLS},
|
||||
{"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS},
|
||||
{"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA, TLS},
|
||||
{"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA},
|
||||
{"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
|
||||
{"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
|
||||
{"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
{"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA},
|
||||
{"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
|
||||
{"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
|
||||
{"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
{"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA},
|
||||
{"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA},
|
||||
{"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"echde_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA},
|
||||
{"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||
{"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA},
|
||||
{"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA},
|
||||
{"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
|
||||
{"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -248,7 +245,7 @@ static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
|
||||
for(i=0; i<NUM_OF_CIPHERS; i++) {
|
||||
rv = SSL_CipherPrefSet(model, cipherlist[i].num, cipher_state[i]);
|
||||
if(rv != SECSuccess) {
|
||||
failf(data, "Unknown cipher in cipher list");
|
||||
failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
@@ -1084,17 +1081,32 @@ int Curl_nss_close_all(struct SessionHandle *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return true if NSS can provide error code (and possibly msg) for the
|
||||
error */
|
||||
static bool is_nss_error(CURLcode err)
|
||||
{
|
||||
switch(err) {
|
||||
case CURLE_PEER_FAILED_VERIFICATION:
|
||||
case CURLE_SSL_CACERT:
|
||||
case CURLE_SSL_CACERT_BADFILE:
|
||||
case CURLE_SSL_CERTPROBLEM:
|
||||
case CURLE_SSL_CONNECT_ERROR:
|
||||
case CURLE_SSL_CRL_BADFILE:
|
||||
case CURLE_SSL_ISSUER_ERROR:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* return true if the given error code is related to a client certificate */
|
||||
static bool is_cc_error(PRInt32 err)
|
||||
{
|
||||
switch(err) {
|
||||
case SSL_ERROR_BAD_CERT_ALERT:
|
||||
return true;
|
||||
|
||||
case SSL_ERROR_REVOKED_CERT_ALERT:
|
||||
return true;
|
||||
|
||||
case SSL_ERROR_EXPIRED_CERT_ALERT:
|
||||
case SSL_ERROR_REVOKED_CERT_ALERT:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -1159,7 +1171,7 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
|
||||
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
PRInt32 err;
|
||||
PRErrorCode err = 0;
|
||||
PRFileDesc *model = NULL;
|
||||
PRBool ssl2 = PR_FALSE;
|
||||
PRBool ssl3 = PR_FALSE;
|
||||
@@ -1304,8 +1316,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
|
||||
infof(data, "warning: ignoring value of ssl.verifyhost\n");
|
||||
else if(data->set.ssl.verifyhost == 1)
|
||||
infof(data, "warning: ignoring unsupported value (1) of ssl.verifyhost\n");
|
||||
|
||||
/* bypass the default SSL_AuthCertificate() hook in case we do not want to
|
||||
* verify peer */
|
||||
@@ -1388,6 +1398,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
time_left = Curl_timeleft(data, NULL, TRUE);
|
||||
if(time_left < 0L) {
|
||||
failf(data, "timed out before SSL handshake");
|
||||
curlerr = CURLE_OPERATION_TIMEDOUT;
|
||||
goto error;
|
||||
}
|
||||
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
|
||||
@@ -1432,15 +1443,18 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
/* reset the flag to avoid an infinite loop */
|
||||
data->state.ssl_connect_retry = FALSE;
|
||||
|
||||
err = PR_GetError();
|
||||
if(is_cc_error(err))
|
||||
curlerr = CURLE_SSL_CERTPROBLEM;
|
||||
if(is_nss_error(curlerr)) {
|
||||
/* read NSPR error code */
|
||||
err = PR_GetError();
|
||||
if(is_cc_error(err))
|
||||
curlerr = CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
/* print the error number and error string */
|
||||
infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
|
||||
/* print the error number and error string */
|
||||
infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
|
||||
|
||||
/* print a human-readable message describing the error if available */
|
||||
nss_print_error_message(data, err);
|
||||
/* print a human-readable message describing the error if available */
|
||||
nss_print_error_message(data, err);
|
||||
}
|
||||
|
||||
if(model)
|
||||
PR_Close(model);
|
||||
|
||||
116
lib/nwlib.c
116
lib/nwlib.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, 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
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <nks/thread.h>
|
||||
#include <nks/synch.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -55,9 +58,9 @@ rtag_t gAllocTag = (rtag_t) NULL;
|
||||
NXMutex_t *gLibLock = (NXMutex_t *) NULL;
|
||||
|
||||
/* internal library function prototypes... */
|
||||
int DisposeLibraryData ( void * );
|
||||
void DisposeThreadData ( void * );
|
||||
int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
|
||||
int DisposeLibraryData( void * );
|
||||
void DisposeThreadData( void * );
|
||||
int GetOrSetUpData( int id, libdata_t **data, libthreaddata_t **threaddata );
|
||||
|
||||
|
||||
int _NonAppStart( void *NLMHandle,
|
||||
@@ -90,12 +93,12 @@ int _NonAppStart( void *NLMHandle,
|
||||
#pragma unused(messages)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Here we process our command line, post errors (to the error screen),
|
||||
** perform initializations and anything else we need to do before being able
|
||||
** to accept calls into us. If we succeed, we return non-zero and the NetWare
|
||||
** Loader will leave us up, otherwise we fail to load and get dumped.
|
||||
*/
|
||||
/*
|
||||
* Here we process our command line, post errors (to the error screen),
|
||||
* perform initializations and anything else we need to do before being able
|
||||
* to accept calls into us. If we succeed, we return non-zero and the NetWare
|
||||
* Loader will leave us up, otherwise we fail to load and get dumped.
|
||||
*/
|
||||
gAllocTag = AllocateResourceTag(NLMHandle,
|
||||
"<library-name> memory allocations",
|
||||
AllocSignature);
|
||||
@@ -126,9 +129,9 @@ int _NonAppStart( void *NLMHandle,
|
||||
}
|
||||
|
||||
/*
|
||||
** Here we clean up any resources we allocated. Resource tags is a big part
|
||||
** of what we created, but NetWare doesn't ask us to free those.
|
||||
*/
|
||||
* Here we clean up any resources we allocated. Resource tags is a big part
|
||||
* of what we created, but NetWare doesn't ask us to free those.
|
||||
*/
|
||||
void _NonAppStop( void )
|
||||
{
|
||||
(void) unregister_library(gLibId);
|
||||
@@ -136,16 +139,16 @@ void _NonAppStop( void )
|
||||
}
|
||||
|
||||
/*
|
||||
** This function cannot be the first in the file for if the file is linked
|
||||
** first, then the check-unload function's offset will be nlmname.nlm+0
|
||||
** which is how to tell that there isn't one. When the check function is
|
||||
** first in the linked objects, it is ambiguous. For this reason, we will
|
||||
** put it inside this file after the stop function.
|
||||
**
|
||||
** Here we check to see if it's alright to ourselves to be unloaded. If not,
|
||||
** we return a non-zero value. Right now, there isn't any reason not to allow
|
||||
** it.
|
||||
*/
|
||||
* This function cannot be the first in the file for if the file is linked
|
||||
* first, then the check-unload function's offset will be nlmname.nlm+0
|
||||
* which is how to tell that there isn't one. When the check function is
|
||||
* first in the linked objects, it is ambiguous. For this reason, we will
|
||||
* put it inside this file after the stop function.
|
||||
*
|
||||
* Here we check to see if it's alright to ourselves to be unloaded. If not,
|
||||
* we return a non-zero value. Right now, there isn't any reason not to allow
|
||||
* it.
|
||||
*/
|
||||
int _NonAppCheckUnload( void )
|
||||
{
|
||||
return 0;
|
||||
@@ -163,22 +166,22 @@ int GetOrSetUpData(int id, libdata_t **appData,
|
||||
err = 0;
|
||||
thread_data = (libthreaddata_t *) NULL;
|
||||
|
||||
/*
|
||||
** Attempt to get our data for the application calling us. This is where we
|
||||
** store whatever application-specific information we need to carry in support
|
||||
** of calling applications.
|
||||
*/
|
||||
/*
|
||||
* Attempt to get our data for the application calling us. This is where we
|
||||
* store whatever application-specific information we need to carry in
|
||||
* support of calling applications.
|
||||
*/
|
||||
app_data = (libdata_t *) get_app_data(id);
|
||||
|
||||
if(!app_data) {
|
||||
/*
|
||||
** This application hasn't called us before; set up application AND per-thread
|
||||
** data. Of course, just in case a thread from this same application is calling
|
||||
** us simultaneously, we better lock our application data-creation mutex. We
|
||||
** also need to recheck for data after we acquire the lock because WE might be
|
||||
** that other thread that was too late to create the data and the first thread
|
||||
** in will have created it.
|
||||
*/
|
||||
/*
|
||||
* This application hasn't called us before; set up application AND
|
||||
* per-thread data. Of course, just in case a thread from this same
|
||||
* application is calling us simultaneously, we better lock our application
|
||||
* data-creation mutex. We also need to recheck for data after we acquire
|
||||
* the lock because WE might be that other thread that was too late to
|
||||
* create the data and the first thread in will have created it.
|
||||
*/
|
||||
NXLock(gLibLock);
|
||||
|
||||
if(!(app_data = (libdata_t *) get_app_data(id))) {
|
||||
@@ -200,13 +203,14 @@ int GetOrSetUpData(int id, libdata_t **appData,
|
||||
}
|
||||
|
||||
if(app_data) {
|
||||
/*
|
||||
** Here we burn in the application data that we were trying to get by calling
|
||||
** get_app_data(). Next time we call the first function, we'll get this data
|
||||
** we're just now setting. We also go on here to establish the per-thread data
|
||||
** for the calling thread, something we'll have to do on each application
|
||||
** thread the first time it calls us.
|
||||
*/
|
||||
/*
|
||||
* Here we burn in the application data that we were trying to get
|
||||
* by calling get_app_data(). Next time we call the first function,
|
||||
* we'll get this data we're just now setting. We also go on here to
|
||||
* establish the per-thread data for the calling thread, something
|
||||
* we'll have to do on each application thread the first time
|
||||
* it calls us.
|
||||
*/
|
||||
err = set_app_data(gLibId, app_data);
|
||||
|
||||
if(err) {
|
||||
@@ -236,13 +240,13 @@ int GetOrSetUpData(int id, libdata_t **appData,
|
||||
if(key != -1 /* couldn't create a key? no thread data */
|
||||
&& !(err = NXKeyGetValue(key, (void **) &thread_data))
|
||||
&& !thread_data) {
|
||||
/*
|
||||
** Allocate the per-thread data for the calling thread. Regardless of whether
|
||||
** there was already application data or not, this may be the first call by a
|
||||
** a new thread. The fact that we allocation 20 bytes on a pointer is not very
|
||||
** important, this just helps to demonstrate that we can have arbitrarily
|
||||
** complex per-thread data.
|
||||
*/
|
||||
/*
|
||||
* Allocate the per-thread data for the calling thread. Regardless of
|
||||
* whether there was already application data or not, this may be the
|
||||
* first call by a new thread. The fact that we allocation 20 bytes on
|
||||
* a pointer is not very important, this just helps to demonstrate that
|
||||
* we can have arbitrarily complex per-thread data.
|
||||
*/
|
||||
thread_data = malloc(sizeof(libthreaddata_t));
|
||||
|
||||
if(thread_data) {
|
||||
@@ -305,13 +309,13 @@ void DisposeThreadData( void *data )
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
/* initialize any globals here... */
|
||||
/* initialize any globals here... */
|
||||
|
||||
/* do this if any global initializing was done
|
||||
SynchronizeStart();
|
||||
*/
|
||||
ExitThread (TSR_THREAD, 0);
|
||||
return 0;
|
||||
/* do this if any global initializing was done
|
||||
SynchronizeStart();
|
||||
*/
|
||||
ExitThread (TSR_THREAD, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
50
lib/nwos.c
50
lib/nwos.c
@@ -28,7 +28,7 @@
|
||||
/* For native LibC-based NLM we need to do nothing. */
|
||||
int netware_init ( void )
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* __NOVELL_LIBC__ */
|
||||
@@ -47,40 +47,40 @@ NETINET_DEFINE_CONTEXT
|
||||
|
||||
int netware_init ( void )
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned int myHandle = GetNLMHandle();
|
||||
/* import UnAugmentAsterisk dynamically for NW4.x compatibility */
|
||||
void (*pUnAugmentAsterisk)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
/* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
|
||||
void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
if(pUnAugmentAsterisk)
|
||||
pUnAugmentAsterisk(1);
|
||||
if(pUseAccurateCaseForPaths)
|
||||
pUseAccurateCaseForPaths(1);
|
||||
UnimportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
/* set long name space */
|
||||
if((SetCurrentNameSpace(4) == 255)) {
|
||||
rc = 1;
|
||||
}
|
||||
if((SetTargetNameSpace(4) == 255)) {
|
||||
rc = rc + 2;
|
||||
}
|
||||
return rc;
|
||||
int rc = 0;
|
||||
unsigned int myHandle = GetNLMHandle();
|
||||
/* import UnAugmentAsterisk dynamically for NW4.x compatibility */
|
||||
void (*pUnAugmentAsterisk)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
/* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
|
||||
void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
|
||||
ImportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
if(pUnAugmentAsterisk)
|
||||
pUnAugmentAsterisk(1);
|
||||
if(pUseAccurateCaseForPaths)
|
||||
pUseAccurateCaseForPaths(1);
|
||||
UnimportSymbol(myHandle, "UnAugmentAsterisk");
|
||||
UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
|
||||
/* set long name space */
|
||||
if((SetCurrentNameSpace(4) == 255)) {
|
||||
rc = 1;
|
||||
}
|
||||
if((SetTargetNameSpace(4) == 255)) {
|
||||
rc = rc + 2;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __init_environment ( void )
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dummy function to satisfy newer prelude */
|
||||
int __deinit_environment ( void )
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __NOVELL_LIBC__ */
|
||||
|
||||
@@ -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
|
||||
@@ -424,6 +424,9 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
|
||||
it may actually contain another end of response already! */
|
||||
clipamount = gotbytes - i;
|
||||
restart = TRUE;
|
||||
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
|
||||
"server response left\n",
|
||||
(int)clipamount));
|
||||
}
|
||||
else if(keepon) {
|
||||
|
||||
|
||||
@@ -212,8 +212,15 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
infof(data, "PolarSSL re-using session\n");
|
||||
}
|
||||
|
||||
/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's
|
||||
1.1.4 version and the like */
|
||||
#if POLARSSL_VERSION_NUMBER<0x01020000
|
||||
ssl_set_session(&connssl->ssl, 1, 600,
|
||||
&connssl->ssn);
|
||||
#else
|
||||
ssl_set_session(&connssl->ssl,
|
||||
&connssl->ssn);
|
||||
#endif
|
||||
|
||||
ssl_set_ca_chain(&connssl->ssl,
|
||||
&connssl->cacert,
|
||||
@@ -306,12 +313,25 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
|
||||
/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's
|
||||
1.1.4 version and the like */
|
||||
#if POLARSSL_VERSION_NUMBER<0x01020000
|
||||
if(conn->ssl[sockindex].ssl.peer_cert) {
|
||||
#else
|
||||
if(ssl_get_peer_cert(&(connssl->ssl))) {
|
||||
#endif
|
||||
/* If the session was resumed, there will be no peer certs */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's
|
||||
1.1.4 version and the like */
|
||||
#if POLARSSL_VERSION_NUMBER<0x01020000
|
||||
if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ",
|
||||
conn->ssl[sockindex].ssl.peer_cert) != -1)
|
||||
#else
|
||||
if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ",
|
||||
ssl_get_peer_cert(&(connssl->ssl))) != -1)
|
||||
#endif
|
||||
infof(data, "Dumping cert info:\n%s\n", buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -340,10 +340,10 @@ static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
|
||||
const char *buffer, size_t length)
|
||||
{
|
||||
/* FIXME: Check for overflow */
|
||||
ssize_t len = conn->buffer_size;
|
||||
int tx = 0;
|
||||
ssize_t tx = 0, len = conn->buffer_size;
|
||||
|
||||
len -= conn->mech->overhead(conn->app_data, conn->data_prot, len);
|
||||
len -= conn->mech->overhead(conn->app_data, conn->data_prot,
|
||||
curlx_sztosi(len));
|
||||
if(len <= 0)
|
||||
len = length;
|
||||
while(length) {
|
||||
@@ -351,7 +351,7 @@ static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
|
||||
/* FIXME: Check for overflow. */
|
||||
len = length;
|
||||
}
|
||||
do_sec_send(conn, fd, buffer, len);
|
||||
do_sec_send(conn, fd, buffer, curlx_sztosi(len));
|
||||
length -= len;
|
||||
buffer += len;
|
||||
tx += len;
|
||||
|
||||
10
lib/select.c
10
lib/select.c
@@ -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
|
||||
@@ -221,8 +221,10 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = (int)(timeout_ms - elapsed_ms);
|
||||
if(pending_ms <= 0)
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
@@ -304,8 +306,10 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
|
||||
break;
|
||||
if(timeout_ms > 0) {
|
||||
pending_ms = timeout_ms - elapsed_ms;
|
||||
if(pending_ms <= 0)
|
||||
if(pending_ms <= 0) {
|
||||
r = 0; /* Simulate a "call timed out" case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(r == -1);
|
||||
|
||||
|
||||
20
lib/select.h
20
lib/select.h
@@ -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
|
||||
@@ -30,24 +30,6 @@
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* poll() function on Windows Vista and later is called WSAPoll()
|
||||
*/
|
||||
|
||||
#if defined(USE_WINSOCK) && (USE_WINSOCK > 1) && \
|
||||
defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
|
||||
# undef HAVE_POLL
|
||||
# define HAVE_POLL 1
|
||||
# undef HAVE_POLL_FINE
|
||||
# define HAVE_POLL_FINE 1
|
||||
# define poll(x,y,z) WSAPoll((x),(y),(z))
|
||||
# if defined(_MSC_VER) && defined(POLLRDNORM)
|
||||
# undef POLLPRI
|
||||
# define POLLPRI POLLRDBAND
|
||||
# define HAVE_STRUCT_POLLFD 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of pollfd struct and constants for platforms lacking them.
|
||||
*/
|
||||
|
||||
@@ -264,7 +264,7 @@ CURLcode Curl_write(struct connectdata *conn,
|
||||
|
||||
default:
|
||||
/* we got a specific curlcode, forward it */
|
||||
return (CURLcode)curlcode;
|
||||
return curlcode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
28
lib/setup.h
28
lib/setup.h
@@ -188,6 +188,24 @@
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTMP
|
||||
# define CURL_DISABLE_RTMP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -610,11 +628,6 @@ int netware_init(void);
|
||||
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
|
||||
#endif
|
||||
|
||||
/* Define S_ISREG if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
|
||||
* Parameters should of course normally not be unused, but for example when
|
||||
@@ -668,4 +681,9 @@ int netware_init(void);
|
||||
# define SHUT_RDWR 0x02
|
||||
#endif
|
||||
|
||||
/* Define S_ISREG if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
||||
@@ -232,6 +232,11 @@ static int smtp_endofresp(struct pingpong *pp, int *resp)
|
||||
line += 4;
|
||||
len -= 4;
|
||||
|
||||
if(smtpc->state == SMTP_EHLO && len >= 4 && !memcmp(line, "SIZE", 4)) {
|
||||
DEBUGF(infof(conn->data, "Server supports SIZE extension.\n"));
|
||||
smtpc->size_supported = true;
|
||||
}
|
||||
|
||||
if(smtpc->state == SMTP_EHLO && len >= 5 && !memcmp(line, "AUTH ", 5)) {
|
||||
line += 5;
|
||||
len -= 5;
|
||||
@@ -943,7 +948,7 @@ static CURLcode smtp_mail(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* calculate the optional SIZE parameter */
|
||||
if(conn->data->set.infilesize > 0) {
|
||||
if(conn->proto.smtpc.size_supported && conn->data->set.infilesize > 0) {
|
||||
size = aprintf("%" FORMAT_OFF_T, data->set.infilesize);
|
||||
|
||||
if(!size) {
|
||||
|
||||
@@ -66,6 +66,8 @@ struct smtp_conn {
|
||||
struct curl_slist *rcpt; /* Recipient list */
|
||||
bool ssldone; /* Is connect() over SSL done? only relevant in
|
||||
multi mode */
|
||||
bool size_supported; /* If server supports SIZE extension according to
|
||||
RFC 1870 */
|
||||
};
|
||||
|
||||
extern const struct Curl_handler Curl_handler_smtp;
|
||||
|
||||
149
lib/socks.c
149
lib/socks.c
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_PROXY) || defined(USE_WINDOWS_SSPI)
|
||||
#if !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
@@ -370,7 +370,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
long timeout;
|
||||
bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
|
||||
const size_t hostname_len = strlen(hostname);
|
||||
ssize_t packetsize = 0;
|
||||
ssize_t len = 0;
|
||||
|
||||
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
|
||||
if(!socks5_resolve_local && hostname_len > 255) {
|
||||
@@ -473,15 +473,14 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
#endif
|
||||
else if(socksreq[1] == 2) {
|
||||
/* Needs user name and password */
|
||||
size_t userlen, pwlen;
|
||||
int len;
|
||||
size_t proxy_name_len, proxy_password_len;
|
||||
if(proxy_name && proxy_password) {
|
||||
userlen = strlen(proxy_name);
|
||||
pwlen = strlen(proxy_password);
|
||||
proxy_name_len = strlen(proxy_name);
|
||||
proxy_password_len = strlen(proxy_password);
|
||||
}
|
||||
else {
|
||||
userlen = 0;
|
||||
pwlen = 0;
|
||||
proxy_name_len = 0;
|
||||
proxy_password_len = 0;
|
||||
}
|
||||
|
||||
/* username/password request looks like
|
||||
@@ -493,14 +492,14 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
*/
|
||||
len = 0;
|
||||
socksreq[len++] = 1; /* username/pw subnegotiation version */
|
||||
socksreq[len++] = (unsigned char) userlen;
|
||||
if(proxy_name && userlen)
|
||||
memcpy(socksreq + len, proxy_name, userlen);
|
||||
len += (int)userlen;
|
||||
socksreq[len++] = (unsigned char) pwlen;
|
||||
if(proxy_password && pwlen)
|
||||
memcpy(socksreq + len, proxy_password, pwlen);
|
||||
len += (int)pwlen;
|
||||
socksreq[len++] = (unsigned char) proxy_name_len;
|
||||
if(proxy_name && proxy_name_len)
|
||||
memcpy(socksreq + len, proxy_name, proxy_name_len);
|
||||
len += proxy_name_len;
|
||||
socksreq[len++] = (unsigned char) proxy_password_len;
|
||||
if(proxy_password && proxy_password_len)
|
||||
memcpy(socksreq + len, proxy_password, proxy_password_len);
|
||||
len += proxy_password_len;
|
||||
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
|
||||
if((code != CURLE_OK) || (len != written)) {
|
||||
@@ -554,31 +553,22 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
}
|
||||
|
||||
/* Authentication is complete, now specify destination to the proxy */
|
||||
socksreq[0] = 5; /* version (SOCKS5) */
|
||||
socksreq[1] = 1; /* connect */
|
||||
socksreq[2] = 0; /* must be zero */
|
||||
len = 0;
|
||||
socksreq[len++] = 5; /* version (SOCKS5) */
|
||||
socksreq[len++] = 1; /* connect */
|
||||
socksreq[len++] = 0; /* must be zero */
|
||||
|
||||
if(!socks5_resolve_local) {
|
||||
packetsize = (ssize_t)(5 + hostname_len + 2);
|
||||
|
||||
socksreq[3] = 3; /* ATYP: domain name = 3 */
|
||||
socksreq[4] = (char) hostname_len; /* address length */
|
||||
memcpy(&socksreq[5], hostname, hostname_len); /* address bytes w/o NULL */
|
||||
|
||||
/* PORT MSB */
|
||||
socksreq[hostname_len+5] = (unsigned char)((remote_port >> 8) & 0xff);
|
||||
/* PORT LSB */
|
||||
socksreq[hostname_len+6] = (unsigned char)(remote_port & 0xff);
|
||||
socksreq[len++] = 3; /* ATYP: domain name = 3 */
|
||||
socksreq[len++] = (char) hostname_len; /* address length */
|
||||
memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
|
||||
len += hostname_len;
|
||||
}
|
||||
else {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *hp=NULL;
|
||||
Curl_addrinfo *hp = NULL;
|
||||
int rc = Curl_resolv(conn, hostname, remote_port, &dns);
|
||||
|
||||
packetsize = 10;
|
||||
|
||||
socksreq[3] = 1; /* IPv4 = 1 */
|
||||
|
||||
if(rc == CURLRESOLV_ERROR)
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
|
||||
@@ -596,17 +586,31 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
if(dns)
|
||||
hp=dns->addr;
|
||||
if(hp) {
|
||||
char buf[64];
|
||||
unsigned short ip[4];
|
||||
Curl_printable_address(hp, buf, sizeof(buf));
|
||||
struct sockaddr_in *saddr_in;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct sockaddr_in6 *saddr_in6;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
if(4 == sscanf( buf, "%hu.%hu.%hu.%hu",
|
||||
&ip[0], &ip[1], &ip[2], &ip[3])) {
|
||||
socksreq[4] = (unsigned char)ip[0];
|
||||
socksreq[5] = (unsigned char)ip[1];
|
||||
socksreq[6] = (unsigned char)ip[2];
|
||||
socksreq[7] = (unsigned char)ip[3];
|
||||
if(hp->ai_family == AF_INET) {
|
||||
socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
|
||||
|
||||
saddr_in = (struct sockaddr_in*)hp->ai_addr;
|
||||
for(i = 0; i < 4; i++) {
|
||||
socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i];
|
||||
infof(data, "%d\n", socksreq[len-1]);
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(hp->ai_family == AF_INET6) {
|
||||
socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
|
||||
|
||||
saddr_in6 = (struct sockaddr_in6*)hp->ai_addr;
|
||||
for(i = 0; i < 16; i++) {
|
||||
socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
hp = NULL; /* fail! */
|
||||
|
||||
@@ -617,25 +621,25 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
hostname);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
socksreq[8] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
|
||||
socksreq[9] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
|
||||
}
|
||||
|
||||
socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
|
||||
socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(conn->socks5_gssapi_enctype) {
|
||||
failf(data, "SOCKS5 gssapi protection not yet implemented.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, packetsize,
|
||||
&written);
|
||||
if((code != CURLE_OK) || (written != packetsize)) {
|
||||
code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
|
||||
|
||||
if((code != CURLE_OK) || (len != written)) {
|
||||
failf(data, "Failed to send SOCKS5 connect request.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
packetsize = 10; /* minimum packet size is 10 */
|
||||
len = 10; /* minimum packet size is 10 */
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
if(conn->socks5_gssapi_enctype) {
|
||||
@@ -643,9 +647,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
|
||||
&actualread);
|
||||
if((result != CURLE_OK) || (actualread != packetsize)) {
|
||||
result = Curl_blockread_all(conn, sock, (char *)socksreq,
|
||||
len, &actualread);
|
||||
|
||||
if((result != CURLE_OK) || (len != actualread)) {
|
||||
failf(data, "Failed to receive SOCKS5 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
@@ -656,13 +661,37 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
if(socksreq[1] != 0) { /* Anything besides 0 is an error */
|
||||
if(socksreq[3] == 1) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
((socksreq[8] << 8) | socksreq[9]),
|
||||
socksreq[1]);
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
else if(socksreq[3] == 3) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %s:%d. (%d)",
|
||||
hostname,
|
||||
((socksreq[8] << 8) | socksreq[9]),
|
||||
socksreq[1]);
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
failf(data,
|
||||
"Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
|
||||
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
|
||||
(unsigned char)socksreq[4], (unsigned char)socksreq[5],
|
||||
(unsigned char)socksreq[6], (unsigned char)socksreq[7],
|
||||
(unsigned char)socksreq[8], (unsigned char)socksreq[9],
|
||||
(unsigned char)socksreq[10], (unsigned char)socksreq[11],
|
||||
(unsigned char)socksreq[12], (unsigned char)socksreq[13],
|
||||
(unsigned char)socksreq[14], (unsigned char)socksreq[15],
|
||||
(unsigned char)socksreq[16], (unsigned char)socksreq[17],
|
||||
(unsigned char)socksreq[18], (unsigned char)socksreq[19],
|
||||
((socksreq[8] << 8) | socksreq[9]),
|
||||
socksreq[1]);
|
||||
}
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* Fix: in general, returned BND.ADDR is variable length parameter by RFC
|
||||
@@ -685,11 +714,11 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
if(socksreq[3] == 3) {
|
||||
/* domain name */
|
||||
int addrlen = (int) socksreq[4];
|
||||
packetsize = 5 + addrlen + 2;
|
||||
len = 5 + addrlen + 2;
|
||||
}
|
||||
else if(socksreq[3] == 4) {
|
||||
/* IPv6 */
|
||||
packetsize = 4 + 16 + 2;
|
||||
len = 4 + 16 + 2;
|
||||
}
|
||||
|
||||
/* At this point we already read first 10 bytes */
|
||||
@@ -697,11 +726,11 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
if(!conn->socks5_gssapi_enctype) {
|
||||
/* decrypt_gssapi_blockread already read the whole packet */
|
||||
#endif
|
||||
if(packetsize > 10) {
|
||||
packetsize -= 10;
|
||||
if(len > 10) {
|
||||
len -= 10;
|
||||
result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
|
||||
packetsize, &actualread);
|
||||
if((result != CURLE_OK) || (actualread != packetsize)) {
|
||||
len, &actualread);
|
||||
if((result != CURLE_OK) || (len != actualread)) {
|
||||
failf(data, "Failed to receive SOCKS5 connect request ack.");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
|
||||
205
lib/ssh.c
205
lib/ssh.c
@@ -324,7 +324,8 @@ static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
|
||||
static LIBSSH2_FREE_FUNC(my_libssh2_free)
|
||||
{
|
||||
(void)abstract; /* arg not used */
|
||||
free(ptr);
|
||||
if(ptr) /* ssh2 agent sometimes call free with null ptr */
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -345,6 +346,9 @@ static void state(struct connectdata *conn, sshstate nowstate)
|
||||
"SSH_AUTH_PKEY",
|
||||
"SSH_AUTH_PASS_INIT",
|
||||
"SSH_AUTH_PASS",
|
||||
"SSH_AUTH_AGENT_INIT",
|
||||
"SSH_AUTH_AGENT_LIST",
|
||||
"SSH_AUTH_AGENT",
|
||||
"SSH_AUTH_HOST_INIT",
|
||||
"SSH_AUTH_HOST",
|
||||
"SSH_AUTH_KEY_INIT",
|
||||
@@ -635,6 +639,49 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode ssh_check_fingerprint(struct connectdata *conn)
|
||||
{
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
|
||||
char md5buffer[33];
|
||||
int i;
|
||||
|
||||
const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
|
||||
LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
|
||||
if(fingerprint) {
|
||||
/* The fingerprint points to static storage (!), don't free() it. */
|
||||
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.
|
||||
*/
|
||||
if(pubkey_md5 && strlen(pubkey_md5) == 32) {
|
||||
if(!fingerprint || !strequal(md5buffer, pubkey_md5)) {
|
||||
if(fingerprint)
|
||||
failf(data,
|
||||
"Denied establishing ssh session: mismatch md5 fingerprint. "
|
||||
"Remote %s is not equal to %s", md5buffer, pubkey_md5);
|
||||
else
|
||||
failf(data,
|
||||
"Denied establishing ssh session: md5 fingerprint not available");
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
|
||||
return sshc->actualcode;
|
||||
}
|
||||
else {
|
||||
infof(data, "MD5 checksum match!\n");
|
||||
/* as we already matched, we skip the check for known hosts */
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
return ssh_knownhost(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* ssh_statemach_act() runs the SSH state machine as far as it can without
|
||||
@@ -650,10 +697,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];
|
||||
const char *fingerprint;
|
||||
char md5buffer[33];
|
||||
char *new_readdir_line;
|
||||
int rc = LIBSSH2_ERROR_NONE, i;
|
||||
int rc = LIBSSH2_ERROR_NONE;
|
||||
int err;
|
||||
int seekerr = CURL_SEEKFUNC_OK;
|
||||
*block = 0; /* we're not blocking by default */
|
||||
@@ -694,36 +739,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
* against our known hosts. How that is handled (reading from file,
|
||||
* 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. */
|
||||
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.
|
||||
*/
|
||||
if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
|
||||
strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
|
||||
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",
|
||||
md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
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);
|
||||
|
||||
if(!result)
|
||||
result = ssh_check_fingerprint(conn);
|
||||
if(result == CURLE_OK)
|
||||
state(conn, SSH_AUTHLIST);
|
||||
break;
|
||||
|
||||
@@ -893,12 +910,101 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
state(conn, SSH_AUTH_HOST);
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
state(conn, SSH_AUTH_AGENT_INIT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SSH_AUTH_HOST:
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
state(conn, SSH_AUTH_AGENT_INIT);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_AGENT_INIT:
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
|
||||
&& (strstr(sshc->authlist, "publickey") != NULL)) {
|
||||
|
||||
/* Connect to the ssh-agent */
|
||||
/* The agent could be shared by a curl thread i believe
|
||||
but nothing obvious as keys can be added/removed at any time */
|
||||
if(!sshc->ssh_agent) {
|
||||
sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
|
||||
if(!sshc->ssh_agent) {
|
||||
infof(data, "Could not create agent object\n");
|
||||
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
rc = libssh2_agent_connect(sshc->ssh_agent);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
if(rc < 0) {
|
||||
infof(data, "Failure connecting to agent\n");
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_AGENT_LIST);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_LIBSSH2_AGENT_API */
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_AGENT_LIST:
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
rc = libssh2_agent_list_identities(sshc->ssh_agent);
|
||||
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
if(rc < 0) {
|
||||
infof(data, "Failure requesting identities to agent\n");
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
}
|
||||
else {
|
||||
state(conn, SSH_AUTH_AGENT);
|
||||
sshc->sshagent_prev_identity = NULL;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SSH_AUTH_AGENT:
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
/* as prev_identity evolves only after an identity user auth finished we
|
||||
can safely request it again as long as EAGAIN is returned here or by
|
||||
libssh2_agent_userauth */
|
||||
rc = libssh2_agent_get_identity(sshc->ssh_agent,
|
||||
&sshc->sshagent_identity,
|
||||
sshc->sshagent_prev_identity);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
break;
|
||||
|
||||
if(rc == 0) {
|
||||
rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
|
||||
sshc->sshagent_identity);
|
||||
|
||||
if(rc < 0) {
|
||||
if(rc != LIBSSH2_ERROR_EAGAIN) {
|
||||
/* tried and failed? go to next identity */
|
||||
sshc->sshagent_prev_identity = sshc->sshagent_identity;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(rc < 0)
|
||||
infof(data, "Failure requesting identities to agent\n");
|
||||
else if(rc == 1)
|
||||
infof(data, "No identity would match\n");
|
||||
|
||||
if(rc == LIBSSH2_ERROR_NONE) {
|
||||
sshc->authed = TRUE;
|
||||
infof(data, "Agent based authentication successful\n");
|
||||
state(conn, SSH_AUTH_DONE);
|
||||
}
|
||||
else
|
||||
state(conn, SSH_AUTH_KEY_INIT);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SSH_AUTH_KEY_INIT:
|
||||
@@ -2357,6 +2463,25 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
if(sshc->ssh_agent) {
|
||||
rc = libssh2_agent_disconnect(sshc->ssh_agent);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
break;
|
||||
}
|
||||
else if(rc < 0) {
|
||||
infof(data, "Failed to disconnect from libssh2 agent\n");
|
||||
}
|
||||
libssh2_agent_free (sshc->ssh_agent);
|
||||
sshc->ssh_agent = NULL;
|
||||
|
||||
/* NB: there is no need to free identities, they are part of internal
|
||||
agent stuff */
|
||||
sshc->sshagent_identity = NULL;
|
||||
sshc->sshagent_prev_identity = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sshc->ssh_session) {
|
||||
rc = libssh2_session_free(sshc->ssh_session);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
@@ -2857,6 +2982,10 @@ static ssize_t scp_send(struct connectdata *conn, int sockindex,
|
||||
*err = CURLE_AGAIN;
|
||||
nwrite = 0;
|
||||
}
|
||||
else if(nwrite < LIBSSH2_ERROR_NONE) {
|
||||
*err = libssh2_session_error_to_CURLE(nwrite);
|
||||
nwrite = -1;
|
||||
}
|
||||
|
||||
return nwrite;
|
||||
}
|
||||
@@ -3001,6 +3130,10 @@ static ssize_t sftp_send(struct connectdata *conn, int sockindex,
|
||||
*err = CURLE_AGAIN;
|
||||
nwrite = 0;
|
||||
}
|
||||
else if(nwrite < LIBSSH2_ERROR_NONE) {
|
||||
*err = libssh2_session_error_to_CURLE(nwrite);
|
||||
nwrite = -1;
|
||||
}
|
||||
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ typedef enum {
|
||||
SSH_AUTH_PKEY,
|
||||
SSH_AUTH_PASS_INIT,
|
||||
SSH_AUTH_PASS,
|
||||
SSH_AUTH_AGENT_INIT,/* initialize then wait for connection to agent */
|
||||
SSH_AUTH_AGENT_LIST,/* ask for list then wait for entire list to come */
|
||||
SSH_AUTH_AGENT, /* attempt one key at a time */
|
||||
SSH_AUTH_HOST_INIT,
|
||||
SSH_AUTH_HOST,
|
||||
SSH_AUTH_KEY_INIT,
|
||||
@@ -139,6 +142,12 @@ struct ssh_conn {
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
int orig_waitfor; /* default READ/WRITE bits wait for */
|
||||
|
||||
#ifdef HAVE_LIBSSH2_AGENT_API
|
||||
LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */
|
||||
struct libssh2_agent_publickey *sshagent_identity,
|
||||
*sshagent_prev_identity;
|
||||
#endif
|
||||
|
||||
/* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
|
||||
header */
|
||||
#ifdef HAVE_LIBSSH2_KNOWNHOST_API
|
||||
|
||||
92
lib/ssluse.c
92
lib/ssluse.c
@@ -50,6 +50,7 @@
|
||||
#include "select.h"
|
||||
#include "sslgen.h"
|
||||
#include "rawstr.h"
|
||||
#include "hostcheck.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -66,6 +67,7 @@
|
||||
#else
|
||||
#include <rand.h>
|
||||
#include <x509v3.h>
|
||||
#include <md5.h>
|
||||
#endif
|
||||
|
||||
#include "warnless.h"
|
||||
@@ -1038,71 +1040,6 @@ static int asn1_output(const ASN1_UTCTIME *tm,
|
||||
|
||||
/* ====================================================== */
|
||||
|
||||
/*
|
||||
* Match a hostname against a wildcard pattern.
|
||||
* E.g.
|
||||
* "foo.host.com" matches "*.host.com".
|
||||
*
|
||||
* We use the matching rule described in RFC6125, section 6.4.3.
|
||||
* http://tools.ietf.org/html/rfc6125#section-6.4.3
|
||||
*/
|
||||
#define HOST_NOMATCH 0
|
||||
#define HOST_MATCH 1
|
||||
|
||||
static int hostmatch(const char *hostname, const char *pattern)
|
||||
{
|
||||
const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
|
||||
int wildcard_enabled;
|
||||
size_t prefixlen, suffixlen;
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL) {
|
||||
return Curl_raw_equal(pattern, hostname) ? HOST_MATCH : HOST_NOMATCH;
|
||||
}
|
||||
/* We require at least 2 dots in pattern to avoid too wide wildcard
|
||||
match. */
|
||||
wildcard_enabled = 1;
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled) {
|
||||
return Curl_raw_equal(pattern, hostname) ? HOST_MATCH : HOST_NOMATCH;
|
||||
}
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end)) {
|
||||
return HOST_NOMATCH;
|
||||
}
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
label of the hostname is at least as large as the left-most label
|
||||
of the pattern. */
|
||||
if(hostname_label_end - hostname < pattern_label_end - pattern) {
|
||||
return HOST_NOMATCH;
|
||||
}
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
HOST_MATCH : HOST_NOMATCH;
|
||||
}
|
||||
|
||||
static int
|
||||
cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
{
|
||||
if(!match_pattern || !*match_pattern ||
|
||||
!hostname || !*hostname) /* sanity check */
|
||||
return 0;
|
||||
|
||||
if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
|
||||
return 1;
|
||||
|
||||
if(hostmatch(hostname,match_pattern) == HOST_MATCH)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Quote from RFC2818 section 3.1 "Server Identity"
|
||||
|
||||
@@ -1191,7 +1128,7 @@ static CURLcode verifyhost(struct connectdata *conn,
|
||||
if((altlen == strlen(altptr)) &&
|
||||
/* if this isn't true, there was an embedded zero in the name
|
||||
string and we cannot match it. */
|
||||
cert_hostcheck(altptr, conn->host.name))
|
||||
Curl_cert_hostcheck(altptr, conn->host.name))
|
||||
matched = 1;
|
||||
else
|
||||
matched = 0;
|
||||
@@ -1290,15 +1227,10 @@ static CURLcode verifyhost(struct connectdata *conn,
|
||||
"SSL: unable to obtain common name from peer certificate");
|
||||
res = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
||||
if(data->set.ssl.verifyhost > 1) {
|
||||
failf(data, "SSL: certificate subject name '%s' does not match "
|
||||
"target host name '%s'", peer_CN, conn->host.dispname);
|
||||
res = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else
|
||||
infof(data, "\t common name: %s (does not match '%s')\n",
|
||||
peer_CN, conn->host.dispname);
|
||||
else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
||||
failf(data, "SSL: certificate subject name '%s' does not match "
|
||||
"target host name '%s'", peer_CN, conn->host.dispname);
|
||||
res = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
infof(data, "\t common name: %s (matched)\n", peer_CN);
|
||||
@@ -1569,6 +1501,10 @@ ossl_connect_step1(struct connectdata *conn,
|
||||
ctx_options |= SSL_OP_NO_TICKET;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
ctx_options |= SSL_OP_NO_COMPRESSION;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
|
||||
/* mitigate CVE-2010-4180 */
|
||||
ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
|
||||
@@ -2307,11 +2243,11 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
infof(data, "\t subject: %s\n", buffer);
|
||||
|
||||
certdate = X509_get_notBefore(connssl->server_cert);
|
||||
asn1_output(certdate, buffer, sizeof(buffer));
|
||||
asn1_output(certdate, buffer, BUFSIZE);
|
||||
infof(data, "\t start date: %s\n", buffer);
|
||||
|
||||
certdate = X509_get_notAfter(connssl->server_cert);
|
||||
asn1_output(certdate, buffer, sizeof(buffer));
|
||||
asn1_output(certdate, buffer, BUFSIZE);
|
||||
infof(data, "\t expire date: %s\n", buffer);
|
||||
|
||||
if(data->set.ssl.verifyhost) {
|
||||
@@ -2324,7 +2260,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
}
|
||||
|
||||
rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert),
|
||||
buffer, sizeof(buffer));
|
||||
buffer, BUFSIZE);
|
||||
if(rc) {
|
||||
if(strict)
|
||||
failf(data, "SSL: couldn't get X509-issuer name!");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, 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
|
||||
@@ -19,7 +19,9 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is 'mem-include-scan' clean. See test 1132.
|
||||
*/
|
||||
#include "setup.h"
|
||||
|
||||
#include "strdup.h"
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
const char *
|
||||
curl_easy_strerror(CURLcode error)
|
||||
|
||||
17
lib/tftp.c
17
lib/tftp.c
@@ -591,16 +591,25 @@ static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
|
||||
case TFTP_EVENT_DATA:
|
||||
/* Is this the block we expect? */
|
||||
rblock = getrpacketblock(&state->rpacket);
|
||||
if(NEXT_BLOCKNUM(state->block) != rblock) {
|
||||
/* No, log it */
|
||||
if(NEXT_BLOCKNUM(state->block) == rblock) {
|
||||
/* This is the expected block. Reset counters and ACK it. */
|
||||
state->retries = 0;
|
||||
}
|
||||
else if(state->block == rblock) {
|
||||
/* This is the last recently received block again. Log it and ACK it
|
||||
again. */
|
||||
infof(data, "Received last DATA packet block %d again.\n", rblock);
|
||||
}
|
||||
else {
|
||||
/* totally unexpected, just log it */
|
||||
infof(data,
|
||||
"Received unexpected DATA packet block %d, expecting block %d\n",
|
||||
rblock, NEXT_BLOCKNUM(state->block));
|
||||
break;
|
||||
}
|
||||
/* This is the expected block. Reset counters and ACK it. */
|
||||
|
||||
/* ACK this block. */
|
||||
state->block = (unsigned short)rblock;
|
||||
state->retries = 0;
|
||||
setpacketevent(&state->spacket, TFTP_EVENT_ACK);
|
||||
setpacketblock(&state->spacket, state->block);
|
||||
sbytes = sendto(state->sockfd, (void *)state->spacket.data,
|
||||
|
||||
@@ -1030,12 +1030,6 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
if(result || *done)
|
||||
return result;
|
||||
}
|
||||
else if(k->keepon & KEEP_RECV) {
|
||||
DEBUGF(infof(data, "additional stuff not fine %s:%d: %d %d\n",
|
||||
__FILE__, __LINE__,
|
||||
select_res & CURL_CSELECT_IN,
|
||||
conn->bits.stream_was_rewound));
|
||||
}
|
||||
|
||||
/* If we still have writing to do, we check if we have a writable socket. */
|
||||
if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
|
||||
@@ -1469,6 +1463,12 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
|
||||
if(data->set.connecttimeout)
|
||||
Curl_expire(data, data->set.connecttimeout);
|
||||
|
||||
/* In case the handle is re-used and an authentication method was picked
|
||||
in the session we need to make sure we only use the one(s) we now
|
||||
consider to be fine */
|
||||
data->state.authhost.picked &= data->state.authhost.want;
|
||||
data->state.authproxy.picked &= data->state.authproxy.want;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -1981,7 +1981,9 @@ Curl_reconnect_request(struct connectdata **connp)
|
||||
conn->bits.close = TRUE; /* enforce close of this connection */
|
||||
result = Curl_done(&conn, result, FALSE); /* we are so done with this */
|
||||
|
||||
/* conn may no longer be a good pointer */
|
||||
/* conn may no longer be a good pointer, clear it to avoid mistakes by
|
||||
parent functions */
|
||||
*connp = NULL;
|
||||
|
||||
/*
|
||||
* According to bug report #1330310. We need to check for CURLE_SEND_ERROR
|
||||
@@ -2056,7 +2058,9 @@ CURLcode Curl_retry_request(struct connectdata *conn,
|
||||
error just because nothing has been
|
||||
transferred! */
|
||||
|
||||
if(data->state.proto.http->writebytecount)
|
||||
|
||||
if((conn->handler->protocol&CURLPROTO_HTTP) &&
|
||||
data->state.proto.http->writebytecount)
|
||||
return Curl_readrewind(conn);
|
||||
}
|
||||
return CURLE_OK;
|
||||
|
||||
80
lib/url.c
80
lib/url.c
@@ -708,7 +708,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||||
* switched off unless wanted.
|
||||
*/
|
||||
set->ssl.verifypeer = TRUE;
|
||||
set->ssl.verifyhost = 2;
|
||||
set->ssl.verifyhost = TRUE;
|
||||
#ifdef USE_TLS_SRP
|
||||
set->ssl.authtype = CURL_TLSAUTH_NONE;
|
||||
#endif
|
||||
@@ -2049,13 +2049,25 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
/*
|
||||
* Enable peer SSL verifying.
|
||||
*/
|
||||
data->set.ssl.verifypeer = va_arg(param, long);
|
||||
data->set.ssl.verifypeer = (0 != va_arg(param, long))?TRUE:FALSE;
|
||||
break;
|
||||
case CURLOPT_SSL_VERIFYHOST:
|
||||
/*
|
||||
* Enable verification of the CN contained in the peer certificate
|
||||
* Enable verification of the host name in the peer certificate
|
||||
*/
|
||||
data->set.ssl.verifyhost = va_arg(param, long);
|
||||
arg = va_arg(param, long);
|
||||
|
||||
/* Obviously people are not reading documentation and too many thought
|
||||
this argument took a boolean when it wasn't and misused it. We thus ban
|
||||
1 as a sensible input and we warn about its use. Then we only have the
|
||||
2 action internally stored as TRUE. */
|
||||
|
||||
if(1 == arg) {
|
||||
failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
data->set.ssl.verifyhost = (0 != arg)?TRUE:FALSE;
|
||||
break;
|
||||
#ifdef USE_SSLEAY
|
||||
/* since these two options are only possible to use on an OpenSSL-
|
||||
@@ -2589,7 +2601,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
|
||||
break;
|
||||
case CURLOPT_TLSAUTH_TYPE:
|
||||
if(strncmp((char *)va_arg(param, char *), "SRP", strlen("SRP")) == 0)
|
||||
if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP")))
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_SRP;
|
||||
else
|
||||
data->set.ssl.authtype = CURL_TLSAUTH_NONE;
|
||||
@@ -2928,10 +2940,14 @@ ConnectionExists(struct SessionHandle *data,
|
||||
{
|
||||
long i;
|
||||
struct connectdata *check;
|
||||
struct connectdata *chosen = 0;
|
||||
bool canPipeline = IsPipeliningPossible(data, needle);
|
||||
bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.want==CURLAUTH_NTLM_WB);
|
||||
|
||||
for(i=0; i< data->state.connc->num; i++) {
|
||||
bool match = FALSE;
|
||||
bool credentialsMatch = FALSE;
|
||||
size_t pipeLen = 0;
|
||||
/*
|
||||
* Note that if we use a HTTP proxy, we check connections to that
|
||||
@@ -3102,9 +3118,7 @@ ConnectionExists(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
if((needle->handler->protocol & CURLPROTO_FTP) ||
|
||||
((needle->handler->protocol & CURLPROTO_HTTP) &&
|
||||
((data->state.authhost.want==CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.want==CURLAUTH_NTLM_WB)))) {
|
||||
((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
|
||||
/* This is FTP or HTTP+NTLM, verify that we're using the same name
|
||||
and password as well */
|
||||
if(!strequal(needle->user, check->user) ||
|
||||
@@ -3112,6 +3126,7 @@ ConnectionExists(struct SessionHandle *data,
|
||||
/* one of them was different */
|
||||
continue;
|
||||
}
|
||||
credentialsMatch = TRUE;
|
||||
}
|
||||
match = TRUE;
|
||||
}
|
||||
@@ -3129,14 +3144,29 @@ ConnectionExists(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
if(match) {
|
||||
check->inuse = TRUE; /* mark this as being in use so that no other
|
||||
handle in a multi stack may nick it */
|
||||
chosen = check;
|
||||
|
||||
*usethis = check;
|
||||
return TRUE; /* yes, we found one to use! */
|
||||
/* If we are not looking for an NTLM connection, we can choose this one
|
||||
immediately. */
|
||||
if(!wantNTLM)
|
||||
break;
|
||||
|
||||
/* Otherwise, check if this is already authenticating with the right
|
||||
credentials. If not, keep looking so that we can reuse NTLM
|
||||
connections if possible. (Especially we must reuse the same
|
||||
connection if partway through a handshake!) */
|
||||
if(credentialsMatch && chosen->ntlm.state != NTLMSTATE_NONE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(chosen) {
|
||||
chosen->inuse = TRUE; /* mark this as being in use so that no other
|
||||
handle in a multi stack may nick it */
|
||||
*usethis = chosen;
|
||||
return TRUE; /* yes, we found one to use! */
|
||||
}
|
||||
|
||||
return FALSE; /* no matching connecting exists */
|
||||
}
|
||||
|
||||
@@ -3957,9 +3987,17 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
||||
last part of the URI. We are looking for the first '#' so that we deal
|
||||
gracefully with non conformant URI such as http://example.com#foo#bar. */
|
||||
fragment = strchr(path, '#');
|
||||
if(fragment)
|
||||
if(fragment) {
|
||||
*fragment = 0;
|
||||
|
||||
/* we know the path part ended with a fragment, so we know the full URL
|
||||
string does too and we need to cut it off from there so it isn't used
|
||||
over proxy */
|
||||
fragment = strchr(data->change.url, '#');
|
||||
if(fragment)
|
||||
*fragment = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* So if the URL was A://B/C#D,
|
||||
* protop is A
|
||||
@@ -4231,7 +4269,7 @@ static CURLcode parse_proxy(struct SessionHandle *data,
|
||||
conn->proxytype = CURLPROXY_SOCKS5;
|
||||
else if(checkprefix("socks4a", proxy))
|
||||
conn->proxytype = CURLPROXY_SOCKS4A;
|
||||
else if(checkprefix("socks4", proxy))
|
||||
else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
|
||||
conn->proxytype = CURLPROXY_SOCKS4;
|
||||
/* Any other xxx:// : change to http proxy */
|
||||
}
|
||||
@@ -4659,13 +4697,12 @@ static CURLcode resolve_server(struct SessionHandle *data,
|
||||
/*************************************************************
|
||||
* Resolve the name of the server or proxy
|
||||
*************************************************************/
|
||||
if(conn->bits.reuse) {
|
||||
/* We're reusing the connection - no need to resolve anything */
|
||||
if(conn->bits.reuse)
|
||||
/* We're reusing the connection - no need to resolve anything, and
|
||||
fix_hostname() was called already in create_conn() for the re-use
|
||||
case. */
|
||||
*async = FALSE;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
fix_hostname(data, conn, &conn->host);
|
||||
}
|
||||
else {
|
||||
/* this is a fresh connect */
|
||||
int rc;
|
||||
@@ -4779,6 +4816,7 @@ static void reuse_conn(struct connectdata *old_conn,
|
||||
Curl_safefree(old_conn->passwd);
|
||||
Curl_safefree(old_conn->proxyuser);
|
||||
Curl_safefree(old_conn->proxypasswd);
|
||||
Curl_safefree(old_conn->localdev);
|
||||
|
||||
Curl_llist_destroy(old_conn->send_pipe, NULL);
|
||||
Curl_llist_destroy(old_conn->recv_pipe, NULL);
|
||||
@@ -5135,6 +5173,10 @@ static CURLcode create_conn(struct SessionHandle *data,
|
||||
free(conn); /* we don't need this anymore */
|
||||
conn = conn_temp;
|
||||
*in_connect = conn;
|
||||
|
||||
/* set a pointer to the hostname we display */
|
||||
fix_hostname(data, conn, &conn->host);
|
||||
|
||||
infof(data, "Re-using existing connection! (#%ld) with host %s\n",
|
||||
conn->connectindex,
|
||||
conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
|
||||
|
||||
@@ -234,6 +234,7 @@ enum protection_level {
|
||||
struct curl_schannel_cred {
|
||||
CredHandle cred_handle;
|
||||
TimeStamp time_stamp;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
struct curl_schannel_ctxt {
|
||||
@@ -331,10 +332,9 @@ struct ssl_connect_data {
|
||||
struct ssl_config_data {
|
||||
long version; /* what version the client wants to use */
|
||||
long certverifyresult; /* result from the certificate verification */
|
||||
long verifypeer; /* set TRUE if this is desired */
|
||||
long verifyhost; /* 0: no verify
|
||||
1: check that CN exists
|
||||
2: CN must match hostname */
|
||||
|
||||
bool verifypeer; /* set TRUE if this is desired */
|
||||
bool verifyhost; /* set TRUE if CN/SAN must match hostname */
|
||||
char *CApath; /* certificate dir (doesn't work on windows) */
|
||||
char *CAfile; /* certificate to verify peer against */
|
||||
const char *CRLfile; /* CRL to check certificate revocation */
|
||||
@@ -993,8 +993,8 @@ struct connectdata {
|
||||
int socks5_gssapi_enctype;
|
||||
#endif
|
||||
|
||||
long verifypeer;
|
||||
long verifyhost;
|
||||
bool verifypeer;
|
||||
bool verifyhost;
|
||||
|
||||
/* When this connection is created, store the conditions for the local end
|
||||
bind. This is stored before the actual bind and before any connection is
|
||||
|
||||
@@ -132,12 +132,15 @@ char *curl_version(void)
|
||||
else
|
||||
suff[0] = '\0';
|
||||
|
||||
len = snprintf(ptr, left, " librtmp/%d.%d%s",
|
||||
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, suff);
|
||||
snprintf(ptr, left, " librtmp/%d.%d%s",
|
||||
RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
|
||||
suff);
|
||||
/*
|
||||
If another lib version is added below this one, this code would
|
||||
also have to do:
|
||||
|
||||
len = what snprintf() returned
|
||||
|
||||
left -= len;
|
||||
ptr += len;
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_CLANG], [
|
||||
flags_dbg_all="$flags_dbg_all -gdwarf-2"
|
||||
flags_dbg_all="$flags_dbg_all -gvms"
|
||||
flags_dbg_yes="-g"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -Os -O3 -O4"
|
||||
flags_opt_yes="-Os"
|
||||
flags_opt_off="-O0"
|
||||
@@ -121,7 +121,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_DEC_C], [
|
||||
compiler_id="DEC_C"
|
||||
flags_dbg_all="-g -g0 -g1 -g2 -g3"
|
||||
flags_dbg_yes="-g2"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -O3 -O4"
|
||||
flags_opt_yes="-O1"
|
||||
flags_opt_off="-O0"
|
||||
@@ -157,7 +157,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [
|
||||
flags_dbg_all="$flags_dbg_all -gdwarf-2"
|
||||
flags_dbg_all="$flags_dbg_all -gvms"
|
||||
flags_dbg_yes="-g"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -O3 -Os"
|
||||
flags_opt_yes="-O2"
|
||||
flags_opt_off="-O0"
|
||||
@@ -236,7 +236,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_INTEL_C], [
|
||||
compiler_id="INTEL_UNIX_C"
|
||||
flags_dbg_all="-g -g0"
|
||||
flags_dbg_yes="-g"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -O3 -Os"
|
||||
flags_opt_yes="-O2"
|
||||
flags_opt_off="-O0"
|
||||
@@ -300,7 +300,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_SGI_MIPS_C], [
|
||||
compiler_id="SGI_MIPS_C"
|
||||
flags_dbg_all="-g -g0 -g1 -g2 -g3"
|
||||
flags_dbg_yes="-g"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -O3 -Ofast"
|
||||
flags_opt_yes="-O2"
|
||||
flags_opt_off="-O0"
|
||||
@@ -327,7 +327,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_SGI_MIPSPRO_C], [
|
||||
compiler_id="SGI_MIPSPRO_C"
|
||||
flags_dbg_all="-g -g0 -g1 -g2 -g3"
|
||||
flags_dbg_yes="-g"
|
||||
flags_dbg_off="-g0"
|
||||
flags_dbg_off=""
|
||||
flags_opt_all="-O -O0 -O1 -O2 -O3 -Ofast"
|
||||
flags_opt_yes="-O2"
|
||||
flags_opt_off="-O0"
|
||||
|
||||
@@ -169,39 +169,6 @@ AC_HELP_STRING([--disable-debug],[Disable debug build options]),
|
||||
AC_MSG_RESULT([$want_debug])
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_CHECK_OPTION_NONBLOCKING
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify if configure has been invoked with option
|
||||
dnl --enable-nonblocking or --disable-nonblocking, and
|
||||
dnl set shell variable want_nonblocking as appropriate.
|
||||
|
||||
AC_DEFUN([CURL_CHECK_OPTION_NONBLOCKING], [
|
||||
AC_BEFORE([$0],[CURL_CHECK_NONBLOCKING_SOCKET])dnl
|
||||
AC_MSG_CHECKING([whether to enable non-blocking communications])
|
||||
OPT_NONBLOCKING="default"
|
||||
AC_ARG_ENABLE(nonblocking,
|
||||
AC_HELP_STRING([--enable-nonblocking],[Enable non-blocking communications])
|
||||
AC_HELP_STRING([--disable-nonblocking],[Disable non-blocking communications]),
|
||||
OPT_NONBLOCKING=$enableval)
|
||||
case "$OPT_NONBLOCKING" in
|
||||
no)
|
||||
dnl --disable-nonblocking option used
|
||||
want_nonblocking="no"
|
||||
;;
|
||||
default)
|
||||
dnl configure option not specified
|
||||
want_nonblocking="yes"
|
||||
;;
|
||||
*)
|
||||
dnl --enable-nonblocking option used
|
||||
want_nonblocking="yes"
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$want_nonblocking])
|
||||
])
|
||||
|
||||
|
||||
dnl CURL_CHECK_OPTION_OPTIMIZE
|
||||
dnl -------------------------------------------------
|
||||
dnl Verify if configure has been invoked with option
|
||||
@@ -421,7 +388,6 @@ dnl -------------------------------------------------
|
||||
dnl Check for how to set a socket into non-blocking state.
|
||||
|
||||
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
|
||||
AC_REQUIRE([CURL_CHECK_OPTION_NONBLOCKING])dnl
|
||||
AC_REQUIRE([CURL_CHECK_FUNC_FCNTL])dnl
|
||||
AC_REQUIRE([CURL_CHECK_FUNC_IOCTL])dnl
|
||||
AC_REQUIRE([CURL_CHECK_FUNC_IOCTLSOCKET])dnl
|
||||
@@ -429,28 +395,22 @@ AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET], [
|
||||
AC_REQUIRE([CURL_CHECK_FUNC_SETSOCKOPT])dnl
|
||||
#
|
||||
tst_method="unknown"
|
||||
if test "$want_nonblocking" = "yes"; then
|
||||
AC_MSG_CHECKING([how to set a socket into non-blocking mode])
|
||||
if test "x$ac_cv_func_fcntl_o_nonblock" = "xyes"; then
|
||||
tst_method="fcntl O_NONBLOCK"
|
||||
elif test "x$ac_cv_func_ioctl_fionbio" = "xyes"; then
|
||||
tst_method="ioctl FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_fionbio" = "xyes"; then
|
||||
tst_method="ioctlsocket FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_camel_fionbio" = "xyes"; then
|
||||
tst_method="IoctlSocket FIONBIO"
|
||||
elif test "x$ac_cv_func_setsockopt_so_nonblock" = "xyes"; then
|
||||
tst_method="setsockopt SO_NONBLOCK"
|
||||
fi
|
||||
AC_MSG_RESULT([$tst_method])
|
||||
if test "$tst_method" = "unknown"; then
|
||||
AC_MSG_WARN([cannot determine non-blocking socket method.])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([how to set a socket into non-blocking mode])
|
||||
if test "x$ac_cv_func_fcntl_o_nonblock" = "xyes"; then
|
||||
tst_method="fcntl O_NONBLOCK"
|
||||
elif test "x$ac_cv_func_ioctl_fionbio" = "xyes"; then
|
||||
tst_method="ioctl FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_fionbio" = "xyes"; then
|
||||
tst_method="ioctlsocket FIONBIO"
|
||||
elif test "x$ac_cv_func_ioctlsocket_camel_fionbio" = "xyes"; then
|
||||
tst_method="IoctlSocket FIONBIO"
|
||||
elif test "x$ac_cv_func_setsockopt_so_nonblock" = "xyes"; then
|
||||
tst_method="setsockopt SO_NONBLOCK"
|
||||
fi
|
||||
AC_MSG_RESULT([$tst_method])
|
||||
if test "$tst_method" = "unknown"; then
|
||||
AC_DEFINE_UNQUOTED(USE_BLOCKING_SOCKETS, 1,
|
||||
[Define to disable non-blocking sockets.])
|
||||
AC_MSG_WARN([non-blocking sockets disabled.])
|
||||
AC_MSG_WARN([cannot determine non-blocking socket method.])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ EXTRA_DIST = README \
|
||||
DOS/README \
|
||||
DOS/common.dj \
|
||||
NetWare/get_ver.awk \
|
||||
NetWare/get_exp.awk \
|
||||
OS400/README.OS400 \
|
||||
OS400/ccsidcurl.c \
|
||||
OS400/ccsidcurl.h \
|
||||
|
||||
@@ -73,6 +73,7 @@ options:
|
||||
CURLOPT_COPYPOSTFIELDS
|
||||
CURLOPT_CRLFILE
|
||||
CURLOPT_CUSTOMREQUEST
|
||||
CURLOPT_DNS_SERVERS
|
||||
CURLOPT_EGDSOCKET
|
||||
CURLOPT_ENCODING
|
||||
CURLOPT_FTP_ACCOUNT
|
||||
@@ -83,6 +84,7 @@ options:
|
||||
CURLOPT_KEYPASSWD
|
||||
CURLOPT_KRBLEVEL
|
||||
CURLOPT_MAIL_FROM
|
||||
CURLOPT_MAIL_AUTH
|
||||
CURLOPT_NETRC_FILE
|
||||
CURLOPT_NOPROXY
|
||||
CURLOPT_PASSWORD
|
||||
|
||||
@@ -1032,7 +1032,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
||||
#ifdef USE_TLS_SRP
|
||||
if ((int) STRING_LAST != (int) STRING_TLSAUTH_PASSWORD + 1)
|
||||
#else
|
||||
if ((int) STRING_LAST != (int) STRING_MAIL_FROM + 1)
|
||||
if ((int) STRING_LAST != (int) STRING_MAIL_AUTH + 1)
|
||||
#endif
|
||||
curl_mfprintf(stderr,
|
||||
"*** WARNING: curl_easy_setopt_ccsid() should be reworked ***\n");
|
||||
@@ -1051,6 +1051,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
||||
case CURLOPT_COOKIELIST:
|
||||
case CURLOPT_CRLFILE:
|
||||
case CURLOPT_CUSTOMREQUEST:
|
||||
case CURLOPT_DNS_SERVERS:
|
||||
case CURLOPT_EGDSOCKET:
|
||||
case CURLOPT_ENCODING:
|
||||
case CURLOPT_FTP_ACCOUNT:
|
||||
@@ -1061,6 +1062,7 @@ curl_easy_setopt_ccsid(CURL * curl, CURLoption tag, ...)
|
||||
case CURLOPT_KEYPASSWD:
|
||||
case CURLOPT_KRBLEVEL:
|
||||
case CURLOPT_MAIL_FROM:
|
||||
case CURLOPT_MAIL_AUTH:
|
||||
case CURLOPT_NETRC_FILE:
|
||||
case CURLOPT_NOPROXY:
|
||||
case CURLOPT_PASSWORD:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user