Compare commits

..

38 Commits

Author SHA1 Message Date
Daniel Stenberg
e2ae32ff5f RELEASE-NOTES: updated contributor count for 7.46.0 2015-12-01 23:10:16 +01:00
Daniel Stenberg
6623a485d3 THANKS: new contributors from the 7.46.0 release 2015-12-01 22:53:24 +01:00
Daniel Stenberg
940c2f51aa THANKS-filter: single Tim Rühsen spelling 2015-12-01 22:51:50 +01:00
Daniel Stenberg
a47137c4a5 docs/examples: gitignore some more built examples 2015-12-01 09:09:04 +01:00
Daniel Stenberg
5648f0a32c RELEASE-NOTES; this bug was never released 2015-11-30 08:22:32 +01:00
Daniel Stenberg
2fddc4e3e1 RELEASE-NOTES: synced with e55f15454e 2015-11-30 08:03:28 +01:00
Flavio Medeiros
e55f15454e Curl_read_plain: clean up ifdefs that break statements
Closes #546
2015-11-30 00:28:28 +01:00
Daniel Stenberg
fe7c39d353 http2: convert some verbose output into debug-only output 2015-11-30 00:12:46 +01:00
Daniel Stenberg
8f281fb76d http2 push: add missing inits of new stream
- set the correct stream_id for pushed streams
- init maxdownload and size properly
2015-11-30 00:11:42 +01:00
Daniel Stenberg
8cbd80686e http2 push: set weight for new stream
give the new stream the old one's stream_weight internally to avoid
sending a PRIORITY frame unless asked for it
2015-11-30 00:10:35 +01:00
Daniel Stenberg
a14fa8f8ff curl_setup.h: undef freeaddrinfo in c-ares block to fix build
Fixes warnings 78c25c854a added.
2015-11-28 17:26:38 +01:00
Daniel Stenberg
81ae6d01fa nonblock: fix setting non-blocking mode for Amiga
IoctlSocket() apparently wants a pointer to a long, passed as a char *
in its third parameter. This bug was introduced already back in commit
c5fdeef41d from October 1 2001!

Bug: http://curl.haxx.se/mail/lib-2015-11/0088.html
Reported-by: Norbert Kett
2015-11-27 23:29:30 +01:00
Daniel Stenberg
19a8afb3c0 zsh install: fix DESTDIR support
Reported-by: Mohammad AlSaleh
2015-11-27 23:24:07 +01:00
Dan Fandrich
78c25c854a lib: Only define curl_dofreeaddrinfo if struct addrinfo is available 2015-11-27 10:51:22 +01:00
Steve Holme
db05d7a731 tool_paramhlp: Fixed display of URL index in password prompt for --next
Commit f3bae6ed73 added the URL index to the password prompt when using
--next. Unfortunately, because the size_t specifier (%zu) is not
supported by all sprintf() implementations we use the curl_off_t format
specifier instead. The display of an incorrect value arises on platforms
where size_t and curl_off_t are of a different size.
2015-11-27 06:59:02 +00:00
Daniel Stenberg
cd2b73b3ed timecond: do not add if-modified-since without timecondition
The RTSP code path didn't skip adding the if-modified-since for certain
RTSP code paths, even if CURLOPT_TIMECONDITION was set to
CURL_TIMECOND_NONE.

Also, an unknown non-zero CURLOPT_TIMECONDITION value no longer equals
CURL_TIMECOND_IFMODSINCE.

Bug: http://stackoverflow.com/questions/33903982/curl-timecond-none-doesnt-work-how-to-remove-if-modified-since-header
2015-11-25 11:38:10 +01:00
Daniel Stenberg
5b96b5e79e RELEASE-NOTES: synced with 99d17a5e2b 2015-11-25 11:29:00 +01:00
Daniel Stenberg
99d17a5e2b examples/README: cut out the incomplete list
... and add a generic explanation for them instead. Each example file
should contain its own description these days.
2015-11-25 10:49:22 +01:00
Daniel Stenberg
facf2925c7 test1513: make sure the callback is only called once 2015-11-24 23:33:37 +01:00
Daniel Shahaf
be0d4141af build: Install zsh completion
Fixes #534
Closes #537
2015-11-24 22:22:01 +01:00
Daniel Stenberg
40c349ada9 done: make sure the final progress update is made
It would previously be skipped if an existing error was returned, but
would lead to a previous value being left there and later used.
CURLINFO_TOTAL_TIME for example.

Still it avoids that final progress update if we reached DONE as the
result of a callback abort to avoid another callback to be called after
an abort-by-callback.

Reported-by: Lukas Ruzicka

Closes #538
2015-11-24 20:49:04 +01:00
Daniel Stenberg
bb9ec5ebb2 curl: expanded the -XHEAD warning text
... to also mention the specific options used.
2015-11-24 10:11:06 +01:00
Daniel Stenberg
c341311a0e Revert "cleanup: general removal of TODO (and similar) comments"
This reverts commit 64e959ffe3.

Feedback-by: Dan Fandrich
URL: http://curl.haxx.se/mail/lib-2015-11/0062.html
2015-11-24 09:36:45 +01:00
Daniel Stenberg
fc5d783589 CURLOPT_HEADERFUNCTION.3: fix typo
Refer to _HEADERDATA not _WRITEDATA.

Reported-by: Michał Piechowski
2015-11-23 16:11:57 +01:00
Daniel Stenberg
98acebb526 TODO: TCP Fast Open 2015-11-23 10:58:12 +01:00
Steve Holme
06b288a72d examples: Added website parse-able descriptions to the e-mail examples 2015-11-22 11:55:10 +00:00
Steve Holme
d55f9071fb TODO: Added another 'multi-interface' idea 2015-11-21 17:59:14 +00:00
Steve Holme
b7f3f1b68f smb.c: Fixed compilation warnings
smb.c:134:3: warning: conversion to 'short unsigned int' from 'int' may
             alter its value
smb.c:146:42: warning: conversion to 'unsigned int' from 'long long
              unsigned int' may alter its value
smb.c:146:65: warning: conversion to 'unsigned int' from 'long long
              unsigned int' may alter its value
2015-11-21 11:41:20 +00:00
Steve Holme
c2f1730e17 schannel: Corrected copy/paste error in commit 8d17117683 2015-11-21 02:54:44 +00:00
Steve Holme
8d17117683 schannel: Use GetVersionEx() when VerifyVersionInfo() isn't available
Regression from commit 7a8e861a5 as highlighted in the msys autobuilds.
2015-11-21 02:43:17 +00:00
Steve Holme
c90e348579 examples: Fixed compilation warnings
pop3-multi.c:96:5: warning: implicit declaration of function 'memset'
imap-multi.c:96:5: warning: implicit declaration of function 'memset'
http2-download.c:226:5: warning: implicit declaration of function 'memset'
http2-upload.c:290:5: warning: implicit declaration of function 'memset'
http2-upload.c:290:5: warning: implicit declaration of function 'memset'
2015-11-21 01:47:02 +00:00
Steve Holme
f024ece8c7 Makefile.inc: Fixed test run error
test845 not present in tests/data/Makefile.inc
2015-11-21 00:04:57 +00:00
Daniel Stenberg
ad6f6e17d3 TODO: remove duplicated title 2015-11-20 09:37:11 +01:00
Daniel Stenberg
0ddc59be0a TODO: added two more libcurl ideas
Moved some ideas from "next major" to just ordinary ideas since we can
always add new things while keeping the old without doing a "next
major".
2015-11-20 08:39:59 +01:00
Steve Holme
bbb34b6f15 tests: Re-enabled tests 889 and 890 following POP3 fix 2015-11-20 07:04:19 +00:00
Steve Holme
41efdadf09 pop3: Differentiate between success and continuation responses 2015-11-20 07:01:01 +00:00
Steve Holme
6af80afe49 pop3: Added clarity on some server response codes 2015-11-20 06:41:53 +00:00
Daniel Shahaf
80562083da build: Fix theoretical infinite loops
Add error-checking to 'cd' in a few cases where omitting the checks
might result in an infinite loop.

Closes #535
2015-11-20 00:25:42 +01:00
122 changed files with 1543 additions and 2354 deletions

1
.gitignore vendored
View File

@@ -49,3 +49,4 @@ missing
mkinstalldirs
tags
test-driver
scripts/_curl

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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

View File

@@ -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/

View File

@@ -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

View File

@@ -73,3 +73,7 @@ smtp-vrfy
url2file
usercertinmem
xmlstream
http2-download
http2-serverpush
http2-upload
imap-lsub

View File

@@ -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.

View File

@@ -25,6 +25,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* somewhat unix-specific */
#include <sys/time.h>

View File

@@ -25,6 +25,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* somewhat unix-specific */
#include <sys/time.h>

View File

@@ -25,6 +25,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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:
*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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:

View File

@@ -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'`; \

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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");

View File

@@ -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);
}

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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
View File

@@ -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;

View File

@@ -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;

View File

@@ -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)) {

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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?"[":"",

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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;

View File

@@ -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:

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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))

View File

@@ -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))

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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];

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 "

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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;

722
lib/url.c

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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) */

View File

@@ -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");

View File

@@ -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;

View File

@@ -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));

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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