Compare commits
38 Commits
HTTPS-prox
...
curl-7_46_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e2ae32ff5f | ||
![]() |
6623a485d3 | ||
![]() |
940c2f51aa | ||
![]() |
a47137c4a5 | ||
![]() |
5648f0a32c | ||
![]() |
2fddc4e3e1 | ||
![]() |
e55f15454e | ||
![]() |
fe7c39d353 | ||
![]() |
8f281fb76d | ||
![]() |
8cbd80686e | ||
![]() |
a14fa8f8ff | ||
![]() |
81ae6d01fa | ||
![]() |
19a8afb3c0 | ||
![]() |
78c25c854a | ||
![]() |
db05d7a731 | ||
![]() |
cd2b73b3ed | ||
![]() |
5b96b5e79e | ||
![]() |
99d17a5e2b | ||
![]() |
facf2925c7 | ||
![]() |
be0d4141af | ||
![]() |
40c349ada9 | ||
![]() |
bb9ec5ebb2 | ||
![]() |
c341311a0e | ||
![]() |
fc5d783589 | ||
![]() |
98acebb526 | ||
![]() |
06b288a72d | ||
![]() |
d55f9071fb | ||
![]() |
b7f3f1b68f | ||
![]() |
c2f1730e17 | ||
![]() |
8d17117683 | ||
![]() |
c90e348579 | ||
![]() |
f024ece8c7 | ||
![]() |
ad6f6e17d3 | ||
![]() |
0ddc59be0a | ||
![]() |
bbb34b6f15 | ||
![]() |
41efdadf09 | ||
![]() |
6af80afe49 | ||
![]() |
80562083da |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,3 +49,4 @@ missing
|
||||
mkinstalldirs
|
||||
tags
|
||||
test-driver
|
||||
scripts/_curl
|
||||
|
@@ -140,7 +140,7 @@ CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
SUBDIRS = lib src include
|
||||
SUBDIRS = lib src include scripts
|
||||
DIST_SUBDIRS = $(SUBDIRS) tests packages docs
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
@@ -160,10 +160,10 @@ dist-hook:
|
||||
done)
|
||||
|
||||
html:
|
||||
cd docs; make html
|
||||
cd docs && make html
|
||||
|
||||
pdf:
|
||||
cd docs; make pdf
|
||||
cd docs && make pdf
|
||||
|
||||
check: test examples check-docs
|
||||
|
||||
|
@@ -4,7 +4,7 @@ Curl and libcurl 7.46.0
|
||||
Command line options: 177
|
||||
curl_easy_setopt() options: 221
|
||||
Public functions in libcurl: 61
|
||||
Contributors: 1322
|
||||
Contributors: 1340
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
@@ -68,6 +68,25 @@ This release includes the following bugfixes:
|
||||
o typecheck-gcc.h: add some missing options
|
||||
o curl: mark two more options strings for --libcurl output
|
||||
o openssl: Free modules on cleanup [20]
|
||||
o CURLMOPT_PUSHFUNCTION.3: *_byname() returns only the first header
|
||||
o getconnectinfo: Don't call recv(2) if socket == -1
|
||||
o http2: http_done: don't free already-freed push headers
|
||||
o zsh completion: Preserve single quotes in output [21]
|
||||
o os400: Provide options for libssh2 use in compile scripts.
|
||||
o build: Fix theoretical infinite loops [22]
|
||||
o pop3: Differentiate between success and continuation responses
|
||||
o examples: Fixed compilation warnings
|
||||
o schannel: Use GetVersionEx() when VerifyVersionInfo() isn't available
|
||||
o CURLOPT_HEADERFUNCTION.3: fix typo
|
||||
o curl: expanded the -XHEAD warning text
|
||||
o done: make sure the final progress update is made [23]
|
||||
o build: Install zsh completion [24]
|
||||
o RTSP: do not add if-modified-since without timecondition [25]
|
||||
o curl: Fixed display of URL index in password prompt for --next
|
||||
o nonblock: fix setting non-blocking mode for Amiga [26]
|
||||
o http2 push: add missing inits of new stream [27]
|
||||
o http2: convert some verbose output into debug-only output
|
||||
o Curl_read_plain: clean up ifdefs that break statements [28]
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -76,13 +95,15 @@ 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:
|
||||
|
||||
Anders Bakken, Dan Fandrich, Daniel Hwang, Daniel Stenberg, Dmitry S. Baikov,
|
||||
Douglas Creager, Erik Johansson, Gisle Vanem, Javier G. Sogo, John Levon,
|
||||
Jonas Minnberg, Justin Ehlert, Kamil Dudka, Kang Lin, Kurt Fankhauser,
|
||||
Lauri Kasanen, Marcel Raad, Patrick Monnerat, Rainer Jung, Ray Satiro,
|
||||
Richard Hosking, Sebastian Pohlschmidt, Stefan Bühler, Steve Holme,
|
||||
Svyatoslav Mishyn, Tatsuhiro Tsujikawa, Tim Rühsen, xiangbin li,
|
||||
(28 contributors)
|
||||
Anders Bakken, Dan Fandrich, Daniel Hwang, Daniel Shahaf, Daniel Stenberg,
|
||||
Davey Shafik, Dmitry S. Baikov, Douglas Creager, Erik Johansson,
|
||||
Flavio Medeiros, Gisle Vanem, Javier G. Sogo, John Levon, Jonas Minnberg,
|
||||
Justin Ehlert, Kamil Dudka, Kang Lin, Kurt Fankhauser, Lauri Kasanen,
|
||||
Lukas Ruzicka, Marcel Raad, Michał Piechowski, Mohammad AlSaleh, Norbert Kett,
|
||||
Patrick Monnerat, Rainer Jung, Ray Satiro, Richard Hosking,
|
||||
Sebastian Pohlschmidt, Stefan Bühler, Steve Holme, Svyatoslav Mishyn,
|
||||
Tatsuhiro Tsujikawa, Tim Rühsen, Xiangbin Li,
|
||||
(35 contributors)
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
@@ -108,3 +129,11 @@ References to bug reports and discussions on issues:
|
||||
[18] = http://curl.haxx.se/bug/?i=523
|
||||
[19] = http://curl.haxx.se/bug/?i=525
|
||||
[20] = http://curl.haxx.se/bug/?i=526
|
||||
[21] = http://curl.haxx.se/bug/?i=532
|
||||
[22] = http://curl.haxx.se/bug/?i=535
|
||||
[23] = http://curl.haxx.se/bug/?i=538
|
||||
[24] = http://curl.haxx.se/bug/?i=534
|
||||
[25] = http://stackoverflow.com/questions/33903982/curl-timecond-none-doesnt-work-how-to-remove-if-modified-since-header
|
||||
[26] = http://curl.haxx.se/mail/lib-2015-11/0088.html
|
||||
[27] = http://curl.haxx.se/bug/?i=530
|
||||
[28] = http://curl.haxx.se/bug/?i=546
|
||||
|
26
configure.ac
26
configure.ac
@@ -3030,6 +3030,31 @@ if test X"$want_h2" != Xno; then
|
||||
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for zsh completion path
|
||||
dnl **********************************************************************
|
||||
|
||||
OPT_ZSH_FPATH=default
|
||||
AC_ARG_WITH(zsh-functions-dir,
|
||||
AC_HELP_STRING([--with-zsh-functions-dir=PATH],[Install zsh completions to PATH])
|
||||
AC_HELP_STRING([--without-zsh-functions-dir],[Do not install zsh completions]),
|
||||
[OPT_ZSH_FPATH=$withval])
|
||||
case "$OPT_ZSH_FPATH" in
|
||||
no)
|
||||
dnl --without-zsh-functions-dir option used
|
||||
;;
|
||||
default|yes)
|
||||
dnl --with-zsh-functions-dir option used without path
|
||||
ZSH_FUNCTIONS_DIR="$datarootdir/zsh/site-functions"
|
||||
AC_SUBST(ZSH_FUNCTIONS_DIR)
|
||||
;;
|
||||
*)
|
||||
dnl --with-zsh-functions-dir option used with path
|
||||
ZSH_FUNCTIONS_DIR="$withval"
|
||||
AC_SUBST(ZSH_FUNCTIONS_DIR)
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Back to "normal" configuring
|
||||
dnl **********************************************************************
|
||||
@@ -3797,6 +3822,7 @@ AC_CONFIG_FILES([Makefile \
|
||||
include/curl/Makefile \
|
||||
src/Makefile \
|
||||
lib/Makefile \
|
||||
scripts/Makefile \
|
||||
lib/libcurl.vers \
|
||||
tests/Makefile \
|
||||
tests/certs/Makefile \
|
||||
|
@@ -45,10 +45,10 @@ MAN2HTML= roffit < $< >$@
|
||||
SUFFIXES = .1 .html .pdf
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
cd libcurl; make html
|
||||
cd libcurl && make html
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
cd libcurl; make pdf
|
||||
cd libcurl && make pdf
|
||||
|
||||
.1.html:
|
||||
$(MAN2HTML)
|
||||
|
20
docs/THANKS
20
docs/THANKS
@@ -262,6 +262,7 @@ Daniel Lee Hwang
|
||||
Daniel Melani
|
||||
Daniel Mentz
|
||||
Daniel Seither
|
||||
Daniel Shahaf
|
||||
Daniel Steinberg
|
||||
Daniel Stenberg
|
||||
Daniel Theron
|
||||
@@ -275,6 +276,7 @@ Dave May
|
||||
Dave Reisner
|
||||
Dave Thompson
|
||||
Dave Vasilevsky
|
||||
Davey Shafik
|
||||
David Bau
|
||||
David Binderman
|
||||
David Blaikie
|
||||
@@ -328,12 +330,14 @@ Dmitry Falko
|
||||
Dmitry Kurochkin
|
||||
Dmitry Popov
|
||||
Dmitry Rechkin
|
||||
Dmitry S. Baikov
|
||||
Dolbneff A.V
|
||||
Domenico Andreoli
|
||||
Dominick Meglio
|
||||
Dominique Leuenberger
|
||||
Doug Kaufman
|
||||
Doug Porter
|
||||
Douglas Creager
|
||||
Douglas E. Wegscheid
|
||||
Douglas Kilpatrick
|
||||
Douglas R. Horner
|
||||
@@ -398,6 +402,7 @@ Feist Josselin
|
||||
Felix Yan
|
||||
Felix von Leitner
|
||||
Feng Tu
|
||||
Flavio Medeiros
|
||||
Florian Schoppmann
|
||||
Florian Weimer
|
||||
Forrest Cahoon
|
||||
@@ -549,6 +554,7 @@ Jason Liu
|
||||
Jason McDonald
|
||||
Jason S. Priebe
|
||||
Javier Barroso
|
||||
Javier G. Sogo
|
||||
Jay Austin
|
||||
Jayesh A Shah
|
||||
Jaz Fresh
|
||||
@@ -615,6 +621,7 @@ John Janssen
|
||||
John Joseph Bachir
|
||||
John Kelly
|
||||
John Lask
|
||||
John Levon
|
||||
John Lightsey
|
||||
John Marino
|
||||
John Marshall
|
||||
@@ -633,6 +640,7 @@ Jon Torrey
|
||||
Jon Travis
|
||||
Jon Turner
|
||||
Jonas Forsman
|
||||
Jonas Minnberg
|
||||
Jonas Schnelli
|
||||
Jonatan Lander
|
||||
Jonatan Vela
|
||||
@@ -661,6 +669,7 @@ Julien Nabet
|
||||
Julien Royer
|
||||
Jun-ichiro itojun Hagino
|
||||
Jurij Smakov
|
||||
Justin Ehlert
|
||||
Justin Fletcher
|
||||
Justin Karneges
|
||||
Justin Maggard
|
||||
@@ -672,6 +681,7 @@ Kai Sommerfeld
|
||||
Kai-Uwe Rommel
|
||||
Kalle Vahlman
|
||||
Kamil Dudka
|
||||
Kang Lin
|
||||
Kang-Jin Lee
|
||||
Karl Moerder
|
||||
Karol Pietrzak
|
||||
@@ -703,6 +713,7 @@ Krishnendu Majumdar
|
||||
Krister Johansen
|
||||
Kristian Gunstone
|
||||
Kristian Köhntopp
|
||||
Kurt Fankhauser
|
||||
Kyle J. McKay
|
||||
Kyle L. Huff
|
||||
Kyle Sallee
|
||||
@@ -719,6 +730,7 @@ Lars Nilsson
|
||||
Lars Torben Wilson
|
||||
Lau Hang Kin
|
||||
Laurent Rabret
|
||||
Lauri Kasanen
|
||||
Legoff Vincent
|
||||
Lehel Bernadt
|
||||
Leif W
|
||||
@@ -747,6 +759,7 @@ Lucas Adamski
|
||||
Lucas Pardue
|
||||
Ludek Finstrle
|
||||
Ludovico Cavedon
|
||||
Lukas Ruzicka
|
||||
Lukasz Czekierda
|
||||
Luke Amery
|
||||
Luke Call
|
||||
@@ -855,6 +868,7 @@ Michal Marek
|
||||
Michał Fita
|
||||
Michał Górny
|
||||
Michał Kowalczyk
|
||||
Michał Piechowski
|
||||
Michel Promonet
|
||||
Michele Bini
|
||||
Miguel Angel
|
||||
@@ -913,6 +927,7 @@ Nis Jorgensen
|
||||
Nobuhiro Ban
|
||||
Nodak Sodak
|
||||
Norbert Frese
|
||||
Norbert Kett
|
||||
Norbert Novotny
|
||||
Ofer
|
||||
Ola Mork
|
||||
@@ -1049,6 +1064,7 @@ Richard Bramante
|
||||
Richard Clayton
|
||||
Richard Cooper
|
||||
Richard Gorton
|
||||
Richard Hosking
|
||||
Richard Michael
|
||||
Richard Moore
|
||||
Richard Prescott
|
||||
@@ -1122,6 +1138,7 @@ Scott Cantor
|
||||
Scott Davis
|
||||
Scott McCreary
|
||||
Sean Boudreau
|
||||
Sebastian Pohlschmidt
|
||||
Sebastian Rasmussen
|
||||
Senthil Raja Velu
|
||||
Sergei Nikulov
|
||||
@@ -1213,7 +1230,7 @@ Tim Costello
|
||||
Tim Harder
|
||||
Tim Heckman
|
||||
Tim Newsome
|
||||
Tim Ruehsen
|
||||
Tim Rühsen
|
||||
Tim Sneddon
|
||||
Tim Stack
|
||||
Tim Starling
|
||||
@@ -1302,6 +1319,7 @@ Wojciech Zwiefka
|
||||
Wouter Van Rooy
|
||||
Wu Yongzheng
|
||||
Xavier Bouchoux
|
||||
Xiangbin Li
|
||||
Yaakov Selkowitz
|
||||
Yamada Yasuharu
|
||||
Yang Tse
|
||||
|
@@ -51,3 +51,4 @@ s/Viktor Szakats/Viktor Szakáts/
|
||||
s/Jonathan Cardoso/Jonathan Cardoso Machado/
|
||||
s/Linus Nielsen/Linus Nielsen Feltzing/
|
||||
s/Todd Ouska$/Todd A Ouska/
|
||||
s/Tim Ruehsen/Tim Rühsen/
|
||||
|
97
docs/TODO
97
docs/TODO
@@ -27,11 +27,16 @@
|
||||
1.9 Cache negative name resolves
|
||||
1.10 Support IDNA2008
|
||||
1.11 minimize dependencies with dynamicly loaded modules
|
||||
1.12 have form functions use CURL handle argument
|
||||
1.13 Add CURLOPT_MAIL_CLIENT option
|
||||
1.14 Typesafe curl_easy_setopt()
|
||||
1.15 TCP Fast Open
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
2.2 Fix HTTP Pipelining for PUT
|
||||
2.3 Better support for same name resolves
|
||||
2.2 Better support for same name resolves
|
||||
2.3 Non-blocking curl_multi_remove_handle()
|
||||
2.4 Split connect and authentication process
|
||||
|
||||
3. Documentation
|
||||
3.1 Update date and version in man pages
|
||||
@@ -141,8 +146,6 @@
|
||||
21.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
21.7 remove progress meter from libcurl
|
||||
21.8 remove 'curl_httppost' from public
|
||||
21.9 have form functions use CURL handle argument
|
||||
21.10 Add CURLOPT_MAIL_CLIENT option
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -236,6 +239,51 @@
|
||||
app/invoke/used protocols would be necessary to load. See
|
||||
https://github.com/bagder/curl/issues/349
|
||||
|
||||
1.12 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
|
||||
thus curl_formget() with callback cannot function without first having
|
||||
curl_easy_perform() (or similar) called - which is hard to grasp and a design
|
||||
mistake.
|
||||
|
||||
The curl_formadd() design can probably also be reconsidered to make it easier
|
||||
to use and less error-prone. Probably easiest by splitting it into several
|
||||
function calls.
|
||||
|
||||
1.13 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
|
||||
specifying this data as the URL is non-standard and to be honest a bit of a
|
||||
hack ;-)
|
||||
|
||||
Please see the following thread for more information:
|
||||
http://curl.haxx.se/mail/lib-2012-05/0178.html
|
||||
|
||||
1.14 Typesafe curl_easy_setopt()
|
||||
|
||||
One of the most common problems in libcurl using applications is the lack of
|
||||
type checks for curl_easy_setopt() which happens because it accepts varargs
|
||||
and thus can take any type.
|
||||
|
||||
One possible solution to this is to introduce a few different versions of the
|
||||
setopt version for the different kinds of data you can set.
|
||||
|
||||
curl_easy_set_num() - sets a long value
|
||||
|
||||
curl_easy_set_large() - sets a curl_off_t value
|
||||
|
||||
curl_easy_set_ptr() - sets a pointer
|
||||
|
||||
curl_easy_set_cb() - sets a callback PLUS its callback data
|
||||
|
||||
1.15 TCP Fast Open
|
||||
|
||||
RFC 7413 defines how to include data already in the TCP SYN handshake to
|
||||
reduce latency.
|
||||
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
2.1 More non-blocking
|
||||
@@ -252,13 +300,7 @@
|
||||
- The "DONE" operation (post transfer protocol-specific actions) for the
|
||||
protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task.
|
||||
|
||||
2.2 Fix HTTP Pipelining for PUT
|
||||
|
||||
HTTP Pipelining can be a way to greatly enhance performance for multiple
|
||||
serial requests and currently libcurl only supports that for HEAD and GET
|
||||
requests but it should also be possible for PUT.
|
||||
|
||||
2.3 Better support for same name resolves
|
||||
2.2 Better support for same name resolves
|
||||
|
||||
If a name resolve has been initiated for name NN and a second easy handle
|
||||
wants to resolve that name as well, make it wait for the first resolve to end
|
||||
@@ -266,6 +308,20 @@
|
||||
especially needed when adding many simultaneous handles using the same host
|
||||
name when the DNS resolver can get flooded.
|
||||
|
||||
2.3 Non-blocking curl_multi_remove_handle()
|
||||
|
||||
The multi interface has a few API calls that assume a blocking behavior, like
|
||||
add_handle() and remove_handle() which limits what we can do internally. The
|
||||
multi API need to be moved even more into a single function that "drives"
|
||||
everything in a non-blocking manner and signals when something is done. A
|
||||
remove or add would then only ask for the action to get started and then
|
||||
multi_perform() etc still be called until the add/remove is completed.
|
||||
|
||||
2.4 Split connect and authentication process
|
||||
|
||||
The multi interface treats the authentication process as part of the connect
|
||||
phase. As such any failures during authentication won't trigger the relevant
|
||||
QUIT or LOGOFF for protocols such as IMAP, POP3 and SMTP.
|
||||
|
||||
3. Documentation
|
||||
|
||||
@@ -815,22 +871,3 @@ Currently the SMB authentication uses NTLMv1.
|
||||
|
||||
Changing them to return a private handle will benefit the implementation and
|
||||
allow us much greater freedoms while still maintaining a solid API and ABI.
|
||||
|
||||
21.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
|
||||
thus curl_formget() with callback cannot function without first having
|
||||
curl_easy_perform() (or similar) called - which is hard to grasp and a design
|
||||
mistake.
|
||||
|
||||
21.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
|
||||
specifying this data as the URL is non-standard and to be honest a bit of a
|
||||
hack ;-)
|
||||
|
||||
Please see the following thread for more information:
|
||||
http://curl.haxx.se/mail/lib-2012-05/0178.html
|
||||
|
||||
|
4
docs/examples/.gitignore
vendored
4
docs/examples/.gitignore
vendored
@@ -73,3 +73,7 @@ smtp-vrfy
|
||||
url2file
|
||||
usercertinmem
|
||||
xmlstream
|
||||
http2-download
|
||||
http2-serverpush
|
||||
http2-upload
|
||||
imap-lsub
|
||||
|
@@ -32,51 +32,7 @@ actually torture our web site with your tests! Thanks.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
anyauthput.c - HTTP PUT using "any" authentication method
|
||||
cacertinmem.c - Use a built-in PEM certificate to retrieve a https page
|
||||
cookie_interface.c - shows usage of simple cookie interface
|
||||
curlgtk.c - download using a GTK progress bar
|
||||
curlx.c - getting file info from the remote cert data
|
||||
debug.c - showing how to use the debug callback
|
||||
fileupload.c - uploading to a file:// URL
|
||||
fopen.c - fopen() layer that supports opening URLs and files
|
||||
ftpget.c - simple getting a file from FTP
|
||||
ftpgetresp.c - get the response strings from the FTP server
|
||||
ftpupload.c - upload a file to an FTP server
|
||||
ftpuploadresume.c - resume an upload to an FTP server
|
||||
getinfo.c - get the Content-Type from the recent transfer
|
||||
getinmemory.c - download a file to memory only
|
||||
ghiper.c - curl_multi_socket() using code with glib-2
|
||||
hiperfifo.c - downloads all URLs written to the fifo, using
|
||||
curl_multi_socket() and libevent
|
||||
htmltidy.c - download a document and use libtidy to parse the HTML
|
||||
htmltitle.cc - download a HTML file and extract the <title> tag from a HTML
|
||||
page using libxml
|
||||
http-post.c - HTTP POST
|
||||
httpput.c - HTTP PUT a local file
|
||||
https.c - simple HTTPS transfer
|
||||
imap.c - simple IMAP transfer
|
||||
multi-app.c - a multi-interface app
|
||||
multi-debugcallback.c - a multi-interface app using the debug callback
|
||||
multi-double.c - a multi-interface app doing two simultaneous transfers
|
||||
multi-post.c - a multi-interface app doing a multipart formpost
|
||||
multi-single.c - a multi-interface app getting a single file
|
||||
multi-uv.c - a multi-interface app using libuv
|
||||
multithread.c - an example using multi-treading transferring multiple files
|
||||
opensslthreadlock.c - show how to do locking when using OpenSSL multi-threaded
|
||||
persistant.c - request two URLs with a persistent connection
|
||||
pop3s.c - POP3S transfer
|
||||
pop3slist.c - POP3S LIST
|
||||
post-callback.c - send a HTTP POST using a callback
|
||||
postit2.c - send a HTTP multipart formpost
|
||||
sampleconv.c - showing how a program on a non-ASCII platform would invoke
|
||||
callbacks to do its own codeset conversions instead of using
|
||||
the built-in iconv functions in libcurl
|
||||
sepheaders.c - download headers to a separate file
|
||||
simple.c - the most simple download a URL source
|
||||
simplepost.c - HTTP POST
|
||||
simplessl.c - HTTPS example with certificates many options set
|
||||
synctime.c - Sync local time by extracting date from remote HTTP servers
|
||||
url2file.c - download a document and store it in a file
|
||||
xmlstream.c - Stream-parse a document using the streaming Expat parser
|
||||
10-at-a-time.c - Download many files simultaneously, 10 at a time.
|
||||
Each example source code file is designed to be and work stand-alone and
|
||||
rather self-explanatory. The examples may at times lack the level of error
|
||||
checks you need in a real world, but that is then only for the sake of
|
||||
readability: to make the code smaller and easier to follow.
|
||||
|
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@@ -19,10 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* Simple IMAP APPEND use
|
||||
* IMAP example showing how to send e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to copy an e-mail from one folder to another
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to create a new folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to delete a folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to obtain information about a folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to retreieve e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example to list the folders within a mailbox
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example to list the subscribed folders
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,14 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using the multi interface
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to perform a noop
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to search for new e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using SSL
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to modify the properties of an e-mail
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using TLS
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to delete e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example to list the contents of a mailbox
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,14 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using the multi interface
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to perform a noop
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to retrieve e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using SSL
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to obtain message statistics
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using TLS
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to retreive only the headers of an e-mail
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example to list the contents of a mailbox by unique ID
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,11 +19,17 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example showing how to expand an e-mail mailing list
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to expand an email mailing list.
|
||||
/* This is a simple example showing how to expand an e-mail mailing list.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example showing how to send e-mails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example using the multi interface
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example using SSL
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,6 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example using TLS
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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,11 +19,17 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* SMTP example showing how to verify an e-mail address
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to verify an email address from an
|
||||
/* This is a simple example showing how to verify an e-mail address from an
|
||||
* SMTP server.
|
||||
*
|
||||
* Notes:
|
||||
|
@@ -99,13 +99,13 @@ libcurl-symbols.3: $(srcdir)/symbols-in-versions $(srcdir)/mksymbolsmanpage.pl
|
||||
perl $(srcdir)/mksymbolsmanpage.pl < $(srcdir)/symbols-in-versions > $@
|
||||
|
||||
html: $(HTMLPAGES)
|
||||
cd opts; make html
|
||||
cd opts && make html
|
||||
|
||||
.3.html:
|
||||
$(MAN2HTML)
|
||||
|
||||
pdf: $(PDFPAGES)
|
||||
cd opts; make pdf
|
||||
cd opts && make pdf
|
||||
|
||||
.3.pdf:
|
||||
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
|
||||
|
@@ -85,7 +85,7 @@ static size_t header_callback(char *buffer, size_t size,
|
||||
size_t nitems, void *userdata)
|
||||
{
|
||||
/* received header is nitems * size long in 'buffer' NOT ZERO TERMINATED */
|
||||
/* 'userdata' is set with CURLOPT_WRITEDATA */
|
||||
/* 'userdata' is set with CURLOPT_HEADERDATA */
|
||||
return nitems * size;
|
||||
}
|
||||
|
||||
|
@@ -237,7 +237,6 @@ CURLINFO_PRIMARY_IP 7.19.0
|
||||
CURLINFO_PRIMARY_PORT 7.21.0
|
||||
CURLINFO_PRIVATE 7.10.3
|
||||
CURLINFO_PROXYAUTH_AVAIL 7.10.8
|
||||
CURLINFO_PROXY_SSL_VERIFYRESULT 7.44.0
|
||||
CURLINFO_REDIRECT_COUNT 7.9.7
|
||||
CURLINFO_REDIRECT_TIME 7.9.7
|
||||
CURLINFO_REDIRECT_URL 7.18.2
|
||||
@@ -463,23 +462,7 @@ CURLOPT_PROXYPORT 7.1
|
||||
CURLOPT_PROXYTYPE 7.10
|
||||
CURLOPT_PROXYUSERNAME 7.19.1
|
||||
CURLOPT_PROXYUSERPWD 7.1
|
||||
CURLOPT_PROXY_CAINFO 7.44.0
|
||||
CURLOPT_PROXY_CAPATH 7.44.0
|
||||
CURLOPT_PROXY_CRLFILE 7.44.0
|
||||
CURLOPT_PROXY_KEYPASSWD 7.44.0
|
||||
CURLOPT_PROXY_SERVICE_NAME 7.43.0
|
||||
CURLOPT_PROXY_SSLCERT 7.44.0
|
||||
CURLOPT_PROXY_SSLCERTTYPE 7.44.0
|
||||
CURLOPT_PROXY_SSLKEY 7.44.0
|
||||
CURLOPT_PROXY_SSLKEYTYPE 7.44.0
|
||||
CURLOPT_PROXY_SSLVERSION 7.44.0
|
||||
CURLOPT_PROXY_SSL_CIPHER_LIST 7.44.0
|
||||
CURLOPT_PROXY_SSL_OPTIONS 7.44.0
|
||||
CURLOPT_PROXY_SSL_VERIFYHOST 7.44.0
|
||||
CURLOPT_PROXY_SSL_VERIFYPEER 7.44.0
|
||||
CURLOPT_PROXY_TLSAUTH_PASSWORD 7.44.0
|
||||
CURLOPT_PROXY_TLSAUTH_TYPE 7.44.0
|
||||
CURLOPT_PROXY_TLSAUTH_USERNAME 7.44.0
|
||||
CURLOPT_PROXY_TRANSFER_MODE 7.18.0
|
||||
CURLOPT_PUT 7.1
|
||||
CURLOPT_QUOTE 7.1
|
||||
@@ -509,8 +492,6 @@ CURLOPT_SOCKOPTDATA 7.16.0
|
||||
CURLOPT_SOCKOPTFUNCTION 7.16.0
|
||||
CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4
|
||||
CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4
|
||||
CURLOPT_SOCKS_PROXY 7.44.0
|
||||
CURLOPT_SOCKS_PROXYTYPE 7.44.0
|
||||
CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5
|
||||
CURLOPT_SOURCE_PATH 7.12.1 - 7.15.5
|
||||
CURLOPT_SOURCE_PORT 7.12.1 - 7.15.5
|
||||
@@ -622,7 +603,6 @@ CURLPROTO_TELNET 7.19.4
|
||||
CURLPROTO_TFTP 7.19.4
|
||||
CURLPROXY_HTTP 7.10
|
||||
CURLPROXY_HTTP_1_0 7.19.4
|
||||
CURLPROXY_HTTPS 7.44.0
|
||||
CURLPROXY_SOCKS4 7.10
|
||||
CURLPROXY_SOCKS4A 7.18.0
|
||||
CURLPROXY_SOCKS5 7.10
|
||||
|
@@ -622,7 +622,6 @@ typedef enum {
|
||||
CONNECT HTTP/1.1 */
|
||||
CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT
|
||||
HTTP/1.0 */
|
||||
CURLPROXY_HTTPS = 2, /* added in TBD */
|
||||
CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
|
||||
in 7.10 */
|
||||
CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
|
||||
@@ -1189,8 +1188,7 @@ typedef enum {
|
||||
CINIT(SHARE, OBJECTPOINT, 100),
|
||||
|
||||
/* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
|
||||
CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
|
||||
CURLPROXY_SOCKS5. */
|
||||
CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
|
||||
CINIT(PROXYTYPE, LONG, 101),
|
||||
|
||||
/* Set the Accept-Encoding string. Use this to tell a server you would like
|
||||
@@ -1674,70 +1672,6 @@ typedef enum {
|
||||
/* Set E-xclusive stream dependency on another CURL handle */
|
||||
CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
|
||||
|
||||
/* The CApath or CAfile used to validate the proxy certificate
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_CAINFO, STRINGPOINT, 242),
|
||||
|
||||
/* The CApath directory used to validate the proxy certificate
|
||||
this option is used only if PROXY_SSL_VERIFYPEER is true */
|
||||
CINIT(PROXY_CAPATH, STRINGPOINT, 243),
|
||||
|
||||
/* Set if we should verify the proxy in ssl handshake,
|
||||
set 1 to verify. */
|
||||
CINIT(PROXY_SSL_VERIFYPEER, LONG, 244),
|
||||
|
||||
/* Set if we should verify the Common name from the proxy certificate in ssl
|
||||
* handshake, set 1 to check existence, 2 to ensure that it matches
|
||||
* the provided hostname. */
|
||||
CINIT(PROXY_SSL_VERIFYHOST, LONG, 245),
|
||||
|
||||
/* What version to specifically try to use for proxy.
|
||||
See CURL_SSLVERSION defines below. */
|
||||
CINIT(PROXY_SSLVERSION, LONG, 246),
|
||||
|
||||
/* Set a username for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 247),
|
||||
|
||||
/* Set a password for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 248),
|
||||
|
||||
/* Set authentication type for authenticated TLS for proxy */
|
||||
CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 249),
|
||||
|
||||
/* name of the file keeping your private SSL-certificate for proxy */
|
||||
CINIT(PROXY_SSLCERT, STRINGPOINT, 250),
|
||||
|
||||
/* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
|
||||
proxy */
|
||||
CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 251),
|
||||
|
||||
/* name of the file keeping your private SSL-key for proxy */
|
||||
CINIT(PROXY_SSLKEY, STRINGPOINT, 252),
|
||||
|
||||
/* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
|
||||
proxy */
|
||||
CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 253),
|
||||
|
||||
/* password for the SSL private key for proxy */
|
||||
CINIT(PROXY_KEYPASSWD, STRINGPOINT, 254),
|
||||
|
||||
/* Specify which SSL ciphers to use for proxy */
|
||||
CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 255),
|
||||
|
||||
/* CRL file for proxy */
|
||||
CINIT(PROXY_CRLFILE, STRINGPOINT, 256),
|
||||
|
||||
/* Enable/disable specific SSL features with a bitmask for proxy, see
|
||||
CURLSSLOPT_* */
|
||||
CINIT(PROXY_SSL_OPTIONS, LONG, 257),
|
||||
|
||||
/* Name of socks proxy to use. */
|
||||
CINIT(SOCKS_PROXY, STRINGPOINT, 258),
|
||||
|
||||
/* indicates type of proxy. accepted values are CURLPROXY_SOCKS4,
|
||||
CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
|
||||
CINIT(SOCKS_PROXYTYPE, LONG, 259),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -2233,10 +2167,9 @@ typedef enum {
|
||||
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
||||
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
|
||||
CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44,
|
||||
CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 45,
|
||||
/* Fill in new entries below here! */
|
||||
|
||||
CURLINFO_LASTONE = 45
|
||||
CURLINFO_LASTONE = 44
|
||||
} CURLINFO;
|
||||
|
||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||
|
@@ -416,6 +416,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
if(result)
|
||||
/* close the connection, since we can't return failure here without
|
||||
cleaning up this connection properly.
|
||||
TODO: remove this action from here, it is not a name resolver decision.
|
||||
*/
|
||||
connclose(conn, "c-ares resolve failed");
|
||||
|
||||
|
@@ -133,9 +133,7 @@ void Curl_conncache_destroy(struct conncache *connc)
|
||||
static char *hashkey(struct connectdata *conn)
|
||||
{
|
||||
return aprintf("%s:%d",
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.name :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.name :
|
||||
conn->host.name,
|
||||
conn->bits.proxy?conn->proxy.name:conn->host.name,
|
||||
conn->localport);
|
||||
}
|
||||
|
||||
|
@@ -850,8 +850,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
}
|
||||
|
||||
failf(data, "Failed to connect to %s port %ld: %s",
|
||||
conn->bits.socksproxy ? conn->socks_proxy.host.name :
|
||||
conn->bits.httpproxy ? conn->http_proxy.host.name : conn->host.name,
|
||||
conn->bits.proxy?conn->proxy.name:conn->host.name,
|
||||
conn->port, Curl_strerror(conn, error));
|
||||
}
|
||||
|
||||
|
@@ -83,7 +83,8 @@ Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
int line, const char *source);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -39,7 +39,7 @@
|
||||
*
|
||||
* File lib/strdup.c is an exception, given that it provides a strdup
|
||||
* clone implementation while using malloc. Extra care needed inside
|
||||
* this one.
|
||||
* this one. TODO: revisit this paragraph and related code.
|
||||
*
|
||||
* The need for curl_memory.h inclusion is due to libcurl's feature
|
||||
* of allowing library user to provide memory replacement functions,
|
||||
|
@@ -137,8 +137,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@@ -350,7 +350,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
userp = conn->proxyuser;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@@ -527,6 +527,7 @@
|
||||
# define CURLRES_ARES
|
||||
/* now undef the stock libc functions just to avoid them being used */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_FREEADDRINFO
|
||||
# undef HAVE_GETHOSTBYNAME
|
||||
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
|
@@ -646,7 +646,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
if(mcode)
|
||||
return CURLE_URL_MALFORMAT;
|
||||
return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
|
||||
|
||||
/* we don't really care about the "msgs_in_queue" value returned in the
|
||||
second argument */
|
||||
|
130
lib/ftp.c
130
lib/ftp.c
@@ -491,7 +491,7 @@ static CURLcode InitiateTransfer(struct connectdata *conn)
|
||||
struct FTP *ftp = data->req.protop;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->bits.ftp_use_data_ssl) {
|
||||
if(conn->ssl[SECONDARYSOCKET].use) {
|
||||
/* since we only have a plaintext TCP connection here, we must now
|
||||
* do the TLS stuff */
|
||||
infof(data, "Doing the SSL/TLS handshake on the data stream\n");
|
||||
@@ -732,7 +732,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
* wait for more data anyway.
|
||||
*/
|
||||
}
|
||||
else if(!Curl_ssl_data_pending(conn, FIRSTSOCKET)) {
|
||||
else {
|
||||
switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) {
|
||||
case -1: /* select() error, stop reading */
|
||||
failf(data, "FTP response aborted due to select/poll error: %d",
|
||||
@@ -1842,6 +1842,84 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the necessary magic that needs to be done once the TCP connection
|
||||
* to the proxy has completed.
|
||||
*/
|
||||
static CURLcode proxy_magic(struct connectdata *conn,
|
||||
char *newhost, unsigned short newport,
|
||||
bool *magicdone)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(CURL_DISABLE_PROXY)
|
||||
(void) newhost;
|
||||
(void) newport;
|
||||
#endif
|
||||
|
||||
*magicdone = FALSE;
|
||||
|
||||
switch(conn->proxytype) {
|
||||
case CURLPROXY_SOCKS5:
|
||||
case CURLPROXY_SOCKS5_HOSTNAME:
|
||||
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
|
||||
newport, SECONDARYSOCKET, conn);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_SOCKS4:
|
||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||
SECONDARYSOCKET, conn, FALSE);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_SOCKS4A:
|
||||
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
|
||||
SECONDARYSOCKET, conn, TRUE);
|
||||
*magicdone = TRUE;
|
||||
break;
|
||||
case CURLPROXY_HTTP:
|
||||
case CURLPROXY_HTTP_1_0:
|
||||
/* do nothing here. handled later. */
|
||||
break;
|
||||
default:
|
||||
failf(data, "unknown proxytype option given");
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
break;
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
/* BLOCKING */
|
||||
/* We want "seamless" FTP operations through HTTP proxy tunnel */
|
||||
|
||||
/* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
|
||||
* member conn->proto.http; we want FTP through HTTP and we have to
|
||||
* change the member temporarily for connecting to the HTTP proxy. After
|
||||
* Curl_proxyCONNECT we have to set back the member to the original
|
||||
* struct FTP pointer
|
||||
*/
|
||||
struct HTTP http_proxy;
|
||||
struct FTP *ftp_save = data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
data->req.protop = &http_proxy;
|
||||
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
|
||||
|
||||
data->req.protop = ftp_save;
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
|
||||
/* the CONNECT procedure is not complete, the tunnel is not yet up */
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
return result;
|
||||
}
|
||||
else
|
||||
*magicdone = TRUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *control_address(struct connectdata *conn)
|
||||
{
|
||||
@@ -1849,7 +1927,11 @@ static char *control_address(struct connectdata *conn)
|
||||
If a proxy tunnel is used, returns the original host name instead, because
|
||||
the effective control connection address is the proxy address,
|
||||
not the ftp host. */
|
||||
if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
return conn->host.name;
|
||||
|
||||
return conn->ip_addr_str;
|
||||
@@ -1973,9 +2055,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
* here. We don't want to rely on a former host lookup that might've
|
||||
* expired now, instead we remake the lookup here and now!
|
||||
*/
|
||||
const char * const host_name = conn->bits.socksproxy ?
|
||||
conn->socks_proxy.host.name : conn->http_proxy.host.name;
|
||||
rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
|
||||
rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
/* BLOCKING, ignores the return code but 'addr' will be NULL in
|
||||
case of failure */
|
||||
@@ -1985,7 +2065,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||
|
||||
if(!addr) {
|
||||
failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
|
||||
failf(data, "Can't resolve proxy host %s:%hu",
|
||||
conn->proxy.name, connectport);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
}
|
||||
}
|
||||
@@ -2026,10 +2107,6 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
|
||||
|
||||
Curl_safefree(conn->secondaryhostname);
|
||||
conn->secondaryhostname = strdup(ftpc->newhost);
|
||||
conn->secondary_port = ftpc->newport;
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
conn->bits.do_more = TRUE;
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
@@ -2678,10 +2755,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.use_ssl &&
|
||||
(!conn->ssl[FIRSTSOCKET].use ||
|
||||
(conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
|
||||
!conn->proxy_ssl[FIRSTSOCKET].use))) {
|
||||
if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
|
||||
/* We don't have a SSL/TLS connection yet, but FTPS is
|
||||
requested. Try a FTPS connection now */
|
||||
|
||||
@@ -2726,7 +2800,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
/* Curl_ssl_connect is BLOCKING */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(!result) {
|
||||
conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
|
||||
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
||||
result = ftp_state_user(conn);
|
||||
}
|
||||
}
|
||||
@@ -2768,7 +2842,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
case FTP_PROT:
|
||||
if(ftpcode/100 == 2)
|
||||
/* We have enabled SSL for the data connection! */
|
||||
conn->bits.ftp_use_data_ssl =
|
||||
conn->ssl[SECONDARYSOCKET].use =
|
||||
(data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
|
||||
/* FTP servers typically responds with 500 if they decide to reject
|
||||
our 'P' request */
|
||||
@@ -3585,7 +3659,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
|
||||
if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
|
||||
/* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
|
||||
aren't used so we blank their arguments. */
|
||||
aren't used so we blank their arguments. TODO: make this nicer */
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
|
||||
|
||||
return result;
|
||||
@@ -3596,6 +3670,10 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
/* Ready to do more? */
|
||||
if(connected) {
|
||||
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
|
||||
if(conn->bits.proxy) {
|
||||
infof(data, "Connection to proxy confirmed\n");
|
||||
result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(result && (ftpc->count1 == 0)) {
|
||||
@@ -3607,18 +3685,6 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
}
|
||||
}
|
||||
|
||||
result = Curl_proxy_connect(conn, SECONDARYSOCKET);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
|
||||
return result;
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
|
||||
conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE)
|
||||
return result;
|
||||
|
||||
|
||||
if(ftpc->state) {
|
||||
/* already in a state so skip the intial commands.
|
||||
They are only done to kickstart the do_more state */
|
||||
@@ -4186,8 +4252,8 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
|
||||
const char *cur_pos;
|
||||
const char *filename = NULL;
|
||||
|
||||
cur_pos = path_to_use; /* current position in path. point at the begin of
|
||||
next path component */
|
||||
cur_pos = path_to_use; /* current position in path. point at the begin
|
||||
of next path component */
|
||||
|
||||
ftpc->ctl_valid = FALSE;
|
||||
ftpc->cwdfail = FALSE;
|
||||
|
@@ -148,9 +148,6 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_PROXY_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.proxy_ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_REDIRECT_COUNT:
|
||||
*param_longp = data->set.followlocation;
|
||||
break;
|
||||
|
78
lib/http.c
78
lib/http.c
@@ -287,8 +287,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
user = conn->http_proxy.user;
|
||||
pwd = conn->http_proxy.passwd;
|
||||
user = conn->proxyuser;
|
||||
pwd = conn->proxypasswd;
|
||||
}
|
||||
else {
|
||||
userp = &conn->allocptr.userpwd;
|
||||
@@ -642,7 +642,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
if(auth) {
|
||||
infof(data, "%s auth using %s with user '%s'\n",
|
||||
proxy?"Proxy":"Server", auth,
|
||||
proxy?(conn->http_proxy.user?conn->http_proxy.user:""):
|
||||
proxy?(conn->proxyuser?conn->proxyuser:""):
|
||||
(conn->user?conn->user:""));
|
||||
authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
|
||||
}
|
||||
@@ -1092,8 +1092,8 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
return result;
|
||||
}
|
||||
|
||||
if(conn->handler->flags & PROTOPT_SSL ||
|
||||
conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
|
||||
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
/* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
|
||||
when we speak HTTPS, as if only a fraction of it is sent now, this data
|
||||
needs to fit into the normal read-callback buffer later on and that
|
||||
@@ -1345,13 +1345,10 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
connkeep(conn, "HTTP default");
|
||||
|
||||
/* the CONNECT procedure might not have been completed */
|
||||
result = Curl_proxy_connect(conn, FIRSTSOCKET);
|
||||
result = Curl_proxy_connect(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
|
||||
return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
|
||||
if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
|
||||
/* nothing else to do except wait right now - we're not done here. */
|
||||
return CURLE_OK;
|
||||
@@ -1394,16 +1391,49 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
|
||||
defined(USE_MBEDTLS)
|
||||
/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
|
||||
It should be made to query the generic SSL layer instead. */
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
return Curl_ssl_getsock(conn, socks, numsocks);
|
||||
if(conn->handler->flags & PROTOPT_SSL) {
|
||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
if(connssl->connecting_state == ssl_connect_2_writing) {
|
||||
/* write mode */
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_WRITESOCK(0);
|
||||
}
|
||||
else if(connssl->connecting_state == ssl_connect_2_reading) {
|
||||
/* read mode */
|
||||
socks[0] = conn->sock[FIRSTSOCKET];
|
||||
return GETSOCK_READSOCK(0);
|
||||
}
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_SSL
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
(void)conn;
|
||||
(void)socks;
|
||||
(void)numsocks;
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
#endif /* USE_SSL */
|
||||
#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
|
||||
|
||||
/*
|
||||
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
||||
@@ -1671,7 +1701,13 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
const struct tm *tm;
|
||||
char *buf = data->state.buffer;
|
||||
struct tm keeptime;
|
||||
CURLcode result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
CURLcode result;
|
||||
|
||||
if(data->set.timecondition == CURL_TIMECOND_NONE)
|
||||
/* no condition was asked for */
|
||||
return CURLE_OK;
|
||||
|
||||
result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
if(result) {
|
||||
failf(data, "Invalid TIMEVALUE");
|
||||
return result;
|
||||
@@ -1697,8 +1733,9 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
tm->tm_sec);
|
||||
|
||||
switch(data->set.timecondition) {
|
||||
case CURL_TIMECOND_IFMODSINCE:
|
||||
default:
|
||||
break;
|
||||
case CURL_TIMECOND_IFMODSINCE:
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"If-Modified-Since: %s\r\n", buf);
|
||||
break;
|
||||
@@ -2017,7 +2054,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
ptr = strstr(url, conn->host.dispname);
|
||||
if(ptr) {
|
||||
/* This is where the display name starts in the URL, now replace this
|
||||
part with the encoded name. */
|
||||
part with the encoded name. TODO: This method of replacing the host
|
||||
name is rather crude as I believe there's a slight risk that the
|
||||
user has entered a user name or password that contain the host name
|
||||
string. */
|
||||
size_t currlen = strlen(conn->host.dispname);
|
||||
size_t newlen = strlen(conn->host.name);
|
||||
size_t urllen = strlen(url);
|
||||
@@ -2361,11 +2401,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.timecondition) {
|
||||
result = Curl_add_timecondition(data, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
result = Curl_add_timecondition(data, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_add_custom_headers(conn, FALSE, req_buffer);
|
||||
if(result)
|
||||
@@ -3299,6 +3337,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
|
||||
}
|
||||
else {
|
||||
/* TODO: do we care about the other cases here? */
|
||||
nc = 0;
|
||||
}
|
||||
}
|
||||
@@ -3529,6 +3568,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
if(k->auto_decoding)
|
||||
/* TODO: we only support the first mentioned compression for now */
|
||||
break;
|
||||
|
||||
if(checkprefix("identity", start)) {
|
||||
|
41
lib/http2.c
41
lib/http2.c
@@ -75,6 +75,8 @@ static int http2_perform_getsock(const struct connectdata *conn,
|
||||
int bitmap = GETSOCK_BLANK;
|
||||
(void)numsocks;
|
||||
|
||||
/* TODO We should check underlying socket state if it is SSL socket
|
||||
because of renegotiation. */
|
||||
sock[0] = conn->sock[FIRSTSOCKET];
|
||||
|
||||
if(nghttp2_session_want_read(c->h2))
|
||||
@@ -308,8 +310,10 @@ static CURL *duphandle(struct SessionHandle *data)
|
||||
(void)Curl_close(second);
|
||||
second = NULL;
|
||||
}
|
||||
else
|
||||
else {
|
||||
Curl_http2_setup_req(second);
|
||||
second->state.stream_weight = data->state.stream_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
return second;
|
||||
@@ -325,12 +329,13 @@ static int push_promise(struct SessionHandle *data,
|
||||
frame->promised_stream_id));
|
||||
if(data->multi->push_cb) {
|
||||
struct HTTP *stream;
|
||||
struct HTTP *newstream;
|
||||
struct curl_pushheaders heads;
|
||||
CURLMcode rc;
|
||||
struct http_conn *httpc;
|
||||
size_t i;
|
||||
/* clone the parent */
|
||||
CURL *newhandle = duphandle(data);
|
||||
struct SessionHandle *newhandle = duphandle(data);
|
||||
if(!newhandle) {
|
||||
infof(data, "failed to duplicate handle\n");
|
||||
rv = 1; /* FAIL HARD */
|
||||
@@ -365,6 +370,11 @@ static int push_promise(struct SessionHandle *data,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newstream = newhandle->req.protop;
|
||||
newstream->stream_id = frame->promised_stream_id;
|
||||
newhandle->req.maxdownload = -1;
|
||||
newhandle->req.size = -1;
|
||||
|
||||
/* approved, add to the multi handle and immediately switch to PERFORM
|
||||
state with the given connection !*/
|
||||
rc = Curl_multi_add_perform(data->multi, newhandle, conn);
|
||||
@@ -574,7 +584,8 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
||||
|
||||
/* if we receive data for another handle, wake that up */
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for
|
||||
immediately? */
|
||||
|
||||
DEBUGF(infof(data_s, "%zu data received for stream %u "
|
||||
"(%zu left in buffer %p, total %zu)\n",
|
||||
@@ -790,8 +801,8 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
if(conn->data != data_s)
|
||||
Curl_expire(data_s, 1);
|
||||
|
||||
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d\n",
|
||||
stream->status_code));
|
||||
DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
|
||||
stream->status_code, data_s));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1035,8 +1046,8 @@ static int h2_session_send(struct SessionHandle *data,
|
||||
|
||||
h2_pri_spec(data, &pri_spec);
|
||||
|
||||
DEBUGF(infof(data, "Queuing HTTP/2 PRIORITY frame on stream %u!\n",
|
||||
stream->stream_id));
|
||||
DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
|
||||
stream->stream_id, data));
|
||||
rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
|
||||
&pri_spec);
|
||||
if(rv)
|
||||
@@ -1090,13 +1101,13 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
ncopy);
|
||||
stream->nread_header_recvbuf += ncopy;
|
||||
|
||||
infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
|
||||
(int)ncopy);
|
||||
DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
|
||||
(int)ncopy));
|
||||
return ncopy;
|
||||
}
|
||||
|
||||
infof(data, "http2_recv: %d bytes buffer at %p (stream %u)\n",
|
||||
len, mem, stream->stream_id);
|
||||
DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
|
||||
data, stream->stream_id));
|
||||
|
||||
if((data->state.drain) && stream->memlen) {
|
||||
DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
|
||||
@@ -1126,8 +1137,8 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
stream->pausedata = NULL;
|
||||
stream->pauselen = 0;
|
||||
}
|
||||
infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
|
||||
nread, stream->stream_id);
|
||||
DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
|
||||
nread, stream->stream_id));
|
||||
return nread;
|
||||
}
|
||||
else if(httpc->pause_stream_id) {
|
||||
@@ -1208,8 +1219,8 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
if(stream->memlen) {
|
||||
ssize_t retlen = stream->memlen;
|
||||
infof(data, "http2_recv: returns %zd for stream %u\n",
|
||||
retlen, stream->stream_id);
|
||||
DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
|
||||
retlen, stream->stream_id));
|
||||
stream->memlen = 0;
|
||||
|
||||
if(httpc->pause_stream_id == stream->stream_id) {
|
||||
|
@@ -96,8 +96,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
if(proxy) {
|
||||
digest = &data->state.proxydigest;
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
authp = &data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
|
@@ -65,7 +65,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
char *spn = Curl_sasl_build_gssapi_spn(
|
||||
proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
|
||||
data->set.str[STRING_SERVICE_NAME],
|
||||
proxy ? conn->http_proxy.host.name : conn->host.name);
|
||||
proxy ? conn->proxy.name : conn->host.name);
|
||||
if(!spn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
|
@@ -90,14 +90,14 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
if(!neg_ctx->server_name) {
|
||||
/* Check proxy auth requested but no given proxy name */
|
||||
if(proxy && !conn->http_proxy.host.name)
|
||||
if(proxy && !conn->proxy.name)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* Generate our SPN */
|
||||
neg_ctx->server_name = Curl_sasl_build_spn(
|
||||
proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
|
||||
data->set.str[STRING_SERVICE_NAME],
|
||||
proxy ? conn->http_proxy.host.name : conn->host.name);
|
||||
proxy ? conn->proxy.name : conn->host.name);
|
||||
if(!neg_ctx->server_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@@ -37,57 +37,19 @@
|
||||
#include "connect.h"
|
||||
#include "curl_printf.h"
|
||||
#include "curlx.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Perform SSL initialization for HTTPS proxy. Sets
|
||||
* proxy_ssl_connected connection bit when complete. Can be
|
||||
* called multiple times.
|
||||
*/
|
||||
static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
CURLcode result = CURLE_OK;
|
||||
DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex]) {
|
||||
/* perform SSL initialization for this socket */
|
||||
result =
|
||||
Curl_ssl_connect_nonblocking(conn, sockindex,
|
||||
&conn->bits.proxy_ssl_connected[sockindex]);
|
||||
if(result)
|
||||
conn->bits.close = TRUE; /* a failed connection is marked for closure to
|
||||
prevent (bad) re-use or similar */
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
|
||||
const CURLcode result = https_proxy_connect(conn, sockindex);
|
||||
if(result)
|
||||
return result;
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex])
|
||||
return result; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* for [protocol] tunneled through HTTP proxy */
|
||||
struct HTTP http_proxy;
|
||||
void *prot_save;
|
||||
CURLcode result;
|
||||
const char * const host = sockindex == SECONDARYSOCKET ?
|
||||
conn->secondaryhostname : conn->host.name;
|
||||
const int port = sockindex == SECONDARYSOCKET ? conn->secondary_port :
|
||||
conn->remote_port;
|
||||
|
||||
/* BLOCKING */
|
||||
/* We want "seamless" operations through HTTP proxy tunnel */
|
||||
@@ -105,7 +67,8 @@ CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
result = Curl_proxyCONNECT(conn, sockindex, host, port, FALSE);
|
||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
|
||||
conn->host.name, conn->remote_port, FALSE);
|
||||
conn->data->req.protop = prot_save;
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
@@ -189,7 +152,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
char *host=(char *)"";
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
"1.0" : "1.1";
|
||||
char *hostheader= /* host:port with IPv6 support */
|
||||
aprintf("%s%s%s:%hu", conn->bits.ipv6_ip?"[":"",
|
||||
|
@@ -32,11 +32,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* Default proxy timeout in milliseconds */
|
||||
#define PROXY_TIMEOUT (3600*1000)
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex);
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn);
|
||||
|
||||
#else
|
||||
#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
|
||||
#define Curl_proxy_connect(x,y) CURLE_OK
|
||||
#define Curl_proxy_connect(x) CURLE_OK
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
20
lib/imap.c
20
lib/imap.c
@@ -842,7 +842,7 @@ static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
|
||||
|
||||
if(imapcode != 'O') {
|
||||
failf(data, "Got unexpected imap-server response");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
}
|
||||
else
|
||||
result = imap_perform_capability(conn);
|
||||
@@ -1033,7 +1033,7 @@ static CURLcode imap_state_list_resp(struct connectdata *conn, int imapcode,
|
||||
line[len] = '\0';
|
||||
}
|
||||
else if(imapcode != 'O')
|
||||
result = CURLE_QUOTE_ERROR;
|
||||
result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
|
||||
else
|
||||
/* End of DO phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1105,7 +1105,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
if(imapcode != '*') {
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
state(conn, IMAP_STOP);
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
|
||||
}
|
||||
|
||||
/* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
|
||||
@@ -1174,7 +1174,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
else {
|
||||
/* We don't know how to parse this line */
|
||||
failf(pp->conn->data, "Failed to parse FETCH response.");
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */
|
||||
}
|
||||
|
||||
/* End of DO phase */
|
||||
@@ -1193,7 +1193,7 @@ static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
|
||||
(void)instate; /* No use for this yet */
|
||||
|
||||
if(imapcode != 'O')
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */
|
||||
else
|
||||
/* End of DONE phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1262,7 +1262,7 @@ static CURLcode imap_state_search_resp(struct connectdata *conn, int imapcode,
|
||||
line[len] = '\0';
|
||||
}
|
||||
else if(imapcode != 'O')
|
||||
result = CURLE_QUOTE_ERROR;
|
||||
result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
|
||||
else
|
||||
/* End of DO phase */
|
||||
state(conn, IMAP_STOP);
|
||||
@@ -1506,10 +1506,10 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
|
||||
|
||||
/* Run the state-machine
|
||||
|
||||
This _really_ should be using the imap_multi_statemach function but we
|
||||
have no general support for non-blocking DONE operations. Neither in
|
||||
the multi state machine and there are Curl_done() invokes on several
|
||||
places in the code!
|
||||
TODO: when the multi interface is used, this _really_ should be using
|
||||
the imap_multi_statemach function but we have no general support for
|
||||
non-blocking DONE operations, not in the multi state machine and with
|
||||
Curl_done() invokes on several places in the code!
|
||||
*/
|
||||
if(!result)
|
||||
result = imap_block_statemach(conn);
|
||||
|
14
lib/ldap.c
14
lib/ldap.c
@@ -273,7 +273,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
|
||||
#else
|
||||
int ldap_option;
|
||||
char* ldap_ca = conn->ssl_config.CAfile;
|
||||
char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
|
||||
#if defined(CURL_HAS_NOVELL_LDAPSDK)
|
||||
rc = ldapssl_client_init(NULL, NULL);
|
||||
if(rc != LDAP_SUCCESS) {
|
||||
@@ -281,11 +281,11 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
}
|
||||
if(conn->ssl_config.verifypeer) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* Novell SDK supports DER or BASE64 files. */
|
||||
int cert_type = LDAPSSL_CERT_FILETYPE_B64;
|
||||
if((data->set.ssl.cert_type) &&
|
||||
(Curl_raw_equal(data->set.ssl.cert_type, "DER")))
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
|
||||
cert_type = LDAPSSL_CERT_FILETYPE_DER;
|
||||
if(!ldap_ca) {
|
||||
failf(data, "LDAP local: ERROR %s CA cert not set!",
|
||||
@@ -323,10 +323,10 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
goto quit;
|
||||
}
|
||||
#elif defined(LDAP_OPT_X_TLS)
|
||||
if(conn->ssl_config.verifypeer) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
if((data->set.ssl.cert_type) &&
|
||||
(!Curl_raw_equal(data->set.ssl.cert_type, "PEM"))) {
|
||||
if((data->set.str[STRING_CERT_TYPE]) &&
|
||||
(!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
|
||||
failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
|
||||
result = CURLE_SSL_CERTPROBLEM;
|
||||
goto quit;
|
||||
|
18
lib/multi.c
18
lib/multi.c
@@ -42,8 +42,7 @@
|
||||
#include "multihandle.h"
|
||||
#include "pipeline.h"
|
||||
#include "sigpipe.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@@ -643,9 +642,6 @@ static int waitconnect_getsock(struct connectdata *conn,
|
||||
if(!numsocks)
|
||||
return GETSOCK_BLANK;
|
||||
|
||||
if(CONNECT_FIRSTSOCKET_PROXY_SSL())
|
||||
return Curl_ssl_getsock(conn, sock, numsocks);
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
if(conn->tempsock[i] != CURL_SOCKET_BAD) {
|
||||
sock[s] = conn->tempsock[i];
|
||||
@@ -1240,9 +1236,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
}
|
||||
else if(!result) {
|
||||
if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
|
||||
data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
|
||||
(data->easy_conn->tunnel_state[FIRSTSOCKET] != TUNNEL_CONNECT))
|
||||
if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
|
||||
/* initiate protocol connect phase */
|
||||
multistate(data, CURLM_STATE_SENDPROTOCONNECT);
|
||||
}
|
||||
@@ -1253,14 +1247,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* awaiting a completion of an asynch TCP connect */
|
||||
result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
|
||||
if(connected && !result) {
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
|
||||
!data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
|
||||
(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)) {
|
||||
multistate(data, CURLM_STATE_WAITPROXYCONNECT);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
rc = CURLM_CALL_MULTI_PERFORM;
|
||||
multistate(data, data->easy_conn->bits.tunnel_proxy?
|
||||
CURLM_STATE_WAITPROXYCONNECT:
|
||||
|
@@ -38,9 +38,7 @@ typedef enum {
|
||||
CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */
|
||||
CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */
|
||||
CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */
|
||||
CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization
|
||||
to complete and/or proxy CONNECT to
|
||||
finalize */
|
||||
CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */
|
||||
CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
|
||||
CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
|
||||
phase */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, 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
|
||||
@@ -77,7 +77,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */
|
||||
|
||||
/* Amiga */
|
||||
long flags = nonblock ? 1L : 0L;
|
||||
return IoctlSocket(sockfd, FIONBIO, flags);
|
||||
return IoctlSocket(sockfd, FIONBIO, (char *)&flags);
|
||||
|
||||
#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
|
||||
|
||||
|
@@ -176,7 +176,9 @@ static CURLcode ldap_setup_connection(struct connectdata *conn)
|
||||
li->proto = proto;
|
||||
conn->proto.generic = li;
|
||||
connkeep(conn, "OpenLDAP default");
|
||||
|
||||
/* TODO:
|
||||
* - provide option to choose SASL Binds instead of Simple
|
||||
*/
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -479,6 +481,8 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
|
||||
lr->nument++;
|
||||
rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
|
||||
if(rc < 0) {
|
||||
/* TODO: verify that this is really how this return code should be
|
||||
handled */
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
@@ -101,9 +101,7 @@ CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
|
||||
else
|
||||
interval_ms = 0; /* immediate */
|
||||
|
||||
if(Curl_ssl_data_pending(conn, FIRSTSOCKET))
|
||||
rc = 1;
|
||||
else if(Curl_pp_moredata(pp))
|
||||
if(Curl_pp_moredata(pp))
|
||||
/* We are receiving and there is data in the cache so just read it */
|
||||
rc = 1;
|
||||
else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
|
||||
|
18
lib/pop3.c
18
lib/pop3.c
@@ -214,7 +214,7 @@ static const struct Curl_handler Curl_handler_pop3s_proxy = {
|
||||
/* SASL parameters for the pop3 protocol */
|
||||
static const struct SASLproto saslpop3 = {
|
||||
"pop", /* The service name */
|
||||
'+', /* Code received when continuation is expected */
|
||||
'*', /* Code received when continuation is expected */
|
||||
'+', /* Code to receive upon authentication success */
|
||||
255 - 8, /* Maximum initial response length (no max) */
|
||||
pop3_perform_auth, /* Send authentication command */
|
||||
@@ -256,21 +256,29 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
|
||||
if(pop3c->state == POP3_CAPA) {
|
||||
/* Do we have the terminating line? */
|
||||
if(len >= 1 && !memcmp(line, ".", 1))
|
||||
/* Treat the response as a success */
|
||||
*resp = '+';
|
||||
else
|
||||
/* Treat the response as an untagged continuation */
|
||||
*resp = '*';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Do we have a command or continuation response? */
|
||||
if((len >= 3 && !memcmp("+OK", line, 3)) ||
|
||||
(len >= 1 && !memcmp("+", line, 1))) {
|
||||
/* Do we have a success response? */
|
||||
if(len >= 3 && !memcmp("+OK", line, 3)) {
|
||||
*resp = '+';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Do we have a continuation response? */
|
||||
if(len >= 1 && !memcmp("+", line, 1)) {
|
||||
*resp = '*';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE; /* Nothing for us */
|
||||
}
|
||||
|
||||
@@ -700,7 +708,7 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
/* Do we have a untagged response? */
|
||||
/* Do we have a untagged continuation response? */
|
||||
if(pop3code == '*') {
|
||||
/* Does the server support the STLS capability? */
|
||||
if(len >= 4 && !memcmp(line, "STLS", 4))
|
||||
|
10
lib/rawstr.c
10
lib/rawstr.c
@@ -116,16 +116,6 @@ int Curl_raw_equal(const char *first, const char *second)
|
||||
return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
|
||||
}
|
||||
|
||||
bool Curl_safe_strequal(const char *str1, const char *str2)
|
||||
{
|
||||
if(str1 && str2)
|
||||
/* both pointers point to something then compare them */
|
||||
return (0 != Curl_raw_equal(str1, str2)) ? TRUE : FALSE;
|
||||
else
|
||||
/* if both pointers are NULL then treat them as equal */
|
||||
return (!str1 && !str2) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
int Curl_raw_nequal(const char *first, const char *second, size_t max)
|
||||
{
|
||||
while(*first && *second && max) {
|
||||
|
@@ -34,7 +34,6 @@
|
||||
*/
|
||||
int Curl_raw_equal(const char *first, const char *second);
|
||||
int Curl_raw_nequal(const char *first, const char *second, size_t max);
|
||||
bool Curl_safe_strequal(const char *str1, const char *str2);
|
||||
|
||||
char Curl_raw_toupper(char in);
|
||||
|
||||
|
13
lib/rtsp.c
13
lib/rtsp.c
@@ -42,6 +42,16 @@
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* TODO (general)
|
||||
* -incoming server requests
|
||||
* -server CSeq counter
|
||||
* -digest authentication
|
||||
* -connect thru proxy
|
||||
* -pipelining?
|
||||
*/
|
||||
|
||||
|
||||
#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1])))
|
||||
|
||||
#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \
|
||||
@@ -212,6 +222,7 @@ static CURLcode rtsp_done(struct connectdata *conn,
|
||||
else if(data->set.rtspreq == RTSPREQ_RECEIVE &&
|
||||
(conn->proto.rtspc.rtp_channel == -1)) {
|
||||
infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
|
||||
/* TODO CPC: Server -> Client logic here */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,6 +328,8 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
/* TODO: proxy? */
|
||||
|
||||
/* Stream URI. Default to server '*' if not specified */
|
||||
if(data->set.str[STRING_RTSP_STREAM_URI]) {
|
||||
p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
|
||||
|
@@ -520,11 +520,13 @@ CURLcode Curl_read_plain(curl_socket_t sockfd,
|
||||
|
||||
if(-1 == nread) {
|
||||
int err = SOCKERRNO;
|
||||
int return_error;
|
||||
#ifdef USE_WINSOCK
|
||||
if(WSAEWOULDBLOCK == err)
|
||||
return_error = WSAEWOULDBLOCK == err;
|
||||
#else
|
||||
if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
|
||||
return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
|
||||
#endif
|
||||
if(return_error)
|
||||
return CURLE_AGAIN;
|
||||
else
|
||||
return CURLE_RECV_ERROR;
|
||||
|
@@ -131,7 +131,7 @@ const struct Curl_handler Curl_handler_smbs = {
|
||||
defined(__OS400__)
|
||||
static unsigned short smb_swap16(unsigned short x)
|
||||
{
|
||||
return (x << 8) | ((x >> 8) & 0xff);
|
||||
return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
|
||||
}
|
||||
|
||||
static unsigned int smb_swap32(unsigned int x)
|
||||
@@ -143,12 +143,14 @@ static unsigned int smb_swap32(unsigned int x)
|
||||
#ifdef HAVE_LONGLONG
|
||||
static unsigned long long smb_swap64(unsigned long long x)
|
||||
{
|
||||
return ((unsigned long long)smb_swap32(x) << 32) | smb_swap32(x >> 32);
|
||||
return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#else
|
||||
static unsigned __int64 smb_swap64(unsigned __int64 x)
|
||||
{
|
||||
return ((unsigned __int64)smb_swap32(x) << 32) | smb_swap32(x >> 32);
|
||||
return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
|
||||
smb_swap32((unsigned int) (x >> 32));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
|
@@ -1256,8 +1256,10 @@ static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
|
||||
|
||||
/* Run the state-machine
|
||||
|
||||
this should be using the smtp_multi_statemach function but we have no
|
||||
support for non-blocking DONE operations!
|
||||
TODO: when the multi interface is used, this _really_ should be using
|
||||
the smtp_multi_statemach function but we have no general support for
|
||||
non-blocking DONE operations, not in the multi state machine and with
|
||||
Curl_done() invokes on several places in the code!
|
||||
*/
|
||||
result = smtp_block_statemach(conn);
|
||||
}
|
||||
|
16
lib/socks.c
16
lib/socks.c
@@ -110,10 +110,9 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn)
|
||||
struct connectdata *conn,
|
||||
bool protocol4a)
|
||||
{
|
||||
const bool protocol4a =
|
||||
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
|
||||
#define SOCKS4REQLEN 262
|
||||
unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
|
||||
id */
|
||||
@@ -128,10 +127,6 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
|
||||
if(conn->bits.httpproxy)
|
||||
infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
|
||||
protocol4a ? "a" : "", hostname, remote_port);
|
||||
|
||||
(void)curlx_nonblock(sock, FALSE);
|
||||
|
||||
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
|
||||
@@ -381,15 +376,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
curl_socket_t sock = conn->sock[sockindex];
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout;
|
||||
bool socks5_resolve_local =
|
||||
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
|
||||
bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
|
||||
const size_t hostname_len = strlen(hostname);
|
||||
ssize_t len = 0;
|
||||
|
||||
if(conn->bits.httpproxy)
|
||||
infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
|
||||
hostname, remote_port);
|
||||
|
||||
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
|
||||
if(!socks5_resolve_local && hostname_len > 255) {
|
||||
infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef CURL_DISABLE_PROXY
|
||||
#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
|
||||
#define Curl_SOCKS4(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
|
||||
#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
|
||||
#else
|
||||
/*
|
||||
@@ -49,7 +49,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
const char *hostname,
|
||||
int remote_port,
|
||||
int sockindex,
|
||||
struct connectdata *conn);
|
||||
struct connectdata *conn,
|
||||
bool protocol4a);
|
||||
|
||||
/*
|
||||
* This function logs in to a SOCKS5 proxy and sends the specifics to the
|
||||
|
@@ -121,7 +121,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
char *user=NULL;
|
||||
unsigned char socksreq[4]; /* room for GSS-API exchange header only */
|
||||
char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
|
||||
const size_t serviceptr_length = strlen(serviceptr);
|
||||
|
||||
/* GSS-API request looks like
|
||||
* +----+------+-----+----------------+
|
||||
@@ -133,23 +132,22 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
|
||||
/* prepare service name */
|
||||
if(strchr(serviceptr, '/')) {
|
||||
service.length = serviceptr_length;
|
||||
service.value = malloc(service.length);
|
||||
service.value = malloc(strlen(serviceptr));
|
||||
if(!service.value)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
service.length = strlen(serviceptr);
|
||||
memcpy(service.value, serviceptr, service.length);
|
||||
|
||||
gss_major_status = gss_import_name(&gss_minor_status, &service,
|
||||
(gss_OID) GSS_C_NULL_OID, &server);
|
||||
}
|
||||
else {
|
||||
service.value = malloc(serviceptr_length +
|
||||
strlen(conn->socks_proxy.host.name)+2);
|
||||
service.value = malloc(strlen(serviceptr) +strlen(conn->proxy.name)+2);
|
||||
if(!service.value)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
service.length = serviceptr_length + strlen(conn->socks_proxy.host.name)+1;
|
||||
service.length = strlen(serviceptr) +strlen(conn->proxy.name)+1;
|
||||
snprintf(service.value, service.length+1, "%s@%s",
|
||||
serviceptr, conn->socks_proxy.host.name);
|
||||
serviceptr, conn->proxy.name);
|
||||
|
||||
gss_major_status = gss_import_name(&gss_minor_status, &service,
|
||||
GSS_C_NT_HOSTBASED_SERVICE, &server);
|
||||
|
@@ -84,7 +84,6 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
unsigned long qop;
|
||||
unsigned char socksreq[4]; /* room for GSS-API exchange header only */
|
||||
char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
|
||||
const size_t service_length = strlen(service);
|
||||
|
||||
/* GSS-API request looks like
|
||||
* +----+------+-----+----------------+
|
||||
@@ -96,19 +95,17 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
|
||||
/* prepare service name */
|
||||
if(strchr(service, '/')) {
|
||||
service_name = malloc(service_length);
|
||||
service_name = malloc(strlen(service));
|
||||
if(!service_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(service_name, service, service_length);
|
||||
memcpy(service_name, service, strlen(service));
|
||||
}
|
||||
else {
|
||||
service_name = malloc(service_length +
|
||||
strlen(conn->socks_proxy.host.name) + 2);
|
||||
service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
|
||||
if(!service_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
snprintf(service_name, service_length +
|
||||
strlen(conn->socks_proxy.host.name)+2, "%s/%s",
|
||||
service, conn->socks_proxy.host.name);
|
||||
snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2,
|
||||
"%s/%s", service, conn->proxy.name);
|
||||
}
|
||||
|
||||
input_desc.cBuffers = 1;
|
||||
|
@@ -211,7 +211,7 @@ struct Curl_tree *Curl_splaygetbest(struct timeval i,
|
||||
/* Deletes the very node we point out from the tree if it's there. Stores a
|
||||
* pointer to the new resulting tree in 'newroot'.
|
||||
*
|
||||
* Returns zero on success and non-zero on errors!
|
||||
* Returns zero on success and non-zero on errors! TODO: document error codes.
|
||||
* When returning error, it does not touch the 'newroot' pointer.
|
||||
*
|
||||
* NOTE: when the last node of the tree is removed, there's no tree left so
|
||||
|
16
lib/ssh.c
16
lib/ssh.c
@@ -296,6 +296,10 @@ static CURLcode libssh2_session_error_to_CURLE(int err)
|
||||
return CURLE_AGAIN;
|
||||
}
|
||||
|
||||
/* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
|
||||
error code, and possibly add a few new SSH-related one. We must however
|
||||
not return or even depend on libssh2 errors in the public libcurl API */
|
||||
|
||||
return CURLE_SSH;
|
||||
}
|
||||
|
||||
@@ -859,7 +863,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
break;
|
||||
}
|
||||
|
||||
sshc->passphrase = data->set.ssl.key_passwd;
|
||||
sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
|
||||
if(!sshc->passphrase)
|
||||
sshc->passphrase = "";
|
||||
|
||||
@@ -2820,8 +2824,10 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done)
|
||||
if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
|
||||
int rc;
|
||||
ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
|
||||
if(!ssh->kh)
|
||||
if(!ssh->kh) {
|
||||
/* eeek. TODO: free the ssh_session! */
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
/* read all known hosts from there */
|
||||
rc = libssh2_knownhost_readfile(ssh->kh,
|
||||
@@ -2958,8 +2964,10 @@ static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
|
||||
if(!status) {
|
||||
/* run the state-machine
|
||||
|
||||
This should be using the ssh_multi_statemach function but we have no
|
||||
support for non-blocking DONE operations!
|
||||
TODO: when the multi interface is used, this _really_ should be using
|
||||
the ssh_multi_statemach function but we have no general support for
|
||||
non-blocking DONE operations, not in the multi state machine and with
|
||||
Curl_done() invokes on several places in the code!
|
||||
*/
|
||||
result = ssh_block_statemach(conn, FALSE);
|
||||
}
|
||||
|
@@ -1220,6 +1220,7 @@ CURLcode telrcv(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Escape and send a telnet data block */
|
||||
/* TODO: write large chunks of data instead of one byte at a time */
|
||||
static CURLcode send_telnet_data(struct connectdata *conn,
|
||||
char *buffer, ssize_t nread)
|
||||
{
|
||||
|
@@ -1311,7 +1311,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
|
||||
/* Init the SSL session ID cache here. We do it here since we want to do it
|
||||
after the *_setopt() calls (that could specify the size of the cache) but
|
||||
before any transfer takes place. */
|
||||
result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions);
|
||||
result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
11
lib/url.h
11
lib/url.h
@@ -82,16 +82,5 @@ CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
|
||||
void Curl_verboseconnect(struct connectdata *conn);
|
||||
#endif
|
||||
|
||||
#define CONNECT_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[sockindex])
|
||||
|
||||
#define CONNECT_FIRSTSOCKET_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[FIRSTSOCKET])
|
||||
|
||||
#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
|
||||
(conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
|
||||
!conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
|
||||
|
||||
#endif /* HEADER_CURL_URL_H */
|
||||
|
@@ -331,8 +331,6 @@ struct ssl_connect_data {
|
||||
gsk_handle handle;
|
||||
int iocport;
|
||||
ssl_connect_state connecting_state;
|
||||
int localfd;
|
||||
int remotefd;
|
||||
#endif
|
||||
#ifdef USE_AXTLS
|
||||
SSL_CTX* ssl_ctx;
|
||||
@@ -361,37 +359,27 @@ struct ssl_connect_data {
|
||||
#endif /* USE_DARWINSSL */
|
||||
};
|
||||
|
||||
struct ssl_primary_config {
|
||||
struct ssl_config_data {
|
||||
long version; /* what version the client wants to use */
|
||||
long certverifyresult; /* result from the certificate verification */
|
||||
|
||||
bool verifypeer; /* set TRUE if this is desired */
|
||||
bool verifyhost; /* set TRUE if CN/SAN must match hostname */
|
||||
bool verifystatus; /* set TRUE if certificate status must be checked */
|
||||
char *CApath; /* certificate dir (doesn't work on windows) */
|
||||
char *CAfile; /* certificate to verify peer against */
|
||||
const char *CRLfile; /* CRL to check certificate revocation */
|
||||
const char *issuercert;/* optional issuer certificate filename */
|
||||
char *random_file; /* path to file containing "random" data */
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
char *cipher_list; /* list of ciphers to use */
|
||||
};
|
||||
|
||||
struct ssl_config_data {
|
||||
struct ssl_primary_config primary;
|
||||
bool enable_beast; /* especially allow this flaw for interoperability's
|
||||
sake*/
|
||||
bool no_revoke; /* disable SSL certificate revocation checks */
|
||||
long certverifyresult; /* result from the certificate verification */
|
||||
char *CRLfile; /* CRL to check certificate revocation */
|
||||
char *issuercert;/* optional issuer certificate filename */
|
||||
size_t max_ssl_sessions; /* SSL session id cache size */
|
||||
curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
|
||||
void *fsslctxp; /* parameter for call back */
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
bool certinfo; /* gather lots of certificate info */
|
||||
bool falsestart;
|
||||
|
||||
char *cert; /* client certificate file name */
|
||||
char *cert_type; /* format for certificate (default: PEM)*/
|
||||
char *key; /* private key file name */
|
||||
char *key_type; /* format for private key (default: PEM) */
|
||||
char *key_passwd; /* plain text private key password */
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
char *username; /* TLS username (for, e.g., SRP) */
|
||||
char *password; /* TLS password (for, e.g., SRP) */
|
||||
@@ -399,11 +387,6 @@ struct ssl_config_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ssl_general_config {
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
size_t max_ssl_sessions; /* SSL session id cache size */
|
||||
};
|
||||
|
||||
/* information stored about one single SSL session */
|
||||
struct curl_ssl_session {
|
||||
char *name; /* host name for which this ID was used */
|
||||
@@ -411,7 +394,7 @@ struct curl_ssl_session {
|
||||
size_t idsize; /* if known, otherwise 0 */
|
||||
long age; /* just a number, the higher the more recent */
|
||||
int remote_port; /* remote port to connect to */
|
||||
struct ssl_primary_config ssl_config; /* setup for this session */
|
||||
struct ssl_config_data ssl_config; /* setup for this session */
|
||||
};
|
||||
|
||||
/* Struct used for Digest challenge-response authentication */
|
||||
@@ -524,7 +507,6 @@ struct ConnectBits {
|
||||
bool reuse; /* if set, this is a re-used connection */
|
||||
bool proxy; /* if set, this transfer is done through a proxy - any type */
|
||||
bool httpproxy; /* if set, this transfer is done through a http proxy */
|
||||
bool socksproxy; /* if set, this transfer is done through a socks proxy */
|
||||
bool user_passwd; /* do we use user+password for this connection? */
|
||||
bool proxy_user_passwd; /* user+password for the proxy? */
|
||||
bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
|
||||
@@ -559,7 +541,6 @@ struct ConnectBits {
|
||||
bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
|
||||
EPRT doesn't work we disable it for the forthcoming
|
||||
requests */
|
||||
bool ftp_use_data_ssl; /* Enabled SSL for the data connection */
|
||||
bool netrc; /* name+password provided by netrc */
|
||||
bool userpwd_in_url; /* name+password found in url */
|
||||
bool stream_was_rewound; /* Indicates that the stream was rewound after a
|
||||
@@ -572,9 +553,6 @@ struct ConnectBits {
|
||||
connection */
|
||||
bool type_set; /* type= was used in the URL */
|
||||
bool multiplex; /* connection is multiplexed */
|
||||
bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
|
||||
is complete */
|
||||
bool socksproxy_connecting; /* connecting through a socks proxy */
|
||||
};
|
||||
|
||||
struct hostname {
|
||||
@@ -862,14 +840,6 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
|
||||
size_t len, /* max amount to read */
|
||||
CURLcode *err); /* error to return */
|
||||
|
||||
struct proxy_info {
|
||||
struct hostname host;
|
||||
long port;
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
char *user; /* proxy user name string, allocated */
|
||||
char *passwd; /* proxy password string, allocated */
|
||||
};
|
||||
|
||||
/*
|
||||
* The connectdata struct contains all fields and variables that should be
|
||||
* unique for an entire connection.
|
||||
@@ -919,15 +889,10 @@ struct connectdata {
|
||||
int socktype; /* SOCK_STREAM or SOCK_DGRAM */
|
||||
|
||||
struct hostname host;
|
||||
char *secondaryhostname; /* secondary socket host name (ftp) */
|
||||
|
||||
struct proxy_info socks_proxy;
|
||||
struct proxy_info http_proxy;
|
||||
struct hostname proxy;
|
||||
|
||||
long port; /* which port to use locally */
|
||||
int remote_port; /* what remote port to connect to, not the proxy port! */
|
||||
unsigned short secondary_port; /* secondary socket remote port to connect to
|
||||
(ftp) */
|
||||
|
||||
/* 'primary_ip' and 'primary_port' get filled with peer's numerical
|
||||
ip address and port number whenever an outgoing connection is
|
||||
@@ -952,6 +917,10 @@ struct connectdata {
|
||||
|
||||
char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
|
||||
|
||||
char *proxyuser; /* proxy user name string, allocated */
|
||||
char *proxypasswd; /* proxy password string, allocated */
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
|
||||
int httpversion; /* the HTTP version*10 reported by the server */
|
||||
int rtspversion; /* the RTSP version*10 reported by the server */
|
||||
|
||||
@@ -966,9 +935,7 @@ struct connectdata {
|
||||
Curl_send *send[2];
|
||||
|
||||
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
|
||||
struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
|
||||
struct ssl_primary_config ssl_config;
|
||||
struct ssl_primary_config proxy_ssl_config;
|
||||
struct ssl_config_data ssl_config;
|
||||
|
||||
struct ConnectBits bits; /* various state-flags for this connection */
|
||||
|
||||
@@ -1094,6 +1061,9 @@ struct connectdata {
|
||||
int socks5_gssapi_enctype;
|
||||
#endif
|
||||
|
||||
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
|
||||
made and will serve the purpose of being used for comparison reasons so
|
||||
@@ -1404,6 +1374,8 @@ struct DynamicStatic {
|
||||
struct Curl_multi; /* declared and used only in multi.c */
|
||||
|
||||
enum dupstring {
|
||||
STRING_CERT, /* client certificate file name */
|
||||
STRING_CERT_TYPE, /* format for certificate (default: PEM)*/
|
||||
STRING_COOKIE, /* HTTP cookie string to send */
|
||||
STRING_COOKIEJAR, /* dump all cookies to this file */
|
||||
STRING_CUSTOMREQUEST, /* HTTP/FTP/RTSP request/method to use */
|
||||
@@ -1413,16 +1385,25 @@ enum dupstring {
|
||||
STRING_FTP_ACCOUNT, /* ftp account data */
|
||||
STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
|
||||
STRING_FTPPORT, /* port to send with the FTP PORT command */
|
||||
STRING_KEY, /* private key file name */
|
||||
STRING_KEY_PASSWD, /* plain text private key password */
|
||||
STRING_KEY_TYPE, /* format for private key (default: PEM) */
|
||||
STRING_KRB_LEVEL, /* krb security level */
|
||||
STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find
|
||||
$HOME/.netrc */
|
||||
STRING_PROXY, /* proxy to use */
|
||||
STRING_SOCKS_PROXY, /* socks proxy to use */
|
||||
STRING_SET_RANGE, /* range, if used */
|
||||
STRING_SET_REFERER, /* custom string for the HTTP referer field */
|
||||
STRING_SET_URL, /* what original URL to work on */
|
||||
STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */
|
||||
STRING_SSL_CAFILE, /* certificate file to verify peer against */
|
||||
STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
|
||||
STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
|
||||
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
|
||||
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
|
||||
STRING_USERAGENT, /* User-Agent string */
|
||||
STRING_SSL_CRLFILE, /* crl file to check certificate */
|
||||
STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */
|
||||
STRING_USERNAME, /* <username>, if used */
|
||||
STRING_PASSWORD, /* <password>, if used */
|
||||
STRING_OPTIONS, /* <options>, if used */
|
||||
@@ -1447,6 +1428,10 @@ enum dupstring {
|
||||
STRING_MAIL_FROM,
|
||||
STRING_MAIL_AUTH,
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
STRING_TLSAUTH_USERNAME, /* TLS auth <username> */
|
||||
STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */
|
||||
#endif
|
||||
STRING_BEARER, /* <bearer>, if used */
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */
|
||||
@@ -1560,10 +1545,7 @@ struct UserDefined {
|
||||
long httpversion; /* when non-zero, a specific HTTP version requested to
|
||||
be used in the library's request(s) */
|
||||
struct ssl_config_data ssl; /* user defined SSL stuff */
|
||||
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
|
||||
struct ssl_general_config general_ssl; /* general user defined SSL stuff */
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
curl_proxytype socks_proxytype; /* what kind of socks proxy that is in use */
|
||||
long dns_cache_timeout; /* DNS cache timeout */
|
||||
long buffer_size; /* size of receive buffer to use */
|
||||
void *private_data; /* application-private data */
|
||||
@@ -1627,6 +1609,9 @@ struct UserDefined {
|
||||
bool ftp_skip_ip; /* skip the IP address the FTP server passes on to
|
||||
us */
|
||||
bool connect_only; /* make connection, let application use the socket */
|
||||
bool ssl_enable_beast; /* especially allow this flaw for interoperability's
|
||||
sake*/
|
||||
bool ssl_no_revoke; /* disable SSL certificate revocation checks */
|
||||
long ssh_auth_types; /* allowed SSH auth types */
|
||||
bool http_te_skip; /* pass the raw body data to the user, even when
|
||||
transfer-encoded (chunked, compressed) */
|
||||
|
@@ -160,7 +160,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* axTLS only supports TLSv1 */
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
break;
|
||||
@@ -185,17 +185,17 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
conn->ssl[sockindex].ssl = NULL;
|
||||
|
||||
/* Load the trusted CA cert bundle file */
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
|
||||
SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
|
||||
if(data->set.ssl.CAfile) {
|
||||
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
|
||||
!= SSL_OK) {
|
||||
infof(data, "error reading ca cert file %s \n",
|
||||
SSL_CONN_CONFIG(CAfile));
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
data->set.ssl.CAfile);
|
||||
if(data->set.ssl.verifypeer) {
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
}
|
||||
else
|
||||
infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
|
||||
infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
|
||||
}
|
||||
|
||||
/* gtls.c tasks we're skipping for now:
|
||||
@@ -207,15 +207,15 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
|
||||
/* Load client certificate */
|
||||
if(SSL_SET_OPTION(cert)) {
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
i=0;
|
||||
/* Instead of trying to analyze cert type here, let axTLS try them all. */
|
||||
while(cert_types[i] != 0) {
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
|
||||
SSL_SET_OPTION(cert), NULL);
|
||||
data->set.str[STRING_CERT], NULL);
|
||||
if(ssl_fcn_return == SSL_OK) {
|
||||
infof(data, "successfully read cert file %s \n",
|
||||
SSL_SET_OPTION(cert));
|
||||
data->set.str[STRING_CERT]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
@@ -223,7 +223,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
/* Tried all cert types, none worked. */
|
||||
if(cert_types[i] == 0) {
|
||||
failf(data, "%s is not x509 or pkcs12 format",
|
||||
SSL_SET_OPTION(cert));
|
||||
data->set.str[STRING_CERT]);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
}
|
||||
@@ -231,15 +231,15 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
/* Load client key.
|
||||
If a pkcs12 file successfully loaded a cert, then there's nothing to do
|
||||
because the key has already been loaded. */
|
||||
if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
|
||||
if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
|
||||
i=0;
|
||||
/* Instead of trying to analyze key type here, let axTLS try them all. */
|
||||
while(key_types[i] != 0) {
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
|
||||
SSL_SET_OPTION(key), NULL);
|
||||
data->set.str[STRING_KEY], NULL);
|
||||
if(ssl_fcn_return == SSL_OK) {
|
||||
infof(data, "successfully read key file %s \n",
|
||||
SSL_SET_OPTION(key));
|
||||
data->set.str[STRING_KEY]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
@@ -247,7 +247,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
/* Tried all key types, none worked. */
|
||||
if(key_types[i] == 0) {
|
||||
failf(data, "Failure: %s is not a supported key file",
|
||||
SSL_SET_OPTION(key));
|
||||
data->set.str[STRING_KEY]);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -259,8 +259,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
*/
|
||||
|
||||
/* In axTLS, handshaking happens inside ssl_client_new. */
|
||||
if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
|
||||
sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
|
||||
/* we got a session id, use it! */
|
||||
infof (data, "SSL re-using session ID\n");
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
|
||||
@@ -288,17 +287,13 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
const char *dns_altname;
|
||||
int8_t found_subject_alt_names = 0;
|
||||
int8_t found_subject_alt_name_matching_conn = 0;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.dispname : conn->host.dispname;
|
||||
|
||||
/* Here, gtls.c gets the peer certificates and fails out depending on
|
||||
* settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
|
||||
*/
|
||||
|
||||
/* Verify server's certificate */
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
if(ssl_verify_cert(ssl) != SSL_OK) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "server cert verify failed");
|
||||
@@ -329,8 +324,8 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
found_subject_alt_names = 1;
|
||||
|
||||
infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
|
||||
dns_altname, hostname);
|
||||
if(Curl_cert_hostcheck(dns_altname, hostname)) {
|
||||
dns_altname, conn->host.name);
|
||||
if(Curl_cert_hostcheck(dns_altname, conn->host.name)) {
|
||||
found_subject_alt_name_matching_conn = 1;
|
||||
break;
|
||||
}
|
||||
@@ -338,21 +333,23 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* RFC2818 checks */
|
||||
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
/* Break connection ! */
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
|
||||
failf(data, "\tsubjectAltName(s) do not match %s\n",
|
||||
conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else
|
||||
infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
|
||||
infof(data, "\tsubjectAltName(s) do not match %s\n",
|
||||
conn->host.dispname);
|
||||
}
|
||||
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) {
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "unable to obtain common name from peer certificate");
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
@@ -361,17 +358,17 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
infof(data, "unable to obtain common name from peer certificate");
|
||||
}
|
||||
else {
|
||||
if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
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, dispname);
|
||||
peer_CN, conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else
|
||||
infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
|
||||
peer_CN, dispname);
|
||||
peer_CN, conn->host.dispname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,7 +381,7 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
/* Put our freshly minted SSL session in cache */
|
||||
ssl_idsize = ssl_get_session_id_size(ssl);
|
||||
ssl_sessionid = ssl_get_session_id(ssl);
|
||||
if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize, sockindex)
|
||||
if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
|
||||
!= CURLE_OK)
|
||||
infof (data, "failed to add session to cache\n");
|
||||
|
||||
|
@@ -117,7 +117,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
|
||||
@@ -168,7 +168,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
|
||||
@@ -191,18 +191,18 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* load trusted cacert */
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||
if(1 != SSL_CTX_load_verify_locations(conssl->ctx,
|
||||
SSL_CONN_CONFIG(CAfile),
|
||||
SSL_CONN_CONFIG(CApath))) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
data->set.str[STRING_SSL_CAFILE],
|
||||
data->set.str[STRING_SSL_CAPATH])) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* Fail if we insist on successfully verifying the server. */
|
||||
failf(data, "error setting certificate verify locations:\n"
|
||||
" CAfile: %s\n CApath: %s",
|
||||
SSL_CONN_CONFIG(CAfile)?
|
||||
SSL_CONN_CONFIG(CAfile): "none",
|
||||
SSL_CONN_CONFIG(CApath)?
|
||||
SSL_CONN_CONFIG(CApath) : "none");
|
||||
data->set.str[STRING_SSL_CAFILE]?
|
||||
data->set.str[STRING_SSL_CAFILE]: "none",
|
||||
data->set.str[STRING_SSL_CAPATH]?
|
||||
data->set.str[STRING_SSL_CAPATH] : "none");
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
else {
|
||||
@@ -219,25 +219,25 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
infof(data,
|
||||
" CAfile: %s\n"
|
||||
" CApath: %s\n",
|
||||
SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
|
||||
data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
|
||||
"none",
|
||||
SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
|
||||
data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
|
||||
"none");
|
||||
}
|
||||
|
||||
/* Load the client certificate, and private key */
|
||||
if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
|
||||
int file_type = do_file_type(SSL_SET_OPTION(cert_type));
|
||||
if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) {
|
||||
int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]);
|
||||
|
||||
if(SSL_CTX_use_certificate_file(conssl->ctx, SSL_SET_OPTION(cert),
|
||||
if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT],
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to use client certificate (no key or wrong pass"
|
||||
" phrase?)");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
file_type = do_file_type(SSL_SET_OPTION(key_type));
|
||||
if(SSL_CTX_use_PrivateKey_file(conssl->ctx, SSL_SET_OPTION(key),
|
||||
file_type = do_file_type(data->set.str[STRING_KEY_TYPE]);
|
||||
if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY],
|
||||
file_type) != 1) {
|
||||
failf(data, "unable to set private key");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -250,8 +250,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
* SSL_get_verify_result() below. */
|
||||
SSL_CTX_set_verify(conssl->ctx,
|
||||
SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
|
||||
SSL_VERIFY_NONE,
|
||||
data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
|
||||
NULL);
|
||||
|
||||
#ifdef HAVE_SNI
|
||||
@@ -260,15 +259,13 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
size_t hostname_len = strlen(hostname);
|
||||
size_t hostname_len = strlen(conn->host.name);
|
||||
if((hostname_len < USHRT_MAX) &&
|
||||
(0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
|
||||
(0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) &&
|
||||
#endif
|
||||
(CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, hostname,
|
||||
(CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name,
|
||||
(unsigned short)hostname_len) != 1)) {
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
@@ -287,7 +284,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
#ifdef NO_FILESYSTEM
|
||||
else if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
else if(data->set.ssl.verifypeer) {
|
||||
failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
|
||||
" with \"no filesystem\". Either disable peer verification"
|
||||
" (insecure) or if you are building an application with libcurl you"
|
||||
@@ -306,7 +303,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(conssl->handle, ssl_sessionid)) {
|
||||
failf(data, "SSL: SSL_set_session failed: %s",
|
||||
@@ -335,17 +332,13 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
int ret = -1;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ssl_connect_data* conssl = &conn->ssl[sockindex];
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.dispname : conn->host.dispname;
|
||||
|
||||
conn->recv[sockindex] = cyassl_recv;
|
||||
conn->send[sockindex] = cyassl_send;
|
||||
|
||||
/* Enable RFC2818 checks */
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
ret = CyaSSL_check_domain_name(conssl->handle, hostname);
|
||||
if(data->set.ssl.verifyhost) {
|
||||
ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
|
||||
if(ret == SSL_FAILURE)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -369,31 +362,31 @@ cyassl_connect_step2(struct connectdata *conn,
|
||||
else if(DOMAIN_NAME_MISMATCH == detail) {
|
||||
#if 1
|
||||
failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
|
||||
dispname);
|
||||
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. 'conn->ssl_config.verifyhost == 0',
|
||||
* 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 'conn->ssl_config.verifyhost' value. */
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
* 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",
|
||||
dispname);
|
||||
conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
infof(data,
|
||||
"\tsubject alt name(s) and/or common name do not match \"%s\"\n",
|
||||
dispname);
|
||||
conn->host.dispname);
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
|
||||
else if(ASN_NO_SIGNER_E == detail) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "\tCA signer not available for verification\n");
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
@@ -473,8 +466,7 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
|
||||
our_ssl_sessionid = SSL_get_session(connssl->handle);
|
||||
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
@@ -485,7 +477,7 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
|
||||
if(!incache) {
|
||||
result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
||||
0 /* unknown size */, sockindex);
|
||||
0 /* unknown size */);
|
||||
if(result) {
|
||||
failf(data, "failed to store ssl session");
|
||||
return result;
|
||||
|
@@ -1055,7 +1055,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||
if(SSLSetProtocolVersionMax != NULL) {
|
||||
switch(conn->ssl_config.version) {
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -1096,7 +1096,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||
kSSLProtocolAll,
|
||||
false);
|
||||
switch (conn->ssl_config.version) {
|
||||
switch (data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -1148,7 +1148,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
#else
|
||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||
switch(conn->ssl_config.version) {
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -1293,7 +1293,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#else
|
||||
if(SSLSetSessionOption != NULL) {
|
||||
#endif /* CURL_BUILD_MAC */
|
||||
bool break_on_auth = !conn->ssl_config.verifypeer ||
|
||||
bool break_on_auth = !data->set.ssl.verifypeer ||
|
||||
data->set.str[STRING_SSL_CAFILE];
|
||||
err = SSLSetSessionOption(connssl->ssl_ctx,
|
||||
kSSLSessionOptionBreakOnServerAuth,
|
||||
@@ -1306,7 +1306,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_8
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
conn->ssl_config.verifypeer?true:false);
|
||||
data->set.ssl.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -1315,7 +1315,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
#else
|
||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||
conn->ssl_config.verifypeer?true:false);
|
||||
data->set.ssl.verifypeer?true:false);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -1340,7 +1340,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
/* Configure hostname check. SNI is used if available.
|
||||
* Both hostname check and SNI require SSLSetPeerDomainName().
|
||||
* Also: the verifyhost setting influences SNI usage */
|
||||
if(conn->ssl_config.verifyhost) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
|
||||
strlen(conn->host.name));
|
||||
|
||||
|
317
lib/vtls/gskit.c
317
lib/vtls/gskit.c
@@ -81,10 +81,6 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/* Directions. */
|
||||
#define SOS_READ 0x01
|
||||
#define SOS_WRITE 0x02
|
||||
|
||||
/* SSL version flags. */
|
||||
#define CURL_GSKPROTO_SSLV2 0
|
||||
#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
|
||||
@@ -293,11 +289,10 @@ static CURLcode set_callback(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
|
||||
static CURLcode set_ciphers(struct connectdata *conn,
|
||||
static CURLcode set_ciphers(struct SessionHandle *data,
|
||||
gsk_handle h, unsigned int *protoflags)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
|
||||
const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
|
||||
const char *clp;
|
||||
const gskit_cipher *ctp;
|
||||
int i;
|
||||
@@ -505,195 +500,17 @@ static void close_async_handshake(struct ssl_connect_data *connssl)
|
||||
connssl->iocport = -1;
|
||||
}
|
||||
|
||||
/* SSL over SSL
|
||||
* Problems:
|
||||
* 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To
|
||||
* pipe an SSL stream into another, it is therefore needed to have a pair
|
||||
* of such communicating sockets and handle the pipelining explicitly.
|
||||
* 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot
|
||||
* be used to produce the pipeline.
|
||||
* The solution is to simulate socketpair() for AF_INET with low-level API
|
||||
* listen(), bind() and connect().
|
||||
*/
|
||||
|
||||
static int
|
||||
inetsocketpair(int sv[2])
|
||||
static void close_one(struct ssl_connect_data *conn,
|
||||
struct SessionHandle *data)
|
||||
{
|
||||
int lfd; /* Listening socket. */
|
||||
int sfd; /* Server socket. */
|
||||
int cfd; /* Client socket. */
|
||||
int len;
|
||||
struct sockaddr_in addr1;
|
||||
struct sockaddr_in addr2;
|
||||
|
||||
/* Create listening socket on a local dynamic port. */
|
||||
lfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(lfd < 0)
|
||||
return -1;
|
||||
memset((char *) &addr1, 0, sizeof addr1);
|
||||
addr1.sin_family = AF_INET;
|
||||
addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr1.sin_port = 0;
|
||||
if(bind(lfd, (struct sockaddr *) &addr1, sizeof addr1) ||
|
||||
listen(lfd, 2) < 0) {
|
||||
close(lfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the allocated port. */
|
||||
len = sizeof addr1;
|
||||
if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
|
||||
close(lfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the client socket. */
|
||||
cfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(cfd < 0) {
|
||||
close(lfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Request unblocking connection to the listening socket. */
|
||||
curlx_nonblock(cfd, TRUE);
|
||||
if(connect(cfd, (struct sockaddr *) &addr1, sizeof addr1) < 0 &&
|
||||
errno != EINPROGRESS) {
|
||||
close(lfd);
|
||||
close(cfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the client dynamic port for intrusion check below. */
|
||||
len = sizeof addr2;
|
||||
if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
|
||||
close(lfd);
|
||||
close(cfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Accept the incoming connection and get the server socket. */
|
||||
curlx_nonblock(lfd, TRUE);
|
||||
for (;;) {
|
||||
len = sizeof addr1;
|
||||
sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
|
||||
if(sfd < 0) {
|
||||
close(lfd);
|
||||
close(cfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for possible intrusion from an external process. */
|
||||
if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr &&
|
||||
addr1.sin_port == addr2.sin_port)
|
||||
break;
|
||||
|
||||
/* Intrusion: reject incoming connection. */
|
||||
close(sfd);
|
||||
}
|
||||
|
||||
/* Done, return sockets and succeed. */
|
||||
close(lfd);
|
||||
curlx_nonblock(cfd, FALSE);
|
||||
sv[0] = cfd;
|
||||
sv[1] = sfd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
|
||||
int directions)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
|
||||
fd_set fds_read;
|
||||
fd_set fds_write;
|
||||
int n;
|
||||
int m;
|
||||
int i;
|
||||
int ret = 0;
|
||||
struct timeval tv = {0, 0};
|
||||
char buf[CURL_MAX_WRITE_SIZE];
|
||||
|
||||
if(!connssl->use || !connproxyssl->use)
|
||||
return 0; /* No SSL over SSL: OK. */
|
||||
|
||||
FD_ZERO(&fds_read);
|
||||
FD_ZERO(&fds_write);
|
||||
n = -1;
|
||||
if(directions & SOS_READ) {
|
||||
FD_SET(connssl->remotefd, &fds_write);
|
||||
n = connssl->remotefd;
|
||||
}
|
||||
if(directions & SOS_WRITE) {
|
||||
FD_SET(connssl->remotefd, &fds_read);
|
||||
n = connssl->remotefd;
|
||||
FD_SET(conn->sock[sockindex], &fds_write);
|
||||
if(n < conn->sock[sockindex])
|
||||
n = conn->sock[sockindex];
|
||||
}
|
||||
i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
|
||||
if(i < 0)
|
||||
return -1; /* Select error. */
|
||||
|
||||
if(FD_ISSET(connssl->remotefd, &fds_write)) {
|
||||
/* Try getting data from HTTPS proxy and pipe it upstream. */
|
||||
n = 0;
|
||||
i = gsk_secure_soc_read(connproxyssl->handle, buf, sizeof buf, &n);
|
||||
switch(i) {
|
||||
case GSK_OK:
|
||||
if(n) {
|
||||
i = write(connssl->remotefd, buf, n);
|
||||
if(i < 0)
|
||||
return -1;
|
||||
ret = 1;
|
||||
}
|
||||
break;
|
||||
case GSK_OS400_ERROR_TIMED_OUT:
|
||||
case GSK_WOULD_BLOCK:
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(FD_ISSET(connssl->remotefd, &fds_read) &&
|
||||
FD_ISSET(conn->sock[sockindex], &fds_write)) {
|
||||
/* Pipe data to HTTPS proxy. */
|
||||
n = read(connssl->remotefd, buf, sizeof buf);
|
||||
if(n < 0)
|
||||
return -1;
|
||||
if(n) {
|
||||
i = gsk_secure_soc_write(connproxyssl->handle, buf, n, &m);
|
||||
if(i != GSK_OK || n != m)
|
||||
return -1;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret; /* OK */
|
||||
}
|
||||
|
||||
|
||||
static void close_one(struct ssl_connect_data *connssl,
|
||||
struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(connssl->handle) {
|
||||
gskit_status(conn->data, gsk_secure_soc_close(&connssl->handle),
|
||||
if(conn->handle) {
|
||||
gskit_status(data, gsk_secure_soc_close(&conn->handle),
|
||||
"gsk_secure_soc_close()", 0);
|
||||
/* Last chance to drain output. */
|
||||
while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
|
||||
;
|
||||
connssl->handle = (gsk_handle) NULL;
|
||||
if(connssl->localfd >= 0) {
|
||||
close(connssl->localfd);
|
||||
connssl->localfd = -1;
|
||||
}
|
||||
if(connssl->remotefd >= 0) {
|
||||
close(connssl->remotefd);
|
||||
connssl->remotefd = -1;
|
||||
}
|
||||
conn->handle = (gsk_handle) NULL;
|
||||
}
|
||||
if(connssl->iocport >= 0)
|
||||
close_async_handshake(connssl);
|
||||
if(conn->iocport >= 0)
|
||||
close_async_handshake(conn);
|
||||
}
|
||||
|
||||
|
||||
@@ -701,18 +518,13 @@ static ssize_t gskit_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *curlcode)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode cc = CURLE_SEND_ERROR;
|
||||
CURLcode cc;
|
||||
int written;
|
||||
|
||||
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
|
||||
cc = gskit_status(data,
|
||||
gsk_secure_soc_write(conn->ssl[sockindex].handle,
|
||||
(char *) mem, (int) len, &written),
|
||||
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
|
||||
if(cc == CURLE_OK)
|
||||
if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
|
||||
cc = CURLE_SEND_ERROR;
|
||||
}
|
||||
cc = gskit_status(data,
|
||||
gsk_secure_soc_write(conn->ssl[sockindex].handle,
|
||||
(char *) mem, (int) len, &written),
|
||||
"gsk_secure_soc_write()", CURLE_SEND_ERROR);
|
||||
if(cc != CURLE_OK) {
|
||||
*curlcode = cc;
|
||||
written = -1;
|
||||
@@ -727,23 +539,15 @@ static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
|
||||
struct SessionHandle *data = conn->data;
|
||||
int buffsize;
|
||||
int nread;
|
||||
CURLcode cc = CURLE_RECV_ERROR;
|
||||
CURLcode cc;
|
||||
|
||||
if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
|
||||
buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
|
||||
cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
|
||||
buf, buffsize, &nread),
|
||||
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
|
||||
}
|
||||
switch(cc) {
|
||||
case CURLE_OK:
|
||||
break;
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
cc = CURLE_AGAIN;
|
||||
default:
|
||||
buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
|
||||
cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle,
|
||||
buf, buffsize, &nread),
|
||||
"gsk_secure_soc_read()", CURLE_RECV_ERROR);
|
||||
if(cc != CURLE_OK) {
|
||||
*curlcode = cc;
|
||||
nread = -1;
|
||||
break;
|
||||
}
|
||||
return (ssize_t) nread;
|
||||
}
|
||||
@@ -756,26 +560,18 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
gsk_handle envir;
|
||||
CURLcode result;
|
||||
int rc;
|
||||
const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
|
||||
const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
|
||||
const char * const keyringlabel = SSL_SET_OPTION(cert);
|
||||
const long int ssl_version = SSL_CONN_CONFIG(version);
|
||||
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
|
||||
const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
|
||||
conn->host.name;
|
||||
const char *sni;
|
||||
char *keyringfile;
|
||||
char *keyringpwd;
|
||||
char *keyringlabel;
|
||||
char *sni;
|
||||
unsigned int protoflags;
|
||||
long timeout;
|
||||
Qso_OverlappedIO_t commarea;
|
||||
int sockpair[2];
|
||||
static const int sobufsize = CURL_MAX_WRITE_SIZE;
|
||||
|
||||
/* Create SSL environment, start (preferably asynchronous) handshake. */
|
||||
|
||||
connssl->handle = (gsk_handle) NULL;
|
||||
connssl->iocport = -1;
|
||||
connssl->localfd = -1;
|
||||
connssl->remotefd = -1;
|
||||
|
||||
/* GSKit supports two ways of specifying an SSL context: either by
|
||||
* application identifier (that should have been defined at the system
|
||||
@@ -790,6 +586,9 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
* application identifier mode is tried first, as recommended in IBM doc.
|
||||
*/
|
||||
|
||||
keyringfile = data->set.str[STRING_SSL_CAFILE];
|
||||
keyringpwd = data->set.str[STRING_KEY_PASSWD];
|
||||
keyringlabel = data->set.str[STRING_CERT];
|
||||
envir = (gsk_handle) NULL;
|
||||
|
||||
if(keyringlabel && *keyringlabel && !keyringpwd &&
|
||||
@@ -814,36 +613,18 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Establish a pipelining socket pair for SSL over SSL. */
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
if(inetsocketpair(sockpair))
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
connssl->localfd = sockpair[0];
|
||||
connssl->remotefd = sockpair[1];
|
||||
setsockopt(connssl->localfd, SOL_SOCKET, SO_RCVBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->remotefd, SOL_SOCKET, SO_RCVBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->localfd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
setsockopt(connssl->remotefd, SOL_SOCKET, SO_SNDBUF,
|
||||
(void *) sobufsize, sizeof sobufsize);
|
||||
curlx_nonblock(connssl->localfd, TRUE);
|
||||
curlx_nonblock(connssl->remotefd, TRUE);
|
||||
}
|
||||
|
||||
/* Determine which SSL/TLS version should be enabled. */
|
||||
protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
|
||||
CURL_GSKPROTO_TLSV12_MASK;
|
||||
sni = hostname;
|
||||
switch (ssl_version) {
|
||||
sni = conn->host.name;
|
||||
switch (data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_SSLv2:
|
||||
protoflags = CURL_GSKPROTO_SSLV2_MASK;
|
||||
sni = NULL;
|
||||
sni = (char *) NULL;
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
protoflags = CURL_GSKPROTO_SSLV3_MASK;
|
||||
sni = NULL;
|
||||
sni = (char *) NULL;
|
||||
break;
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
protoflags = CURL_GSKPROTO_TLSV10_MASK |
|
||||
@@ -880,12 +661,9 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
(timeout + 999) / 1000);
|
||||
}
|
||||
if(!result)
|
||||
result = set_numeric(data, connssl->handle, GSK_OS400_READ_TIMEOUT, 1);
|
||||
result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
|
||||
if(!result)
|
||||
result = set_numeric(data, connssl->handle, GSK_FD, connssl->localfd >= 0?
|
||||
connssl->localfd: conn->sock[sockindex]);
|
||||
if(!result)
|
||||
result = set_ciphers(conn, connssl->handle, &protoflags);
|
||||
result = set_ciphers(data, connssl->handle, &protoflags);
|
||||
if(!protoflags) {
|
||||
failf(data, "No SSL protocol/cipher combination enabled");
|
||||
result = CURLE_SSL_CIPHER;
|
||||
@@ -928,7 +706,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
if(!result)
|
||||
result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
|
||||
verifypeer? GSK_SERVER_AUTH_FULL:
|
||||
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
|
||||
GSK_SERVER_AUTH_PASSTHRU, FALSE);
|
||||
|
||||
if(!result) {
|
||||
@@ -952,10 +730,6 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
else if(errno != ENOBUFS)
|
||||
result = gskit_status(data, GSK_ERROR_IO,
|
||||
"QsoCreateIOCompletionPort()", 0);
|
||||
else if(conn->proxy_ssl[sockindex].use) {
|
||||
/* Cannot pipeline while handshaking synchronously. */
|
||||
result = CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
else {
|
||||
/* No more completion port available. Use synchronous IO. */
|
||||
result = gskit_status(data, gsk_secure_soc_init(connssl->handle),
|
||||
@@ -968,7 +742,7 @@ static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* Error: rollback. */
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1139,11 +913,6 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
result = gskit_connect_step1(conn, sockindex);
|
||||
}
|
||||
|
||||
/* Handle handshake pipelining. */
|
||||
if(!result)
|
||||
if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
|
||||
result = CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* Step 2: check if handshake is over. */
|
||||
if(!result && connssl->connecting_state == ssl_connect_2) {
|
||||
/* check allowed time left */
|
||||
@@ -1158,17 +927,12 @@ static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
|
||||
result = gskit_connect_step2(conn, sockindex, nonblocking);
|
||||
}
|
||||
|
||||
/* Handle handshake pipelining. */
|
||||
if(!result)
|
||||
if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
|
||||
result = CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
/* Step 3: gather certificate info, verify host. */
|
||||
if(!result && connssl->connecting_state == ssl_connect_3)
|
||||
result = gskit_connect_step3(conn, sockindex);
|
||||
|
||||
if(result)
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data);
|
||||
else if(connssl->connecting_state == ssl_connect_done) {
|
||||
connssl->state = ssl_connection_complete;
|
||||
connssl->connecting_state = ssl_connect_1;
|
||||
@@ -1212,8 +976,11 @@ CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
void Curl_gskit_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
close_one(&conn->ssl[sockindex], conn, sockindex);
|
||||
close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(connssl->use)
|
||||
close_one(connssl, data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1232,7 +999,7 @@ int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
|
||||
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
|
||||
return 0;
|
||||
|
||||
close_one(connssl, conn, sockindex);
|
||||
close_one(connssl, data);
|
||||
rc = 0;
|
||||
what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
|
257
lib/vtls/gtls.c
257
lib/vtls/gtls.c
@@ -171,16 +171,6 @@ static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t Curl_gtls_push_ssl(void *s, const void *buf, size_t len)
|
||||
{
|
||||
return gnutls_record_send((gnutls_session_t) s, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t Curl_gtls_pull_ssl(void *s, void *buf, size_t len)
|
||||
{
|
||||
return gnutls_record_recv((gnutls_session_t) s, buf, len);
|
||||
}
|
||||
|
||||
/* Curl_gtls_init()
|
||||
*
|
||||
* Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
|
||||
@@ -383,9 +373,6 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
void *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
bool sni = TRUE; /* default is SNI enabled */
|
||||
void *transport_ptr = NULL;
|
||||
gnutls_push_func gnutls_transport_push = NULL;
|
||||
gnutls_pull_func gnutls_transport_pull = NULL;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr;
|
||||
#else
|
||||
@@ -416,9 +403,6 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
const char *err = NULL;
|
||||
#endif
|
||||
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
if(conn->ssl[sockindex].state == ssl_connection_complete)
|
||||
/* to make us tolerant against being called more than once for the
|
||||
same connection */
|
||||
@@ -428,11 +412,11 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
Curl_gtls_init();
|
||||
|
||||
/* GnuTLS only supports SSLv3 and TLSv1 */
|
||||
if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
|
||||
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
|
||||
failf(data, "GnuTLS does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
|
||||
else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
|
||||
sni = FALSE; /* SSLv3 has no SNI */
|
||||
|
||||
/* allocate a cred struct */
|
||||
@@ -443,8 +427,8 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
|
||||
infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
|
||||
|
||||
rc = gnutls_srp_allocate_client_credentials(
|
||||
&conn->ssl[sockindex].srp_client_cred);
|
||||
@@ -456,8 +440,8 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
|
||||
rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
|
||||
srp_client_cred,
|
||||
SSL_SET_OPTION(username),
|
||||
SSL_SET_OPTION(password));
|
||||
data->set.ssl.username,
|
||||
data->set.ssl.password);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_srp_set_client_cred() failed: %s",
|
||||
gnutls_strerror(rc));
|
||||
@@ -466,56 +450,56 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(data->set.ssl.CAfile) {
|
||||
/* set the trusted CA cert bundle file */
|
||||
gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
|
||||
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
|
||||
|
||||
rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
|
||||
SSL_CONN_CONFIG(CAfile),
|
||||
data->set.ssl.CAfile,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
infof(data, "error reading ca cert file %s (%s)\n",
|
||||
SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
|
||||
if(SSL_CONN_CONFIG(verifypeer))
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
else
|
||||
infof(data, "found %d certificates in %s\n", rc,
|
||||
SSL_CONN_CONFIG(CAfile));
|
||||
}
|
||||
|
||||
#ifdef HAS_CAPATH
|
||||
if(SSL_CONN_CONFIG(CApath)) {
|
||||
/* set the trusted CA cert directory */
|
||||
rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
|
||||
SSL_CONN_CONFIG(CApath),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
infof(data, "error reading ca cert file %s (%s)\n",
|
||||
SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
|
||||
if(SSL_CONN_CONFIG(verifypeer))
|
||||
data->set.ssl.CAfile, gnutls_strerror(rc));
|
||||
if(data->set.ssl.verifypeer)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
else
|
||||
infof(data, "found %d certificates in %s\n",
|
||||
rc, SSL_CONN_CONFIG(CApath));
|
||||
rc, data->set.ssl.CAfile);
|
||||
}
|
||||
|
||||
#ifdef HAS_CAPATH
|
||||
if(data->set.ssl.CApath) {
|
||||
/* set the trusted CA cert directory */
|
||||
rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
|
||||
data->set.ssl.CApath,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
infof(data, "error reading ca cert file %s (%s)\n",
|
||||
data->set.ssl.CAfile, gnutls_strerror(rc));
|
||||
if(data->set.ssl.verifypeer)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
else
|
||||
infof(data, "found %d certificates in %s\n",
|
||||
rc, data->set.ssl.CApath);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(SSL_SET_OPTION(CRLfile)) {
|
||||
if(data->set.ssl.CRLfile) {
|
||||
/* set the CRL list file */
|
||||
rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
|
||||
SSL_SET_OPTION(CRLfile),
|
||||
data->set.ssl.CRLfile,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(rc < 0) {
|
||||
failf(data, "error reading crl file %s (%s)",
|
||||
SSL_SET_OPTION(CRLfile), gnutls_strerror(rc));
|
||||
data->set.ssl.CRLfile, gnutls_strerror(rc));
|
||||
return CURLE_SSL_CRL_BADFILE;
|
||||
}
|
||||
else
|
||||
infof(data, "found %d CRL in %s\n",
|
||||
rc, SSL_SET_OPTION(CRLfile));
|
||||
rc, data->set.ssl.CRLfile);
|
||||
}
|
||||
|
||||
/* Initialize TLS session as a client */
|
||||
@@ -528,13 +512,13 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* convenient assign */
|
||||
session = conn->ssl[sockindex].session;
|
||||
|
||||
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
|
||||
if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||
#endif
|
||||
sni &&
|
||||
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname,
|
||||
strlen(hostname)) < 0))
|
||||
(gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name,
|
||||
strlen(conn->host.name)) < 0))
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
|
||||
@@ -555,13 +539,13 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
if(rc != GNUTLS_E_SUCCESS)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
|
||||
if(SSL_CONN_CONFIG(cipher_list) != NULL) {
|
||||
if(data->set.ssl.cipher_list != NULL) {
|
||||
failf(data, "can't pass a custom cipher list to older GnuTLS"
|
||||
" versions");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
switch (SSL_CONN_CONFIG(version) {
|
||||
switch (data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
protocol_priority[0] = GNUTLS_SSL3;
|
||||
break;
|
||||
@@ -596,7 +580,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* Ensure +SRP comes at the *end* of all relevant strings so that it can be
|
||||
* removed if a run-time error indicates that SRP is not supported by this
|
||||
* GnuTLS version */
|
||||
switch (SSL_CONN_CONFIG(version)) {
|
||||
switch (data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
|
||||
sni = false;
|
||||
@@ -671,8 +655,8 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(SSL_SET_OPTION(cert)) {
|
||||
if(SSL_SET_OPTION(key_passwd)) {
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
if(data->set.str[STRING_KEY_PASSWD]) {
|
||||
#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
|
||||
const unsigned int supported_key_encryption_algorithms =
|
||||
GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
|
||||
@@ -681,11 +665,11 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
GNUTLS_PKCS_USE_PBES2_AES_256;
|
||||
rc = gnutls_certificate_set_x509_key_file2(
|
||||
conn->ssl[sockindex].cred,
|
||||
SSL_SET_OPTION(cert),
|
||||
SSL_SET_OPTION(key) ?
|
||||
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
|
||||
do_file_type(SSL_SET_OPTION(cert_type)),
|
||||
SSL_SET_OPTION(key_passwd),
|
||||
data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY] ?
|
||||
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
||||
do_file_type(data->set.str[STRING_CERT_TYPE]),
|
||||
data->set.str[STRING_KEY_PASSWD],
|
||||
supported_key_encryption_algorithms);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data,
|
||||
@@ -699,14 +683,15 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(gnutls_certificate_set_x509_key_file(
|
||||
rc = gnutls_certificate_set_x509_key_file(
|
||||
conn->ssl[sockindex].cred,
|
||||
SSL_SET_OPTION(cert),
|
||||
SSL_SET_OPTION(key) ?
|
||||
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
|
||||
do_file_type(SSL_SET_OPTION(cert_type)) ) !=
|
||||
GNUTLS_E_SUCCESS) {
|
||||
failf(data, "error reading X.509 key or certificate file");
|
||||
data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY] ?
|
||||
data->set.str[STRING_KEY] : data->set.str[STRING_CERT],
|
||||
do_file_type(data->set.str[STRING_CERT_TYPE]) );
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "error reading X.509 key or certificate file: %s",
|
||||
gnutls_strerror(rc));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -714,7 +699,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
/* put the credentials to the current session */
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
||||
conn->ssl[sockindex].srp_client_cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
@@ -733,30 +718,19 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
transport_ptr = conn->proxy_ssl[sockindex].session;
|
||||
gnutls_transport_push = Curl_gtls_push_ssl;
|
||||
gnutls_transport_pull = Curl_gtls_pull_ssl;
|
||||
}
|
||||
else {
|
||||
/* file descriptor for the socket */
|
||||
transport_ptr = GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]);
|
||||
gnutls_transport_push = Curl_gtls_push;
|
||||
gnutls_transport_pull = Curl_gtls_pull;
|
||||
}
|
||||
|
||||
/* set the connection handle */
|
||||
gnutls_transport_set_ptr(session, transport_ptr);
|
||||
/* set the connection handle (file descriptor for the socket) */
|
||||
gnutls_transport_set_ptr(session,
|
||||
GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex]));
|
||||
|
||||
/* register callback functions to send and receive data. */
|
||||
gnutls_transport_set_push_function(session, gnutls_transport_push);
|
||||
gnutls_transport_set_pull_function(session, gnutls_transport_pull);
|
||||
gnutls_transport_set_push_function(session, Curl_gtls_push);
|
||||
gnutls_transport_set_pull_function(session, Curl_gtls_pull);
|
||||
|
||||
/* lowat must be set to zero when using custom push and pull functions. */
|
||||
gnutls_transport_set_lowat(session, 0);
|
||||
|
||||
#ifdef HAS_OCSP
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(data->set.ssl.verifystatus) {
|
||||
rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
|
||||
@@ -768,7 +742,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
/* This might be a reconnect, so we check for a session ID in the cache
|
||||
to speed up things */
|
||||
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) {
|
||||
/* we got a session id, use it! */
|
||||
gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
|
||||
|
||||
@@ -863,9 +837,8 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
gnutls_datum_t proto;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
gnutls_protocol_t version = gnutls_protocol_get_version(session);
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
/* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
|
||||
ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
|
||||
@@ -883,13 +856,13 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
|
||||
chainp = gnutls_certificate_get_peers(session, &cert_list_size);
|
||||
if(!chainp) {
|
||||
if(SSL_CONN_CONFIG(verifypeer) ||
|
||||
SSL_CONN_CONFIG(verifyhost) ||
|
||||
if(data->set.ssl.verifypeer ||
|
||||
data->set.ssl.verifyhost ||
|
||||
data->set.ssl.issuercert) {
|
||||
#ifdef USE_TLS_SRP
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
|
||||
&& SSL_SET_OPTION(username) != NULL
|
||||
&& !SSL_CONN_CONFIG(verifypeer)
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
|
||||
&& data->set.ssl.username != NULL
|
||||
&& !data->set.ssl.verifypeer
|
||||
&& gnutls_cipher_get(session)) {
|
||||
/* no peer cert, but auth is ok if we have SRP user and cipher and no
|
||||
peer verify */
|
||||
@@ -922,7 +895,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* This function will try to verify the peer's certificate and return its
|
||||
status (trusted, invalid etc.). The value of status should be one or
|
||||
more of the gnutls_certificate_status_t enumerated elements bitwise
|
||||
@@ -938,11 +911,10 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
|
||||
/* verify_status is a bitmask of gnutls_certificate_status bits */
|
||||
if(verify_status & GNUTLS_CERT_INVALID) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "server certificate verification failed. CAfile: %s "
|
||||
"CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
|
||||
"none",
|
||||
SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
|
||||
"CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none",
|
||||
data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none");
|
||||
return CURLE_SSL_CACERT;
|
||||
}
|
||||
else
|
||||
@@ -955,7 +927,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
infof(data, "\t server certificate verification SKIPPED\n");
|
||||
|
||||
#ifdef HAS_OCSP
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(data->set.ssl.verifystatus) {
|
||||
if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
|
||||
gnutls_datum_t status_request;
|
||||
gnutls_ocsp_resp_t ocsp_resp;
|
||||
@@ -1100,7 +1072,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
in RFC2818 (HTTPS), which takes into account wildcards, and the subject
|
||||
alternative name PKIX extension. Returns non zero on success, and zero on
|
||||
failure. */
|
||||
rc = gnutls_x509_crt_check_hostname(x509_cert, hostname);
|
||||
rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name);
|
||||
#if GNUTLS_VERSION_NUMBER < 0x030306
|
||||
/* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
|
||||
addresses. */
|
||||
@@ -1116,10 +1088,10 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
|
||||
if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0)
|
||||
addrlen = 4;
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0)
|
||||
else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0)
|
||||
addrlen = 16;
|
||||
#endif
|
||||
|
||||
@@ -1144,18 +1116,15 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
if(!rc) {
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.dispname : conn->host.dispname;
|
||||
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
failf(data, "SSL: certificate subject name (%s) does not match "
|
||||
"target host name '%s'", certbuf, dispname);
|
||||
"target host name '%s'", certbuf, conn->host.dispname);
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else
|
||||
infof(data, "\t common name: %s (does not match '%s')\n",
|
||||
certbuf, dispname);
|
||||
certbuf, conn->host.dispname);
|
||||
}
|
||||
else
|
||||
infof(data, "\t common name: %s (matched)\n", certbuf);
|
||||
@@ -1164,7 +1133,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
|
||||
|
||||
if(certclock == (time_t)-1) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "server cert expiration date verify failed");
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -1174,7 +1143,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
if(certclock < time(NULL)) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "server certificate expiration date has passed.");
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
@@ -1189,7 +1158,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
certclock = gnutls_x509_crt_get_activation_time(x509_cert);
|
||||
|
||||
if(certclock == (time_t)-1) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "server cert activation date verify failed");
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -1199,7 +1168,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
else {
|
||||
if(certclock > time(NULL)) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
failf(data, "server certificate not activated yet.");
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
@@ -1307,8 +1276,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
/* extract session ID to the allocated buffer */
|
||||
gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
|
||||
|
||||
incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL));
|
||||
if(incache) {
|
||||
/* there was one before in the cache, so instead of risking that the
|
||||
previous one was rejected, we just kill that and store the new */
|
||||
@@ -1316,8 +1284,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* store this session id */
|
||||
result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize,
|
||||
sockindex);
|
||||
result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
|
||||
if(result) {
|
||||
free(connect_sessionid);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@@ -1398,20 +1365,6 @@ Curl_gtls_connect(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
bool Curl_gtls_data_pending(const struct connectdata *conn, int connindex)
|
||||
{
|
||||
bool res = FALSE;
|
||||
if(conn->ssl[connindex].session &&
|
||||
0 != gnutls_record_check_pending(conn->ssl[connindex].session))
|
||||
res = TRUE;
|
||||
|
||||
if(conn->proxy_ssl[connindex].session &&
|
||||
0 != gnutls_record_check_pending(conn->proxy_ssl[connindex].session))
|
||||
res = TRUE;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t gtls_send(struct connectdata *conn,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
@@ -1431,29 +1384,29 @@ static ssize_t gtls_send(struct connectdata *conn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void close_one(struct ssl_connect_data *ssl)
|
||||
static void close_one(struct connectdata *conn,
|
||||
int idx)
|
||||
{
|
||||
if(ssl->session) {
|
||||
gnutls_bye(ssl->session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(ssl->session);
|
||||
ssl->session = NULL;
|
||||
if(conn->ssl[idx].session) {
|
||||
gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(conn->ssl[idx].session);
|
||||
conn->ssl[idx].session = NULL;
|
||||
}
|
||||
if(ssl->cred) {
|
||||
gnutls_certificate_free_credentials(ssl->cred);
|
||||
ssl->cred = NULL;
|
||||
if(conn->ssl[idx].cred) {
|
||||
gnutls_certificate_free_credentials(conn->ssl[idx].cred);
|
||||
conn->ssl[idx].cred = NULL;
|
||||
}
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl->srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(ssl->srp_client_cred);
|
||||
ssl->srp_client_cred = NULL;
|
||||
if(conn->ssl[idx].srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
|
||||
conn->ssl[idx].srp_client_cred = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Curl_gtls_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
close_one(&conn->ssl[sockindex]);
|
||||
close_one(&conn->proxy_ssl[sockindex]);
|
||||
close_one(conn, sockindex);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1519,8 +1472,8 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
|
||||
&& SSL_SET_OPTION(username) != NULL)
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
|
||||
&& data->set.ssl.username != NULL)
|
||||
gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
|
||||
#endif
|
||||
|
||||
@@ -1586,8 +1539,14 @@ static int Curl_gtls_seed(struct SessionHandle *data)
|
||||
/* Quickly add a bit of entropy */
|
||||
gcry_fast_random_poll();
|
||||
|
||||
if(!ssl_seeded || data->set.ssl.primary.random_file ||
|
||||
data->set.ssl.primary.egdsocket) {
|
||||
if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
|
||||
data->set.str[STRING_SSL_EGDSOCKET]) {
|
||||
|
||||
/* TODO: to a good job seeding the RNG
|
||||
This may involve the gcry_control function and these options:
|
||||
GCRYCTL_SET_RANDOM_SEED_FILE
|
||||
GCRYCTL_SET_RNDEGD_SOCKET
|
||||
*/
|
||||
ssl_seeded = TRUE;
|
||||
}
|
||||
return 0;
|
||||
|
@@ -34,8 +34,6 @@ CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
|
||||
CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
|
||||
int sockindex,
|
||||
bool *done);
|
||||
bool Curl_gtls_data_pending(const struct connectdata *conn,
|
||||
int connindex);
|
||||
|
||||
/* close a SSL connection */
|
||||
void Curl_gtls_close(struct connectdata *conn, int sockindex);
|
||||
@@ -80,7 +78,7 @@ bool Curl_gtls_cert_status_request(void);
|
||||
#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL)
|
||||
#define curlssl_version Curl_gtls_version
|
||||
#define curlssl_check_cxn(x) ((void)x, -1)
|
||||
#define curlssl_data_pending(x,y) Curl_gtls_data_pending(x,y)
|
||||
#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
|
||||
#define curlssl_random(x,y,z) Curl_gtls_random(x,y,z)
|
||||
#define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d)
|
||||
#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d)
|
||||
|
170
lib/vtls/nss.c
170
lib/vtls/nss.c
@@ -319,8 +319,9 @@ static int is_file(const char *filename)
|
||||
* should be later deallocated using free(). If the OOM failure occurs, we
|
||||
* return NULL, too.
|
||||
*/
|
||||
static char* dup_nickname(struct SessionHandle *data, const char *str)
|
||||
static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
|
||||
{
|
||||
const char *str = data->set.str[cert_kind];
|
||||
const char *n;
|
||||
|
||||
if(!is_file(str))
|
||||
@@ -553,7 +554,6 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
|
||||
SECStatus status;
|
||||
CURLcode result;
|
||||
struct ssl_connect_data *ssl = conn->ssl;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
@@ -571,7 +571,8 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
|
||||
SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
|
||||
PK11_IsPresent(slot);
|
||||
|
||||
status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
|
||||
status = PK11_Authenticate(slot, PR_TRUE,
|
||||
conn->data->set.str[STRING_KEY_PASSWD]);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
|
||||
@@ -650,7 +651,7 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
|
||||
struct connectdata *conn = (struct connectdata *)arg;
|
||||
|
||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(conn->data->set.ssl.verifystatus) {
|
||||
SECStatus cacheResult;
|
||||
|
||||
const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
|
||||
@@ -676,7 +677,7 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(!conn->data->set.ssl.verifypeer) {
|
||||
infof(conn->data, "skipping SSL peer certificate verification\n");
|
||||
return SECSuccess;
|
||||
}
|
||||
@@ -896,12 +897,9 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
|
||||
CERTCertificate *cert;
|
||||
|
||||
/* remember the cert verification result */
|
||||
if(SSL_IS_PROXY())
|
||||
data->set.proxy_ssl.certverifyresult = err;
|
||||
else
|
||||
data->set.ssl.certverifyresult = err;
|
||||
data->set.ssl.certverifyresult = err;
|
||||
|
||||
if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
|
||||
if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost)
|
||||
/* we are asked not to verify the host name */
|
||||
return SECSuccess;
|
||||
|
||||
@@ -1336,55 +1334,36 @@ Curl_nss_check_cxn(struct connectdata *conn)
|
||||
return -1; /* connection status unknown */
|
||||
}
|
||||
|
||||
static void nss_close(struct ssl_connect_data *connssl)
|
||||
{
|
||||
/* before the cleanup, check whether we are using a client certificate */
|
||||
const bool client_cert = (connssl->client_nickname != NULL)
|
||||
|| (connssl->obj_clicert != NULL);
|
||||
|
||||
free(connssl->client_nickname);
|
||||
connssl->client_nickname = NULL;
|
||||
|
||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||
Curl_llist_destroy(connssl->obj_list, NULL);
|
||||
connssl->obj_list = NULL;
|
||||
connssl->obj_clicert = NULL;
|
||||
|
||||
if(connssl->handle) {
|
||||
if(client_cert)
|
||||
/* A server might require different authentication based on the
|
||||
* particular path being requested by the client. To support this
|
||||
* scenario, we must ensure that a connection will never reuse the
|
||||
* authentication data from a previous connection. */
|
||||
SSL_InvalidateSession(connssl->handle);
|
||||
|
||||
PR_Close(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called when an SSL connection is closed.
|
||||
*/
|
||||
void Curl_nss_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
|
||||
|
||||
if(connssl->handle || connssl_proxy->handle) {
|
||||
if(connssl->handle) {
|
||||
/* NSS closes the socket we previously handed to it, so we must mark it
|
||||
as closed to avoid double close */
|
||||
fake_sclose(conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
|
||||
if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL))
|
||||
/* A server might require different authentication based on the
|
||||
* particular path being requested by the client. To support this
|
||||
* scenario, we must ensure that a connection will never reuse the
|
||||
* authentication data from a previous connection. */
|
||||
SSL_InvalidateSession(connssl->handle);
|
||||
|
||||
free(connssl->client_nickname);
|
||||
connssl->client_nickname = NULL;
|
||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||
Curl_llist_destroy(connssl->obj_list, NULL);
|
||||
connssl->obj_list = NULL;
|
||||
connssl->obj_clicert = NULL;
|
||||
|
||||
PR_Close(connssl->handle);
|
||||
connssl->handle = NULL;
|
||||
}
|
||||
|
||||
if(connssl->handle)
|
||||
/* nss_close(connssl) will transitively close also connssl_proxy->handle
|
||||
if both are used. Clear it to avoid a double close leading to crash. */
|
||||
connssl_proxy->handle = NULL;
|
||||
|
||||
nss_close(connssl);
|
||||
nss_close(connssl_proxy);
|
||||
}
|
||||
|
||||
/* return true if NSS can provide error code (and possibly msg) for the
|
||||
@@ -1425,8 +1404,8 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *cafile = SSL_CONN_CONFIG(CAfile);
|
||||
const char *capath = SSL_CONN_CONFIG(CApath);
|
||||
const char *cafile = data->set.ssl.CAfile;
|
||||
const char *capath = data->set.ssl.CApath;
|
||||
|
||||
if(cafile) {
|
||||
CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
|
||||
@@ -1474,10 +1453,9 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
}
|
||||
|
||||
static CURLcode nss_init_sslver(SSLVersionRange *sslver,
|
||||
struct SessionHandle *data,
|
||||
struct connectdata *conn)
|
||||
struct SessionHandle *data)
|
||||
{
|
||||
switch (SSL_CONN_CONFIG(version)) {
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -1578,7 +1556,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
CURLcode result;
|
||||
bool second_layer = FALSE;
|
||||
|
||||
SSLVersionRange sslver = {
|
||||
SSL_LIBRARY_VERSION_TLS_1_0, /* min */
|
||||
@@ -1637,18 +1614,18 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
|
||||
/* do not use SSL cache if disabled or we are not going to verify peer */
|
||||
ssl_no_cache = (data->set.general_ssl.sessionid
|
||||
&& SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
|
||||
ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
|
||||
PR_FALSE : PR_TRUE;
|
||||
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* enable/disable the requested SSL version(s) */
|
||||
if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
|
||||
if(nss_init_sslver(&sslver, data) != CURLE_OK)
|
||||
goto error;
|
||||
if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
ssl_cbc_random_iv = !SSL_SET_OPTION(enable_beast);
|
||||
ssl_cbc_random_iv = !data->set.ssl_enable_beast;
|
||||
#ifdef SSL_CBC_RANDOM_IV
|
||||
/* unless the user explicitly asks to allow the protocol vulnerability, we
|
||||
use the work-around */
|
||||
@@ -1660,14 +1637,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
|
||||
#endif
|
||||
|
||||
if(SSL_CONN_CONFIG(cipher_list)) {
|
||||
if(set_ciphers(data, model, SSL_CONN_CONFIG(cipher_list)) != SECSuccess) {
|
||||
if(data->set.ssl.cipher_list) {
|
||||
if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
|
||||
result = CURLE_SSL_CIPHER;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost))
|
||||
if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost)
|
||||
infof(data, "warning: ignoring value of ssl.verifyhost\n");
|
||||
|
||||
/* bypass the default SSL_AuthCertificate() hook in case we do not want to
|
||||
@@ -1675,19 +1652,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* not checked yet */
|
||||
if(SSL_IS_PROXY())
|
||||
data->set.proxy_ssl.certverifyresult = 0;
|
||||
else
|
||||
data->set.ssl.certverifyresult = 0;
|
||||
|
||||
data->set.ssl.certverifyresult=0; /* not checked yet */
|
||||
if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
|
||||
if(rv) {
|
||||
result = rv;
|
||||
@@ -1695,24 +1667,24 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
|
||||
if(SSL_SET_OPTION(CRLfile)) {
|
||||
const CURLcode rv = nss_load_crl(SSL_SET_OPTION(CRLfile));
|
||||
if(data->set.ssl.CRLfile) {
|
||||
const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
|
||||
if(rv) {
|
||||
result = rv;
|
||||
goto error;
|
||||
}
|
||||
infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile));
|
||||
infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile);
|
||||
}
|
||||
|
||||
if(SSL_SET_OPTION(cert)) {
|
||||
char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
char *nickname = dup_nickname(data, STRING_CERT);
|
||||
if(nickname) {
|
||||
/* we are not going to use libnsspem.so to read the client cert */
|
||||
connssl->obj_clicert = NULL;
|
||||
}
|
||||
else {
|
||||
CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
|
||||
SSL_SET_OPTION(key));
|
||||
CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY]);
|
||||
if(rv) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
result = rv;
|
||||
@@ -1732,24 +1704,15 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
|
||||
DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
|
||||
nspr_io = conn->proxy_ssl[sockindex].handle;
|
||||
second_layer = TRUE;
|
||||
}
|
||||
else {
|
||||
/* wrap OS file descriptor by NSPR's file descriptor abstraction */
|
||||
nspr_io = PR_ImportTCPSocket(sockfd);
|
||||
if(!nspr_io)
|
||||
goto error;
|
||||
}
|
||||
/* wrap OS file descriptor by NSPR's file descriptor abstraction */
|
||||
nspr_io = PR_ImportTCPSocket(sockfd);
|
||||
if(!nspr_io)
|
||||
goto error;
|
||||
|
||||
/* create our own NSPR I/O layer */
|
||||
nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
|
||||
if(!nspr_io_stub) {
|
||||
if(!second_layer)
|
||||
PR_Close(nspr_io);
|
||||
PR_Close(nspr_io);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1758,8 +1721,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
|
||||
/* push our new layer to the NSPR I/O stack */
|
||||
if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
|
||||
if(!second_layer)
|
||||
PR_Close(nspr_io);
|
||||
PR_Close(nspr_io);
|
||||
PR_Close(nspr_io_stub);
|
||||
goto error;
|
||||
}
|
||||
@@ -1767,8 +1729,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
/* import our model socket onto the current I/O stack */
|
||||
connssl->handle = SSL_ImportFD(model, nspr_io);
|
||||
if(!connssl->handle) {
|
||||
if(!second_layer)
|
||||
PR_Close(nspr_io);
|
||||
PR_Close(nspr_io);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -1776,12 +1737,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
model = NULL;
|
||||
|
||||
/* This is the password associated with the cert that we're using */
|
||||
if(SSL_SET_OPTION(key_passwd)) {
|
||||
SSL_SetPKCS11PinArg(connssl->handle, SSL_SET_OPTION(key_passwd));
|
||||
if(data->set.str[STRING_KEY_PASSWD]) {
|
||||
SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
|
||||
}
|
||||
|
||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(data->set.ssl.verifystatus) {
|
||||
if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
|
||||
!= SECSuccess)
|
||||
goto error;
|
||||
@@ -1841,14 +1802,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
|
||||
/* propagate hostname to the TLS layer */
|
||||
if(SSL_SetURL(connssl->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name) != SECSuccess)
|
||||
if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
/* prevent NSS from re-using the session for a different hostname */
|
||||
if(SSL_SetSockPeerID(connssl->handle, SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.name : conn->host.name)
|
||||
!= SECSuccess)
|
||||
if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
return CURLE_OK;
|
||||
@@ -1866,8 +1824,6 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
||||
PRUint32 timeout;
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
|
||||
/* check timeout situation */
|
||||
const long time_left = Curl_timeleft(data, NULL, TRUE);
|
||||
@@ -1883,9 +1839,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
|
||||
/* blocking direction is updated by nss_update_connecting_state() */
|
||||
return CURLE_AGAIN;
|
||||
else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
|
||||
else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
|
||||
result = CURLE_PEER_FAILED_VERIFICATION;
|
||||
else if(*certverifyresult != 0)
|
||||
else if(conn->data->set.ssl.certverifyresult!=0)
|
||||
result = CURLE_SSL_CACERT;
|
||||
goto error;
|
||||
}
|
||||
@@ -1894,11 +1850,11 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||
if(result)
|
||||
goto error;
|
||||
|
||||
if(data->set.ssl.issuercert) {
|
||||
if(data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||
SECStatus ret = SECFailure;
|
||||
char *nickname = dup_nickname(data, data->set.ssl.issuercert);
|
||||
char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT);
|
||||
if(nickname) {
|
||||
/* we support only nicknames in case of issuercert for now */
|
||||
/* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
free(nickname);
|
||||
}
|
||||
|
@@ -189,13 +189,13 @@ static int ossl_seed(struct SessionHandle *data)
|
||||
#ifndef RANDOM_FILE
|
||||
/* if RANDOM_FILE isn't defined, we only perform this if an option tells
|
||||
us to! */
|
||||
if(data->set.ssl.primary.random_file)
|
||||
if(data->set.ssl.random_file)
|
||||
#define RANDOM_FILE "" /* doesn't matter won't be used */
|
||||
#endif
|
||||
{
|
||||
/* let the option override the define */
|
||||
nread += RAND_load_file((data->set.ssl.primary.random_file?
|
||||
data->set.ssl.primary.random_file:
|
||||
nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
|
||||
data->set.str[STRING_SSL_RANDOM_FILE]:
|
||||
RANDOM_FILE),
|
||||
RAND_LOAD_LENGTH);
|
||||
if(seed_enough(nread))
|
||||
@@ -208,14 +208,14 @@ static int ossl_seed(struct SessionHandle *data)
|
||||
#ifndef EGD_SOCKET
|
||||
/* If we don't have the define set, we only do this if the egd-option
|
||||
is set */
|
||||
if(data->set.ssl.primary.egdsocket)
|
||||
if(data->set.str[STRING_SSL_EGDSOCKET])
|
||||
#define EGD_SOCKET "" /* doesn't matter won't be used */
|
||||
#endif
|
||||
{
|
||||
/* If there's an option and a define, the option overrides the
|
||||
define */
|
||||
int ret = RAND_egd(data->set.ssl.primary.egdsocket?
|
||||
data->set.ssl.primary.egdsocket:EGD_SOCKET);
|
||||
int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
|
||||
data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
|
||||
if(-1 != ret) {
|
||||
nread += ret;
|
||||
if(seed_enough(nread))
|
||||
@@ -253,8 +253,8 @@ static void Curl_ossl_seed(struct SessionHandle *data)
|
||||
time-consuming seedings in vain */
|
||||
static bool ssl_seeded = FALSE;
|
||||
|
||||
if(!ssl_seeded || data->set.ssl.primary.random_file ||
|
||||
data->set.ssl.primary.egdsocket) {
|
||||
if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
|
||||
data->set.str[STRING_SSL_EGDSOCKET]) {
|
||||
ossl_seed(data);
|
||||
ssl_seeded = TRUE;
|
||||
}
|
||||
@@ -334,8 +334,7 @@ int cert_stuff(struct connectdata *conn,
|
||||
char *cert_file,
|
||||
const char *cert_type,
|
||||
char *key_file,
|
||||
const char *key_type,
|
||||
char *key_passwd)
|
||||
const char *key_type)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
@@ -346,9 +345,10 @@ int cert_stuff(struct connectdata *conn,
|
||||
X509 *x509;
|
||||
int cert_done = 0;
|
||||
|
||||
if(key_passwd) {
|
||||
if(data->set.str[STRING_KEY_PASSWD]) {
|
||||
/* set the password in the callback userdata */
|
||||
SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd);
|
||||
SSL_CTX_set_default_passwd_cb_userdata(ctx,
|
||||
data->set.str[STRING_KEY_PASSWD]);
|
||||
/* Set passwd callback: */
|
||||
SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
|
||||
}
|
||||
@@ -457,7 +457,7 @@ int cert_stuff(struct connectdata *conn,
|
||||
|
||||
PKCS12_PBE_add();
|
||||
|
||||
if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
|
||||
if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509,
|
||||
&ca)) {
|
||||
failf(data,
|
||||
"could not parse PKCS12 file, check password, OpenSSL error %s",
|
||||
@@ -570,7 +570,7 @@ int cert_stuff(struct connectdata *conn,
|
||||
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
ui_method,
|
||||
#endif
|
||||
key_passwd);
|
||||
data->set.str[STRING_KEY_PASSWD]);
|
||||
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
|
||||
UI_destroy_method(ui_method);
|
||||
#endif
|
||||
@@ -864,8 +864,13 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
|
||||
}
|
||||
|
||||
|
||||
static void ossl_close(struct ssl_connect_data *connssl)
|
||||
/*
|
||||
* This function is called when an SSL connection is closed.
|
||||
*/
|
||||
void Curl_ossl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
if(connssl->handle) {
|
||||
(void)SSL_shutdown(connssl->handle);
|
||||
SSL_set_connect_state(connssl->handle);
|
||||
@@ -879,15 +884,6 @@ static void ossl_close(struct ssl_connect_data *connssl)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called when an SSL connection is closed.
|
||||
*/
|
||||
void Curl_ossl_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
ossl_close(&conn->ssl[sockindex]);
|
||||
ossl_close(&conn->proxy_ssl[sockindex]);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called to shut down the SSL layer but keep the
|
||||
* socket open (CCC - Clear Command Channel)
|
||||
@@ -1050,20 +1046,16 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
|
||||
struct in_addr addr;
|
||||
#endif
|
||||
CURLcode result = CURLE_OK;
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const char * const dispname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.dispname : conn->host.dispname;
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
if(conn->bits.ipv6_ip &&
|
||||
Curl_inet_pton(AF_INET6, hostname, &addr)) {
|
||||
Curl_inet_pton(AF_INET6, conn->host.name, &addr)) {
|
||||
target = GEN_IPADD;
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(Curl_inet_pton(AF_INET, hostname, &addr)) {
|
||||
if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) {
|
||||
target = GEN_IPADD;
|
||||
addrlen = sizeof(struct in_addr);
|
||||
}
|
||||
@@ -1105,7 +1097,7 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
|
||||
if((altlen == strlen(altptr)) &&
|
||||
/* if this isn't true, there was an embedded zero in the name
|
||||
string and we cannot match it. */
|
||||
Curl_cert_hostcheck(altptr, hostname))
|
||||
Curl_cert_hostcheck(altptr, conn->host.name))
|
||||
matched = 1;
|
||||
else
|
||||
matched = 0;
|
||||
@@ -1127,13 +1119,13 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
|
||||
|
||||
if(matched == 1)
|
||||
/* an alternative name matched the server hostname */
|
||||
infof(data, "\t subjectAltName: %s matched\n", dispname);
|
||||
infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
|
||||
else if(matched == 0) {
|
||||
/* an alternative name field existed, but didn't match and then
|
||||
we MUST fail */
|
||||
infof(data, "\t subjectAltName does not match %s\n", dispname);
|
||||
infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname);
|
||||
failf(data, "SSL: no alternative certificate subject name matches "
|
||||
"target host name '%s'", dispname);
|
||||
"target host name '%s'", conn->host.dispname);
|
||||
result = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
@@ -1207,9 +1199,9 @@ static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
|
||||
"SSL: unable to obtain common name from peer certificate");
|
||||
result = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
|
||||
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, dispname);
|
||||
"target host name '%s'", peer_CN, conn->host.dispname);
|
||||
result = CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
else {
|
||||
@@ -1646,30 +1638,17 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
struct in_addr addr;
|
||||
#endif
|
||||
#endif
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
const long int ssl_version = SSL_CONN_CONFIG(version);
|
||||
#ifdef USE_TLS_SRP
|
||||
const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
|
||||
#endif
|
||||
char * const ssl_cert = SSL_SET_OPTION(cert);
|
||||
const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
|
||||
const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
|
||||
const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
|
||||
const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
|
||||
const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
|
||||
DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
|
||||
|
||||
/* Make funny stuff to get random input */
|
||||
Curl_ossl_seed(data);
|
||||
|
||||
*certverifyresult = !X509_V_OK;
|
||||
data->set.ssl.certverifyresult = !X509_V_OK;
|
||||
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(ssl_version) {
|
||||
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -1677,8 +1656,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
case CURL_SSLVERSION_TLSv1_1:
|
||||
case CURL_SSLVERSION_TLSv1_2:
|
||||
/* it will be handled later with the context options */
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
|
||||
req_method = TLS_client_method();
|
||||
#else
|
||||
req_method = SSLv23_client_method();
|
||||
@@ -1691,7 +1670,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#else
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl_authtype == CURL_TLSAUTH_SRP)
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
#endif
|
||||
req_method = SSLv2_client_method();
|
||||
@@ -1704,7 +1683,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#else
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl_authtype == CURL_TLSAUTH_SRP)
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP)
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
#endif
|
||||
req_method = SSLv3_client_method();
|
||||
@@ -1789,14 +1768,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
/* unless the user explicitly ask to allow the protocol vulnerability we
|
||||
use the work-around */
|
||||
if(!SSL_SET_OPTION(enable_beast))
|
||||
if(!conn->data->set.ssl_enable_beast)
|
||||
ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
#endif
|
||||
|
||||
switch(ssl_version) {
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl_authtype == CURL_TLSAUTH_SRP) {
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
infof(data, "Set version TLSv1.x for SRP authorisation\n");
|
||||
}
|
||||
#endif
|
||||
@@ -1890,16 +1869,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ssl_cert || ssl_cert_type) {
|
||||
if(!cert_stuff(conn, connssl->ctx, ssl_cert, ssl_cert_type,
|
||||
SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
|
||||
SSL_SET_OPTION(key_passwd))) {
|
||||
if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
|
||||
if(!cert_stuff(conn,
|
||||
connssl->ctx,
|
||||
data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_CERT_TYPE],
|
||||
data->set.str[STRING_KEY],
|
||||
data->set.str[STRING_KEY_TYPE])) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
}
|
||||
|
||||
ciphers = SSL_CONN_CONFIG(cipher_list);
|
||||
ciphers = data->set.str[STRING_SSL_CIPHER_LIST];
|
||||
if(!ciphers)
|
||||
ciphers = (char *)DEFAULT_CIPHER_SELECTION;
|
||||
if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) {
|
||||
@@ -1909,20 +1891,18 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof(data, "Cipher selection: %s\n", ciphers);
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(ssl_authtype == CURL_TLSAUTH_SRP) {
|
||||
char * const ssl_username = SSL_SET_OPTION(username);
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
|
||||
|
||||
infof(data, "Using TLS-SRP username: %s\n", ssl_username);
|
||||
|
||||
if(!SSL_CTX_set_srp_username(connssl->ctx, ssl_username)) {
|
||||
if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) {
|
||||
failf(data, "Unable to set SRP user name");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
if(!SSL_CTX_set_srp_password(connssl->ctx, SSL_SET_OPTION(password))) {
|
||||
if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) {
|
||||
failf(data, "failed setting SRP password");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
if(!SSL_CONN_CONFIG(cipher_list)) {
|
||||
if(!data->set.str[STRING_SSL_CIPHER_LIST]) {
|
||||
infof(data, "Setting cipher list SRP\n");
|
||||
|
||||
if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) {
|
||||
@@ -1932,17 +1912,20 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ssl_cafile || ssl_capath) {
|
||||
if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) {
|
||||
/* tell SSL where to find CA certificates that are used to verify
|
||||
the servers certificate. */
|
||||
if(!SSL_CTX_load_verify_locations(connssl->ctx, ssl_cafile, ssl_capath)) {
|
||||
if(verifypeer) {
|
||||
if(!SSL_CTX_load_verify_locations(connssl->ctx,
|
||||
data->set.str[STRING_SSL_CAFILE],
|
||||
data->set.str[STRING_SSL_CAPATH])) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* Fail if we insist on successfully verifying the server. */
|
||||
failf(data, "error setting certificate verify locations:\n"
|
||||
" CAfile: %s\n CApath: %s",
|
||||
ssl_cafile ? ssl_cafile : "none",
|
||||
ssl_capath ? ssl_capath : "none");
|
||||
data->set.str[STRING_SSL_CAFILE]?
|
||||
data->set.str[STRING_SSL_CAFILE]: "none",
|
||||
data->set.str[STRING_SSL_CAPATH]?
|
||||
data->set.str[STRING_SSL_CAPATH] : "none");
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
else {
|
||||
@@ -1959,18 +1942,22 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof(data,
|
||||
" CAfile: %s\n"
|
||||
" CApath: %s\n",
|
||||
ssl_cafile ? ssl_cafile : "none",
|
||||
ssl_capath ? ssl_capath : "none");
|
||||
data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]:
|
||||
"none",
|
||||
data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]:
|
||||
"none");
|
||||
}
|
||||
|
||||
if(ssl_crlfile) {
|
||||
if(data->set.str[STRING_SSL_CRLFILE]) {
|
||||
/* tell SSL where to find CRL file that is used to check certificate
|
||||
* revocation */
|
||||
lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx),
|
||||
X509_LOOKUP_file());
|
||||
if(!lookup ||
|
||||
(!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
|
||||
failf(data, "error loading CRL file: %s", ssl_crlfile);
|
||||
(!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE],
|
||||
X509_FILETYPE_PEM)) ) {
|
||||
failf(data, "error loading CRL file: %s",
|
||||
data->set.str[STRING_SSL_CRLFILE]);
|
||||
return CURLE_SSL_CRL_BADFILE;
|
||||
}
|
||||
else {
|
||||
@@ -1979,7 +1966,9 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx),
|
||||
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
|
||||
}
|
||||
infof(data, " CRLfile: %s\n", ssl_crlfile ? ssl_crlfile: "none");
|
||||
infof(data,
|
||||
" CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ?
|
||||
data->set.str[STRING_SSL_CRLFILE]: "none");
|
||||
}
|
||||
|
||||
/* Try building a chain using issuers in the trusted store first to avoid
|
||||
@@ -2001,7 +1990,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
* anyway. In the latter case the result of the verification is checked with
|
||||
* SSL_get_verify_result() below. */
|
||||
SSL_CTX_set_verify(connssl->ctx,
|
||||
verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
|
||||
data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
|
||||
NULL);
|
||||
|
||||
/* give application a chance to interfere with SSL set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
@@ -2024,26 +2014,27 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
|
||||
!defined(OPENSSL_IS_BORINGSSL)
|
||||
if(SSL_CONN_CONFIG(verifystatus))
|
||||
if(data->set.ssl.verifystatus)
|
||||
SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp);
|
||||
#endif
|
||||
|
||||
SSL_set_connect_state(connssl->handle);
|
||||
|
||||
connssl->server_cert = 0x0;
|
||||
|
||||
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
|
||||
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
|
||||
if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
(0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
|
||||
(0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
|
||||
#endif
|
||||
sni &&
|
||||
!SSL_set_tlsext_host_name(connssl->handle, hostname))
|
||||
!SSL_set_tlsext_host_name(connssl->handle, conn->host.name))
|
||||
infof(data, "WARNING: failed to configure server name indication (SNI) "
|
||||
"TLS extension\n");
|
||||
#endif
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
|
||||
/* we got a session id, use it! */
|
||||
if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
|
||||
failf(data, "SSL: SSL_set_session failed: %s",
|
||||
@@ -2054,16 +2045,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof (data, "SSL re-using session ID\n");
|
||||
}
|
||||
|
||||
if(conn->proxy_ssl[sockindex].use) {
|
||||
BIO *const bio = BIO_new(BIO_f_ssl());
|
||||
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
|
||||
DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
|
||||
DEBUGASSERT(bio != NULL);
|
||||
BIO_set_ssl(bio, conn->proxy_ssl[sockindex].handle, FALSE);
|
||||
SSL_set_bio(connssl->handle, bio, bio);
|
||||
}
|
||||
else if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
|
||||
/* pass the raw socket into the SSL layers */
|
||||
/* pass the raw socket into the SSL layers */
|
||||
if(!SSL_set_fd(connssl->handle, (int)sockfd)) {
|
||||
failf(data, "SSL: SSL_set_fd failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -2080,8 +2063,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
int err;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|
||||
|| ssl_connect_2_reading == connssl->connecting_state
|
||||
|| ssl_connect_2_writing == connssl->connecting_state);
|
||||
|| ssl_connect_2_reading == connssl->connecting_state
|
||||
|| ssl_connect_2_writing == connssl->connecting_state);
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
@@ -2156,11 +2139,8 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
* the SO_ERROR is also lost.
|
||||
*/
|
||||
if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
|
||||
const char * const hostname = SSL_IS_PROXY() ?
|
||||
conn->http_proxy.host.name : conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
failf(data, "Unknown SSL protocol error in connection to %s:%ld ",
|
||||
hostname, port);
|
||||
conn->host.name, conn->remote_port);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2405,6 +2385,11 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
print_pubkey_BN(dh, priv_key, i);
|
||||
print_pubkey_BN(dh, pub_key, i);
|
||||
break;
|
||||
#if 0
|
||||
case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
|
||||
/* left TODO */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
EVP_PKEY_free(pubkey);
|
||||
}
|
||||
@@ -2504,8 +2489,6 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
FILE *fp;
|
||||
char *buffer = data->state.buffer;
|
||||
const char *ptr;
|
||||
long * const certverifyresult = SSL_IS_PROXY() ?
|
||||
&data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
|
||||
BIO *mem = BIO_new(BIO_s_mem());
|
||||
|
||||
if(data->set.ssl.certinfo)
|
||||
@@ -2521,7 +2504,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
}
|
||||
|
||||
infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
|
||||
infof(data, "Server certificate:\n");
|
||||
|
||||
rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert),
|
||||
buffer, BUFSIZE);
|
||||
@@ -2539,7 +2522,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
|
||||
BIO_free(mem);
|
||||
|
||||
if(SSL_CONN_CONFIG(verifyhost)) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
result = verifyhost(conn, connssl->server_cert);
|
||||
if(result) {
|
||||
X509_free(connssl->server_cert);
|
||||
@@ -2562,12 +2545,12 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
deallocating the certificate. */
|
||||
|
||||
/* e.g. match issuer name with provided issuer certificate */
|
||||
if(data->set.ssl.issuercert) {
|
||||
fp = fopen(data->set.ssl.issuercert, FOPEN_READTEXT);
|
||||
if(data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||
fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT);
|
||||
if(!fp) {
|
||||
if(strict)
|
||||
failf(data, "SSL: Unable to open issuer cert (%s)",
|
||||
data->set.ssl.issuercert);
|
||||
data->set.str[STRING_SSL_ISSUERCERT]);
|
||||
X509_free(connssl->server_cert);
|
||||
connssl->server_cert = NULL;
|
||||
return CURLE_SSL_ISSUER_ERROR;
|
||||
@@ -2577,7 +2560,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
if(!issuer) {
|
||||
if(strict)
|
||||
failf(data, "SSL: Unable to read issuer cert (%s)",
|
||||
data->set.ssl.issuercert);
|
||||
data->set.str[STRING_SSL_ISSUERCERT]);
|
||||
X509_free(connssl->server_cert);
|
||||
X509_free(issuer);
|
||||
fclose(fp);
|
||||
@@ -2589,7 +2572,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) {
|
||||
if(strict)
|
||||
failf(data, "SSL: Certificate issuer check failed (%s)",
|
||||
data->set.ssl.issuercert);
|
||||
data->set.str[STRING_SSL_ISSUERCERT]);
|
||||
X509_free(connssl->server_cert);
|
||||
X509_free(issuer);
|
||||
connssl->server_cert = NULL;
|
||||
@@ -2597,14 +2580,15 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
}
|
||||
|
||||
infof(data, "\t SSL certificate issuer check ok (%s)\n",
|
||||
data->set.ssl.issuercert);
|
||||
data->set.str[STRING_SSL_ISSUERCERT]);
|
||||
X509_free(issuer);
|
||||
}
|
||||
|
||||
lerr = *certverifyresult = SSL_get_verify_result(connssl->handle);
|
||||
lerr = data->set.ssl.certverifyresult =
|
||||
SSL_get_verify_result(connssl->handle);
|
||||
|
||||
if(*certverifyresult != X509_V_OK) {
|
||||
if(SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(data->set.ssl.certverifyresult != X509_V_OK) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
/* We probably never reach this, because SSL_connect() will fail
|
||||
and we return earlier if verifypeer is set? */
|
||||
if(strict)
|
||||
@@ -2623,7 +2607,7 @@ static CURLcode servercert(struct connectdata *conn,
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
|
||||
!defined(OPENSSL_IS_BORINGSSL)
|
||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||
if(data->set.ssl.verifystatus) {
|
||||
result = verifystatus(conn, connssl);
|
||||
if(result) {
|
||||
X509_free(connssl->server_cert);
|
||||
@@ -2668,8 +2652,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
will stay in memory until explicitly freed with SSL_SESSION_free(3),
|
||||
regardless of its state. */
|
||||
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
@@ -2680,7 +2663,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(!incache) {
|
||||
result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
|
||||
0 /* unknown size */, sockindex);
|
||||
0 /* unknown size */);
|
||||
if(result) {
|
||||
failf(data, "failed to store ssl session");
|
||||
return result;
|
||||
@@ -2701,8 +2684,8 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
* operations.
|
||||
*/
|
||||
|
||||
result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) ||
|
||||
SSL_CONN_CONFIG(verifyhost)));
|
||||
result = servercert(conn, connssl,
|
||||
(data->set.ssl.verifypeer || data->set.ssl.verifyhost));
|
||||
|
||||
if(!result)
|
||||
connssl->connecting_state = ssl_connect_done;
|
||||
@@ -2849,10 +2832,7 @@ bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex)
|
||||
{
|
||||
if(conn->ssl[connindex].handle)
|
||||
/* SSL is in use */
|
||||
return (0 != SSL_pending(conn->ssl[connindex].handle) ||
|
||||
(conn->proxy_ssl[connindex].handle &&
|
||||
0 != SSL_pending(conn->proxy_ssl[connindex].handle))) ?
|
||||
TRUE : FALSE;
|
||||
return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2897,18 +2877,8 @@ static ssize_t ossl_send(struct connectdata *conn,
|
||||
/* A failure in the SSL library occurred, usually a protocol error.
|
||||
The OpenSSL error queue contains more information on the error. */
|
||||
sslerror = ERR_get_error();
|
||||
if(sslerror ==
|
||||
ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET) &&
|
||||
conn->ssl[sockindex].state == ssl_connection_complete &&
|
||||
conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
|
||||
char ver[120];
|
||||
Curl_ossl_version(ver, 120);
|
||||
failf(conn->data, "Error: %s does not support double SSL tunneling.",
|
||||
ver);
|
||||
}
|
||||
else
|
||||
failf(conn->data, "SSL_write() error: %s",
|
||||
ERR_error_string(sslerror, error_buffer));
|
||||
failf(conn->data, "SSL_write() error: %s",
|
||||
ERR_error_string(sslerror, error_buffer));
|
||||
*curlcode = CURLE_SEND_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
@@ -132,10 +132,6 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
|
||||
const char *capath = SSL_CONN_CONFIG(CApath);
|
||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||
conn->host.name;
|
||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||
|
||||
bool sni = TRUE; /* default is SNI enabled */
|
||||
int ret = -1;
|
||||
@@ -150,11 +146,11 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
errorbuf[0]=0;
|
||||
|
||||
/* PolarSSL only supports SSLv3 and TLSv1 */
|
||||
if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
|
||||
if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
|
||||
failf(data, "PolarSSL does not support SSLv2");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
|
||||
else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
|
||||
sni = FALSE; /* SSLv3 has no SNI */
|
||||
|
||||
#ifdef THREADING_SUPPORT
|
||||
@@ -184,33 +180,34 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
/* Load the trusted CA */
|
||||
memset(&connssl->cacert, 0, sizeof(x509_crt));
|
||||
|
||||
if(SSL_CONN_CONFIG(CAfile)) {
|
||||
if(data->set.str[STRING_SSL_CAFILE]) {
|
||||
ret = x509_crt_parse_file(&connssl->cacert,
|
||||
SSL_CONN_CONFIG(CAfile));
|
||||
data->set.str[STRING_SSL_CAFILE]);
|
||||
|
||||
if(ret<0) {
|
||||
#ifdef POLARSSL_ERROR_C
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
|
||||
SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
|
||||
data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
|
||||
|
||||
if(SSL_CONN_CONFIG(verifypeer))
|
||||
if(data->set.ssl.verifypeer)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
}
|
||||
|
||||
if(capath) {
|
||||
ret = x509_crt_parse_path(&connssl->cacert, capath);
|
||||
if(data->set.str[STRING_SSL_CAPATH]) {
|
||||
ret = x509_crt_parse_path(&connssl->cacert,
|
||||
data->set.str[STRING_SSL_CAPATH]);
|
||||
|
||||
if(ret<0) {
|
||||
#ifdef POLARSSL_ERROR_C
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
|
||||
capath, -ret, errorbuf);
|
||||
data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
|
||||
|
||||
if(SSL_CONN_CONFIG(verifypeer))
|
||||
if(data->set.ssl.verifypeer)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
}
|
||||
@@ -218,27 +215,27 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
/* Load the client certificate */
|
||||
memset(&connssl->clicert, 0, sizeof(x509_crt));
|
||||
|
||||
if(SSL_SET_OPTION(cert)) {
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
ret = x509_crt_parse_file(&connssl->clicert,
|
||||
SSL_SET_OPTION(cert));
|
||||
data->set.str[STRING_CERT]);
|
||||
|
||||
if(ret) {
|
||||
#ifdef POLARSSL_ERROR_C
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
|
||||
SSL_SET_OPTION(cert), -ret, errorbuf);
|
||||
data->set.str[STRING_CERT], -ret, errorbuf);
|
||||
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the client private key */
|
||||
if(SSL_SET_OPTION(key)) {
|
||||
if(data->set.str[STRING_KEY]) {
|
||||
pk_context pk;
|
||||
pk_init(&pk);
|
||||
ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
|
||||
SSL_SET_OPTION(key_passwd));
|
||||
ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
|
||||
data->set.str[STRING_KEY_PASSWD]);
|
||||
if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
|
||||
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
|
||||
if(ret == 0)
|
||||
@@ -252,7 +249,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
|
||||
SSL_SET_OPTION(key), -ret, errorbuf);
|
||||
data->set.str[STRING_KEY], -ret, errorbuf);
|
||||
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
@@ -261,29 +258,30 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
/* Load the CRL */
|
||||
memset(&connssl->crl, 0, sizeof(x509_crl));
|
||||
|
||||
if(SSL_SET_OPTION(CRLfile)) {
|
||||
if(data->set.str[STRING_SSL_CRLFILE]) {
|
||||
ret = x509_crl_parse_file(&connssl->crl,
|
||||
SSL_SET_OPTION(CRLfile));
|
||||
data->set.str[STRING_SSL_CRLFILE]);
|
||||
|
||||
if(ret) {
|
||||
#ifdef POLARSSL_ERROR_C
|
||||
error_strerror(ret, errorbuf, sizeof(errorbuf));
|
||||
#endif /* POLARSSL_ERROR_C */
|
||||
failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
|
||||
SSL_SET_OPTION(CRLfile), -ret, errorbuf);
|
||||
data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
|
||||
|
||||
return CURLE_SSL_CRL_BADFILE;
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
|
||||
infof(data, "PolarSSL: Connecting to %s:%d\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
|
||||
if(ssl_init(&connssl->ssl)) {
|
||||
failf(data, "PolarSSL: ssl_init failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
switch(SSL_CONN_CONFIG(version)) {
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -330,8 +328,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
net_send, &conn->sock[sockindex]);
|
||||
|
||||
ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
|
||||
if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size,
|
||||
sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
|
||||
memcpy(&connssl->ssn, old_session, old_session_size);
|
||||
infof(data, "PolarSSL re-using session\n");
|
||||
}
|
||||
@@ -342,16 +339,16 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
ssl_set_ca_chain(&connssl->ssl,
|
||||
&connssl->cacert,
|
||||
&connssl->crl,
|
||||
hostname);
|
||||
conn->host.name);
|
||||
|
||||
ssl_set_own_cert_rsa(&connssl->ssl,
|
||||
&connssl->clicert, &connssl->rsa);
|
||||
|
||||
if(!Curl_inet_pton(AF_INET, hostname, &addr) &&
|
||||
if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
|
||||
#ifdef ENABLE_IPV6
|
||||
!Curl_inet_pton(AF_INET6, hostname, &addr) &&
|
||||
!Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
|
||||
#endif
|
||||
sni && ssl_set_hostname(&connssl->ssl, hostname)) {
|
||||
sni && ssl_set_hostname(&connssl->ssl, conn->host.name)) {
|
||||
infof(data, "WARNING: failed to configure "
|
||||
"server name indication (SNI) TLS extension\n");
|
||||
}
|
||||
@@ -429,7 +426,7 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
|
||||
ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
|
||||
|
||||
if(ret && SSL_CONN_CONFIG(verifypeer)) {
|
||||
if(ret && data->set.ssl.verifypeer) {
|
||||
if(ret & BADCERT_EXPIRED)
|
||||
failf(data, "Cert verify failed: BADCERT_EXPIRED");
|
||||
|
||||
@@ -499,8 +496,7 @@ polarssl_connect_step3(struct connectdata *conn,
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
/* Save the current session data for possible re-use */
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
|
||||
sockindex));
|
||||
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
|
||||
if(incache) {
|
||||
if(old_ssl_sessionid != our_ssl_sessionid) {
|
||||
infof(data, "old SSL session ID is stale, removing\n");
|
||||
@@ -515,8 +511,7 @@ polarssl_connect_step3(struct connectdata *conn,
|
||||
if(new_session) {
|
||||
memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session));
|
||||
|
||||
result = Curl_ssl_addsessionid(conn, new_session,
|
||||
sizeof(ssl_session), sockindex);
|
||||
result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session));
|
||||
}
|
||||
else
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
@@ -111,7 +111,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
conn->host.name, conn->remote_port);
|
||||
|
||||
/* check for an existing re-usable credential handle */
|
||||
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
|
||||
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) {
|
||||
connssl->cred = old_cred;
|
||||
infof(data, "schannel: re-using existing credential handle\n");
|
||||
}
|
||||
@@ -120,7 +120,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
memset(&schannel_cred, 0, sizeof(schannel_cred));
|
||||
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
|
||||
|
||||
if(conn->ssl_config.verifypeer) {
|
||||
if(data->set.ssl.verifypeer) {
|
||||
#ifdef _WIN32_WCE
|
||||
/* certificate validation on CE doesn't seem to work right; we'll
|
||||
do it following a more manual process. */
|
||||
@@ -148,14 +148,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
infof(data, "schannel: disabled server certificate revocation checks\n");
|
||||
}
|
||||
|
||||
if(!conn->ssl_config.verifyhost) {
|
||||
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(conn->ssl_config.version) {
|
||||
switch(data->set.ssl.version) {
|
||||
default:
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
@@ -520,7 +520,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
|
||||
#ifdef _WIN32_WCE
|
||||
/* Windows CE doesn't do any server certificate validation.
|
||||
We have to do it manually. */
|
||||
if(conn->ssl_config.verifypeer)
|
||||
if(data->set.ssl.verifypeer)
|
||||
return verify_certificate(conn, sockindex);
|
||||
#endif
|
||||
|
||||
@@ -567,8 +567,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
/* save the current session data for possible re-use */
|
||||
incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
|
||||
sockindex));
|
||||
incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL));
|
||||
if(incache) {
|
||||
if(old_cred != connssl->cred) {
|
||||
infof(data, "schannel: old credential handle is stale, removing\n");
|
||||
@@ -579,8 +578,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
|
||||
if(!incache) {
|
||||
result = Curl_ssl_addsessionid(conn, (void *)connssl->cred,
|
||||
sizeof(struct curl_schannel_cred),
|
||||
sockindex);
|
||||
sizeof(struct curl_schannel_cred));
|
||||
if(result) {
|
||||
failf(data, "schannel: failed to store credential handle");
|
||||
return result;
|
||||
@@ -1122,7 +1120,22 @@ cleanup:
|
||||
*/
|
||||
if(len && !connssl->decdata_offset && connssl->recv_connection_closed &&
|
||||
!connssl->recv_sspi_close_notify) {
|
||||
BOOL isWin2k;
|
||||
bool isWin2k = FALSE;
|
||||
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_WIN2K)
|
||||
OSVERSIONINFO osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
|
||||
/* Find out the Windows version */
|
||||
if(GetVersionEx(&osver)) {
|
||||
/* Verify the version number is 5.0 */
|
||||
if(osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0)
|
||||
isWin2k = TRUE;
|
||||
}
|
||||
#else
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
@@ -1135,10 +1148,11 @@ cleanup:
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
isWin2k = VerifyVersionInfo(&osver,
|
||||
(VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm);
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
isWin2k = TRUE;
|
||||
#endif
|
||||
|
||||
if(isWin2k && sspi_status == SEC_E_OK)
|
||||
connssl->recv_sspi_close_notify = true;
|
||||
@@ -1443,7 +1457,7 @@ static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
if(result == CURLE_OK) {
|
||||
if(conn->ssl_config.verifyhost) {
|
||||
if(data->set.ssl.verifyhost) {
|
||||
TCHAR cert_hostname_buff[128];
|
||||
xcharp_u hostname;
|
||||
xcharp_u cert_hostname;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user