Compare commits

...

352 Commits

Author SHA1 Message Date
Daniel Stenberg
70812c2f32 THANKS: added contributors from the 7.32.0 release notes 2013-08-11 23:43:32 +02:00
Fabian Keil
a64bca68c7 test1228: add 'HTTP proxy' to the keywords 2013-08-11 19:56:23 +02:00
Fabian Keil
67633e1308 tests: add keywords for a couple of FILE tests 2013-08-11 19:56:14 +02:00
Fabian Keil
715ca7c5fe tests: add 'FAILURE' keywords to tests 1409 and 1410 2013-08-11 19:56:11 +02:00
Fabian Keil
001758760b tests: add keywords for a couple of HTTP tests 2013-08-11 19:56:05 +02:00
Fabian Keil
2f06265e39 tests: add keywords for a couple of FTP tests 2013-08-11 19:56:01 +02:00
Fabian Keil
432431368f test1511: consistently terminate headers with CRLF 2013-08-11 19:55:44 +02:00
Daniel Stenberg
4b0028f82d DISABLED: shut of test 1512 for now
It shows intermittent failures and I haven't been able to track them
down yet. Disable this test for now.
2013-08-10 23:55:10 +02:00
Daniel Stenberg
8c9236bb2c curl_multi_add_handle.3: ... that timer callback is for event-based 2013-08-09 23:53:51 +02:00
Daniel Stenberg
2af0b10c95 comments: remove old and wrong multi/easy interface statements 2013-08-09 23:39:09 +02:00
Daniel Stenberg
08adecc9a1 curl_multi_add_handle.3: mention the CURLMOPT_TIMERFUNCTION use 2013-08-09 23:27:43 +02:00
John E. Malmberg
015556d74c KNOWN_BUGS: 22 and 57 have been fixed and committed 2013-08-08 23:34:36 +02:00
Daniel Stenberg
4c40fe64b8 RELEASE-NOTES: synced with d20def2046 2013-08-08 16:37:17 +02:00
Daniel Stenberg
d20def2046 global dns cache: fix memory leak
The take down of the global dns cache didn't take CURLOPT_RESOLVE names
into account.
2013-08-08 16:28:46 +02:00
Daniel Stenberg
d2b36e466a global dns cache: didn't work [regression]
CURLOPT_DNS_USE_GLOBAL_CACHE broke in commit c43127414d (been
broken since the libcurl 7.29.0 release). While this option has been
documented as deprecated for almost a decade and nobody even reported
this bug, it should remain functional.

Added test case 1512 to verify
2013-08-08 16:28:46 +02:00
John Malmberg
27f8c93daf packages/vms: update VMS build files
VMS modified files either missing from a previous commit and changes
to remove references to CVS repositories.
2013-08-08 13:13:56 +02:00
Daniel Stenberg
058b86e6f3 FTP: renamed several local functions
The previous naming scheme ftp_state_post_XXXX() wasn't really helpful
as it wasn't always immediately after 'xxxx' and it wasn't easy to
understand what it does based on such a name.

This new one is instead ftp_state_yyyy() where yyyy describes what it
does or sends.
2013-08-08 12:19:01 +02:00
Daniel Stenberg
0018d6830e mk-ca-bundle.1: don't install on make install
Since the mk-ca-bundle tool itself isn't installed with make install,
there's no point in installing its documentation.

Bug: http://curl.haxx.se/mail/lib-2013-08/0057.html
Reported-by: Guenter Knauf
2013-08-08 09:45:51 +02:00
Yang Tse
59224a31fd packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-07 12:21:56 +02:00
John Malmberg
0994d737c8 Building_vms_pcsi_kit
These are the files needed to build VMS distribution packages known as
PCSI kits.

Also minor update to the existing files, mainly to the documentation and
file clean up code.
2013-08-07 12:16:08 +02:00
Daniel Stenberg
96749554fd LIBCURL-STRUCTS: new document
This is the first version of this new document, detailing the seven
perhaps most important internal structs in libcurl source code:

  1.1 SessionHandle
  1.2 connectdata
  1.3 Curl_multi
  1.4 Curl_handler
  1.5 conncache
  1.6 Curl_share
  1.7 CookieInfo
2013-08-06 14:13:33 +02:00
Daniel Stenberg
785749405f CONTRIBUTE: minor language polish 2013-08-06 14:12:45 +02:00
Daniel Stenberg
7cc00d9a83 FTP: when EPSV gets a 229 but fails to connect, retry with PASV
This is a regression as this logic used to work. It isn't clear when it
broke, but I'm assuming in 7.28.0 when we went all-multi internally.

This likely never worked with the multi interface. As the failed
connection is detected once the multi state has reached DO_MORE, the
Curl_do_more() function was now expanded somewhat so that the
ftp_do_more() function can request to go "back" to the previous state
when it makes another attempt - using PASV.

Added test case 1233 to verify this fix. It has the little issue that it
assumes no service is listening/accepting connections on port 1...

Reported-by: byte_bucket in the #curl IRC channel
2013-08-06 09:57:59 +02:00
Nick Zitzmann
230e16dc03 md5: remove use of CommonCrypto-to-OpenSSL macros for the benefit of Leopard
For some reason, OS X 10.5's GCC suddenly stopped working correctly with
macros that change MD5_Init etc. in the code to CC_MD5_Init etc., so I
worked around this by removing use of the macros and inserting static
functions that just call CommonCrypto's implementations of the functions
instead.
2013-08-05 19:47:56 -06:00
Guenter Knauf
0ce410a629 Simplify check for trusted certificates.
This changes the previous check for untrusted certs to a check for
certs explicitely marked as trusted.
The change is backward-compatible (tested with certdata.txt v1.80).
2013-08-05 13:02:27 +02:00
Daniel Stenberg
5d3cbde72e configure: warn on bad env variable use, don't error
Use XC_CHECK_BUILD_FLAGS instead XC_CHECK_USER_FLAGS.
2013-08-05 09:31:59 +02:00
Daniel Stenberg
8fe8fd2b17 Revert "configure: don't error out on variable confusions, just warn"
This reverts commit 6b27703b5f.
2013-08-05 09:28:44 +02:00
Daniel Stenberg
0ddc678927 formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used
The internal function that's used to detect known file extensions for
the default Content-Type got the the wrong pointer passed in when
CURLFORM_BUFFER + CURLFORM_BUFFERPTR were used. This had the effect that
strlen() would be used which could lead to an out-of-bounds read (and
thus segfault). In most cases it would only lead to it not finding or
using the correct default content-type.

It also showed that test 554 and test 587 were testing for the
previous/wrong behavior and now they're updated as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1262
Reported-by: Konstantin Isakov
2013-08-04 23:32:36 +02:00
Guenter Knauf
51f0b798fa Skip more untrusted certificates.
Christian Heimes brought to our attention that the certdata.txt
format has recently changed [1], causing ca-bundle.crt created
with mk-ca-bundle.[pl|vbs] to include untrusted certs.

[1] http://lists.debian.org/debian-release/2012/11/msg00411.html
2013-08-04 21:30:11 +02:00
Daniel Stenberg
6b27703b5f configure: don't error out on variable confusions, just warn 2013-08-04 10:28:26 +02:00
Daniel Stenberg
045ccb59a4 configure: rephrase the notice in _XC_CHECK_VAR_*
Instead of claiming it is an error, we call it a "note" to reduce the
severity level. But the following text now says the [variable] "*should*
only be used to specify"... instead of previously having said "may".
2013-08-03 23:39:23 +02:00
Daniel Stenberg
784336deec multi: remove data->state.current_conn struct field
Not needed
2013-08-03 22:51:35 +02:00
Daniel Stenberg
eb41e8eebe multi: remove the one_easy struct field
Since the merge of SessionHandle with Curl_one_easy, this indirection
isn't used anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
3cd43bbfec multi: rename all Curl_one_easy to SessionHandle 2013-08-03 22:51:35 +02:00
Daniel Stenberg
204e340bcd multi: remove the multi_pos struct field
Since Curl_one_easy is really a SessionHandle now, this indirection
doesn't exist anymore.
2013-08-03 22:51:35 +02:00
Daniel Stenberg
37f2ba7e57 multi: remove easy_handle struct field
It isn't needed anymore
2013-08-03 22:51:35 +02:00
Daniel Stenberg
09b9fc9009 multi: remove 'Curl_one_easy' struct, phase 1
The motivation for having a separate struct that keep track of an easy
handle when using the multi handle was removed when we switched to
always using the multi interface internally. Now they were just two
separate struct that was always allocated for each easy handle.

This first step just moves the Curl_one_easy struct members into the
SessionHandle struct and hides this somehow (== keeps the source code
changes to a minimum) by defining Curl_one_easy to SessionHandle

The biggest changes in this commit are:

 1 - the linked list of easy handles had to be changed somewhat due
     to the new struct layout. This made the main linked list pointer
     get renamed to 'easyp' and there's also a new pointer to the last
     node, called easylp. It is no longer circular but ends with ->next
     pointing to NULL. New nodes are still added last.

 2 - easy->state is now called easy->mstate to avoid name collision
2013-08-03 22:51:35 +02:00
Steve Holme
7da3caaf95 Revert "DOCS: Added IMAP URL example for listing new messages"
This reverts commit 82ab5f1b0c as this was the wrong place to
document the complexity of IMAP URLs and Custom Requests.
2013-08-02 14:25:21 +01:00
Steve Holme
82ab5f1b0c DOCS: Added IMAP URL example for listing new messages
In addition to listing the folder contents, in the URL examples, added
an example to list the new messages waiting in the user's inbox.
2013-08-02 10:08:55 +01:00
Yang Tse
7ae64af368 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-08-01 13:57:00 +02:00
John Malmberg
2ad688ed7c Add in the files needed to build libcurl shared images on VMS.
Update the packages/vms/readme file to be current.

Also some files for the GNV based build were either missing or needed an
update.

curl_crtl_init.c is a special file that is run before main() to
set up the proper C runtime behavior.

generate_vax_transfer.com generates the VAX transfer vector modules from
the gnv_libcurl_symbols.opt file.

gnv_conftest.c_first is a helper file needed for configure scripts to
come up with the expected answers on VMS.

gnv_libcurl_symbols.opt is the public symbols for the libcurl shared
image.

gnv_link_curl.com builds the shared libcurl image and rebuilds other
programs to use it.

macro32_exactcase.patch is a hack to make a local copy of the VMS Macro32
assembler case sensitive, which is needed to build the VAX transfer modules.

report_openssl_version.c is a tool for help verify that the libcurl
shared image is being built for a minium version of openssl.
2013-08-01 13:51:52 +02:00
Yang Tse
ca786233d2 curl: second follow-up for commit 5af2bfb9
Display progress-bar unconditionally on first call
2013-08-01 12:25:01 +02:00
Yang Tse
14a3139c4d curl: follow-up for commit 5af2bfb9
Use tvnow() and tvdiff() to avoid introducing new linkage issues
2013-07-31 15:36:56 +02:00
Daniel Stenberg
5af2bfb955 curl: --progress-bar max update frequency now at 5Hz 2013-07-31 13:41:00 +02:00
Daniel Stenberg
1691a31cab curl: make --progress-bar update the line less frequently
Also, use memset() instead of a lame loop.

The previous logic that tried to avoid too many updates were very
ineffective for really fast transfers, as then it could easily end up
doing hundreds of updates per second that would make a significant
impact in transfer performance!

Bug: http://curl.haxx.se/mail/archive-2013-07/0031.html
Reported-by: Marc Doughty
2013-07-31 13:41:00 +02:00
Nick Zitzmann
9dedcbf9ec darwinssl: added LFs to some strings passed into infof()
(This doesn't need to appear in the release notes.) I noticed a few places
where infof() was called, and there should've been an LF at the end of the
string, but there wasn't.
2013-07-30 20:32:18 -06:00
Nick Zitzmann
537ffc4c69 darwinssl: fix build error in crypto authentication under Snow Leopard
It turns out Snow Leopard not only has SecItemCopyMatching() defined in
a header not included by the omnibus header, but it won't work for our
purposes, because searching for SecIdentityRef objects wasn't added
to that API until Lion. So we now use the old SecKeychainSearch API
instead if the user is building under, or running under, Snow Leopard.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:25:38 -06:00
Nick Zitzmann
c3e7210548 md5 & metalink: use better build macros on Apple operating systems
Previously we used __MAC_10_X and __IPHONE_X to mark digest-generating
code that was specific to OS X and iOS. Now we use
__MAC_OS_X_VERSION_MAX_ALLOWED and __IPHONE_OS_VERSION_MAX_ALLOWED
instead of those macros.

Bug: http://sourceforge.net/p/curl/bugs/1255/
Reported by: Edward Rudd
2013-07-30 20:20:20 -06:00
Yang Tse
9a5c2d8373 tool_operhlp.c: fix add_file_name_to_url() OOM handling 2013-07-29 18:32:39 +02:00
Yang Tse
8693bbd8c4 tool_operate.c: fix brace placement for vi/emacs delimiter matching 2013-07-29 18:32:38 +02:00
Yang Tse
251dd03b88 tool_operate.c: move <fabdef.h> header inclusion location 2013-07-29 18:32:37 +02:00
Daniel Stenberg
55ea83d622 RELEASE-NOTES: synced with b5478a0e03 2013-07-29 14:51:09 +02:00
Daniel Stenberg
b5478a0e03 curl_easy_pause: on unpause, trigger mulit-socket handling
When the multi-socket API is used, we need the handle to be checked
again when it gets unpaused.

Bug: http://curl.haxx.se/mail/lib-2013-07/0239.html
Reported-by: Justin Karneges
2013-07-29 14:37:08 +02:00
John E. Malmberg
db2deba6b4 curl_formadd: fix file upload on VMS
For the standard VMS text file formats, VMS needs to read the file to
get the actual file size.

For the standard VMS binary file formats, VMS needs a special format of
fopen() call so that it stops reading at the logical end of file instead
of at the end of the blocks allocated to the file.

I structured the patch this way as I was not sure about changing the
structures or parameters to the routines, but would prefer to only call
the stat() function once and pass the information to where the fopen()
call is made.

Bug: https://sourceforge.net/p/curl/bugs/758/
2013-07-29 13:09:08 +02:00
Daniel Stenberg
41fb6443ce formadd: CURLFORM_FILECONTENT wrongly rejected some option combos
The code for CURLFORM_FILECONTENT had its check for duplicate options
wrong so that it would reject CURLFORM_PTRNAME if used in combination
with it (but not CURLFORM_COPYNAME)! The flags field used for this
purpose cannot be interpreted that broadly.

Bug: http://curl.haxx.se/mail/lib-2013-07/0258.html
Reported-by: Byrial Jensen
2013-07-26 23:45:01 +02:00
Yang Tse
e5dfe6c282 packages/vms/Makefile.am: add latest file additions to EXTRA_DIST 2013-07-25 13:18:50 +02:00
John E. Malmberg
e277e20a6d VMS: intial set of files to allow building using GNV toolkit. 2013-07-25 13:04:29 +02:00
Yang Tse
a23e56d109 string formatting: fix too many arguments for format 2013-07-24 17:06:28 +02:00
Yang Tse
ca89a0a092 string formatting: fix zero-length printf format string 2013-07-24 17:05:02 +02:00
Yang Tse
50a74be125 easy.c: curl_easy_getinfo() fix va_start/va_end matching 2013-07-24 16:46:26 +02:00
Yang Tse
8c1e3bb713 imap.c: imap_sendf() fix va_start/va_end matching 2013-07-24 16:46:25 +02:00
Yang Tse
4fad1943a2 string formatting: fix 15+ printf-style format strings 2013-07-24 16:46:24 +02:00
Patrick Monnerat
4d346673a2 OS400: sync ILE/RPG binding with current curl.h 2013-07-24 16:12:35 +02:00
Yang Tse
de052ca6fc string formatting: fix 25+ printf-style format strings 2013-07-24 01:21:26 +02:00
Daniel Stenberg
1a593191c2 Makefile.am: use LDFLAGS as well when linking libcurl
Linking on Solaris 10 x86 with Sun Studio 12 failed when we upgraded
automake for the release builds.

Bug: http://curl.haxx.se/bug/view.cgi?id=1217
Reported-by: Dagobert Michelsen
2013-07-23 21:51:12 +02:00
Fabian Keil
2c4ef997b9 url.c: Fix dot file path cleanup when using an HTTP proxy
Previously the path was cleaned, but the URL wasn't properly updated.
2013-07-23 20:51:15 +02:00
Fabian Keil
d020e2c381 tests: test1232 verifies dotdot removal from path with proxy 2013-07-23 20:51:15 +02:00
Fabian Keil
48fe9226a0 dotdot.c: Fix a RFC section number in a comment for Curl_dedotdotify() 2013-07-23 20:50:59 +02:00
John E. Malmberg
a77ac42e52 build_vms.com: fix debug and float options
In the reorganization of the build_vms.com the debug and float options
were not fixed up correctly.
2013-07-22 22:30:05 +02:00
John E. Malmberg
5880db8abd curl: fix upload of a zip file in OpenVMS
Two fixes:

1. Force output file format to be stream-lf so that partial downloads
can be continued.

This should have minor impact as if the file does not exist, it was
created with stream-lf format.  The only time this was an issue is if
there was already an existing file with a different format.

2. Fix file uploads are now fixed.

   a. VMS binary files such as ZIP archives are now uploaded
      correctly.

   b. VMS text files are read once to get the correct size
      and then converted to line-feed terminated records as
      they are read into curl.

The default VMS text formats do not contain either line-feed or
carriage-return terminated records.  Those delimiters are added by the
operating system file read calls if the application requests them.

Bug: http://curl.haxx.se/bug/view.cgi?id=496
2013-07-22 22:30:05 +02:00
Yang Tse
0f4ba89ffd libtest: fix data type of some *_setopt() 'long' arguments 2013-07-22 21:40:45 +02:00
Yang Tse
edeb1ae65f curl: fix symbolic names for CURL_NETRC_* enum in --libcurl output 2013-07-22 21:40:44 +02:00
Yang Tse
82232bbbaf curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output 2013-07-22 21:40:43 +02:00
Yang Tse
bb2e0686ab tool_operate.c: fix passing curl_easy_setopt long arg on some x64 ABIs
We no longer pass our 'bool' data type variables nor constants as
an argument to my_setopt(), instead we use proper 1L or 0L values.

This also fixes macro used to pass string argument for CURLOPT_SSLCERT,
CURLOPT_SSLKEY and CURLOPT_EGDSOCKET using my_setopt_str() instead of
my_setopt().

This also casts enum or int argument data types to long when passed to
my_setopt_enum().
2013-07-22 21:40:43 +02:00
Daniel Stenberg
513e587c5e curl_multi_wait: fix revents
Commit 6d30f8ebed didn't work properly. First, it used the wrong
array index, but this fix also:

1 - only does the copying if indeed there was any activity

2 - makes sure to properly translate between internal and external
bitfields, which are not guaranteed to match

Reported-by: Evgeny Turnaev
2013-07-21 21:54:47 +02:00
Daniel Stenberg
6ed2bcc5f5 RELEASE-NOTES: synced with d529f3882b 2013-07-19 23:38:43 +02:00
Daniel Stenberg
d529f3882b curl_easy_perform: gradually increase the delay time
Instead of going 50,100,150 etc millisecond delay time when nothing has
been found to do or wait for, we now start lower and double each loop as
in 4,8,16,32 etc.

This lowers the minimum wait without sacrifizing the longer wait too
much with unnecessary CPU cycles burnt.

Bug: http://curl.haxx.se/mail/lib-2013-07/0103.html
Reported-by: Andreas Malzahn
2013-07-19 23:27:17 +02:00
Daniel Stenberg
e2e92486a7 ftp_do_more: consider DO_MORE complete when server connects back
In the case of an active connection when ftp_do_more() detects that the
server has connected back, it must make sure to mark it as complete so
that the multi_runsingle() function will detect this and move on to the
next state.

Bug: http://curl.haxx.se/mail/lib-2013-07/0115.html
Reported-by: Clemens Gruber
2013-07-19 23:02:30 +02:00
Yang Tse
2e5b3168d6 Makefile.b32: Borland makefile adjustments. Tested with BCC 5.5.1 2013-07-19 12:33:11 +02:00
Yang Tse
6bcacff1a5 WIN32 MemoryTracking: require UNICODE for wide strdup code support 2013-07-19 12:33:10 +02:00
Daniel Stenberg
12d01cb6fa CURLOPT_XFERINFOFUNCTION: introducing a new progress callback
CURLOPT_XFERINFOFUNCTION is now the preferred progress callback function
and CURLOPT_PROGRESSFUNCTION is considered deprecated.

This new callback uses pure 'curl_off_t' arguments to pass on full
resolution sizes. It otherwise retains the same characteristics: the
same call rate, the same meanings for the arguments and the return code
is used the same way.

The progressfunc.c example is updated to show how to use the new
callback for newer libcurls while supporting the older one if built with
an older libcurl or even built with a newer libcurl while running with
an older.
2013-07-18 23:44:06 +02:00
Yang Tse
90695fb2c5 Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage".
This reverts commit 7ed25cc, reinstating commit 8ec2cb5.

As of 18-jul-2013 we still do have code in libcurl that makes use of these
memory functions. Commit 8ec2cb5 comment still applies and is yet valid.

These memory functions are solely used in Windows builds, so all related
code is protected with '#ifdef WIN32' preprocessor conditional compilation
directives.

Specifically, wcsdup() _wcsdup() are used when building a Windows target with
UNICODE and USE_WINDOWS_SSPI preprocessor symbols defined. This is the case
when building a Windows UNICODE target with Windows native SSL/TLS support
enabled.

Realizing that wcsdup() _wcsdup() are used is a bit tricky given that usage
of these is hidden behind _tcsdup() which is MS way of dealing with code
that must tolerate UNICODE and non-UNICODE compilation. Additionally, MS
header files and those compatible from other compilers use this preprocessor
conditional compilation directive in order to select at compilation time
whether 'wide' or 'ansi' MS API functions are used.

Without this code, Windows build targets with Windows native SSL/TLS support
enabled and MemoryTracking support enabled misbehave in tracking memory usage,
regardless of being a UNICODE enabled build or not.
2013-07-18 23:37:33 +02:00
Yang Tse
dd17069c9e xc-am-iface.m4: comments refinement 2013-07-18 16:03:15 +02:00
Yang Tse
26b0cb6ae2 configure: fix 'subdir-objects' distclean related issue
See XC_AMEND_DISTCLEAN comments for details.
2013-07-18 04:48:33 +02:00
Evgeny Turnaev
6d30f8ebed curl_multi_wait: set revents for extra fds
Pass back the revents that happened for the user-provided file
descriptors.
2013-07-18 00:06:09 +02:00
Ben Greear
11220678c4 asyn-ares: Don't blank ares servers if none configured.
Best to just let c-ares use it's defaults if none are configured
in (lib)curl.

Signed-off-by: Ben Greear <greearb@candelatech.com>
2013-07-17 23:55:58 +02:00
Sergei Nikulov
448d55ef0a cmake: Fix for MSVC2010 project generation
Fixed issue with static build for MSVC2010.

After some investigation I've discovered known issue
http://public.kitware.com/Bug/view.php?id=11240 When .rc file is linked
to static lib it fails with following linker error

LINK : warning LNK4068: /MACHINE not specified; defaulting to X86
file.obj : fatal error LNK1112: module machine type 'x64' conflicts with
target machine type 'X86'

Fix add target property /MACHINE: for MSVC generation.

Also removed old workarounds - it caused errors during msvc build.

Bug: http://curl.haxx.se/mail/lib-2013-07/0046.html
2013-07-17 00:26:58 +02:00
Daniel Stenberg
7b115cc1e1 mk-ca-bundle.1: point out certdata.txt format docs 2013-07-17 00:06:16 +02:00
Yang Tse
a10d5e3851 slist.c: Curl_slist_append_nodup() OOM handling fix 2013-07-16 23:59:05 +02:00
Daniel Stenberg
1016637f5a test1414: FTP PORT download without SIZE support 2013-07-16 22:54:31 +02:00
Yang Tse
2e00872c04 tests/Makefile.am: add configurehelp.pm to DISTCLEANFILES 2013-07-16 22:51:35 +02:00
Patrick Monnerat
56ece42c81 curl_slist_append(): fix error detection 2013-07-15 19:49:30 +02:00
Patrick Monnerat
99924f6606 slist.c: fix indentation 2013-07-15 19:46:19 +02:00
Patrick Monnerat
0eba02fd41 OS400: new SSL backend GSKit 2013-07-15 19:00:36 +02:00
Patrick Monnerat
464c8693d2 OS400: add slist and certinfo EBCDIC support 2013-07-15 18:48:02 +02:00
Patrick Monnerat
50af17ef24 config-os400.h: enable system strdup(), strcmpi(), etc. 2013-07-15 18:38:17 +02:00
Patrick Monnerat
3a24cb7bc4 x509asn1.c,x509asn1.h: new module to support ASN.1/X509 parsing & info extract
Use from qssl backend
2013-07-15 18:16:13 +02:00
Patrick Monnerat
e839446c2a ssluse.c,sslgen.c,sslgen.h: move certinfo support to generic SSL 2013-07-15 17:26:59 +02:00
Patrick Monnerat
695931cf8e Merge branch 'master' of github.com:bagder/curl
Merge for resync
2013-07-15 16:55:30 +02:00
Patrick Monnerat
964a7600b9 slist.c, slist.h, cookie.c: new internal procedure Curl_slist_append_nodup() 2013-07-15 16:53:43 +02:00
Yang Tse
d4492f955d sslgen.c: fix Curl_rand() compiler warning
Use simple seeding method upon RANDOM_FILE seeding method failure.
2013-07-15 16:00:32 +02:00
Yang Tse
9c15325d34 sslgen.c: fix unreleased Curl_rand() infinite recursion 2013-07-15 13:22:08 +02:00
Dave Reisner
d8c04909fa src/tool: allow timeouts to accept decimal values
Implement wrappers around strtod to convert the user argument to a
double with sane error checking. Use this to allow --max-time and
--connect-timeout to accept decimal values instead of strictly integers.

The manpage is updated to make mention of this feature and,
additionally, forewarn that the actual timeout of the operation can
vary in its precision (particularly as the value increases in its
decimal precision).
2013-07-14 23:04:05 +02:00
Dave Reisner
c0a7a98aee curl.1: fix long line, found by checksrc.pl 2013-07-14 22:50:29 +02:00
Dave Reisner
f5005dd8d0 src/tool_paramhlp: try harder to catch negatives
strto* functions happily chomp off leading whitespace, so simply
checking for str[0] can lead to false negatives. Do the full parse and
check the out value instead.
2013-07-14 22:48:29 +02:00
John E. Malmberg
d3aaa68f55 build_vms.com: detect and use zlib shared image
Update the build_vms.com to detect and use zlib shared image installed
by the ZLIB kit produced by Jean-Francois Pieronne, and the also the
future ZLIB 1.2.8 kit in addition to the older ZLIB kits.

Also fix the indentation to match one of the common standards used for
VMS DCL command files and removed the hard tab characters.

Tested on OpenVMS 8.4 Alpha and IA64, and OpenVMS 7.3 VAX.
2013-07-14 17:37:49 +02:00
Yang Tse
cfc907e43d url.c: fix parse_url_login() OOM handling 2013-07-14 12:19:57 +02:00
Yang Tse
2af64c6432 http_digest.c: SIGSEGV and OOM handling fixes 2013-07-12 19:32:13 +02:00
Yang Tse
83f0dae129 url.c: fix parse_login_details() OOM handling 2013-07-12 12:17:31 +02:00
John E. Malmberg
65d53cf6ef setup-vms.h: sk_pop symbol tweak
Newer versions of curl are referencing a sk_pop symbol while the HP
OpenSSL library has the symbol in uppercase only.
2013-07-12 12:11:11 +02:00
Yang Tse
0d9e65f79f getinfo.c: fix enumerated type mixed with another type 2013-07-11 17:07:36 +02:00
Yang Tse
c983aa9efc test 1511: fix enumerated type mixed with another type 2013-07-11 17:01:02 +02:00
Yang Tse
b16b7f9d3a url.c: fix SIGSEGV 2013-07-11 13:31:08 +02:00
Yang Tse
5c6f12b9f2 dotdot.c: fix global declaration shadowing 2013-07-11 13:31:07 +02:00
Yang Tse
2022b10e50 easy.c: fix global declaration shadowing 2013-07-11 13:31:06 +02:00
Kamil Dudka
45339625bc Revert "curl.1: document the --time-cond option in the man page"
This reverts commit 3a0e931fc7 because
the documentation of --time-cond was duplicated by mistake.

Reported by: Dave Reisner
2013-07-09 15:46:49 +02:00
Kamil Dudka
20ff820ef2 curl.1: document the --sasl-ir option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
39e85d99fe curl.1: document the --post303 option in the man page 2013-07-09 15:18:39 +02:00
Kamil Dudka
3a0e931fc7 curl.1: document the --time-cond option in the man page 2013-07-09 15:18:39 +02:00
Yang Tse
fe7e3229f8 configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) 2013-07-09 00:10:38 +02:00
Yang Tse
ecf042ff3c xc-am-iface.m4: provide XC_AUTOMAKE macro 2013-07-09 00:07:26 +02:00
Guenter Knauf
aff245b360 Added winssl-zlib target to VC builds. 2013-07-08 17:46:15 +02:00
Guenter Knauf
e01469907a Synced Makefile.vc6 with recent changes.
Issue posted to the list by malinowsky AT FTW DOT at.
2013-07-08 15:05:10 +02:00
Guenter Knauf
b7a933154a Added libmetalink URL; added Android versions. 2013-07-04 04:35:22 +02:00
Dan Fandrich
54f18e5427 examples: Moved usercertinmem.c to COMPLICATED_EXAMPLES
This prevents it from being built during a "make check" since it
depends on OpenSSL.
2013-07-03 21:13:12 +02:00
Nick Zitzmann
833fba265d Merge branch 'master' of https://github.com/bagder/curl 2013-07-02 19:40:14 -06:00
Nick Zitzmann
d633052905 darwinssl: SSLv2 connections are aborted if unsupported by the OS
I just noticed that OS X no longer supports SSLv2. Other TLS engines return
an error if the requested protocol isn't supported by the underlying
engine, so we do that now for SSLv2 if the framework returns an error
when trying to turn on SSLv2 support. (Note: As always, SSLv2 support is
only enabled in curl when starting the app with the -2 argument; it's off
by default. SSLv2 is really old and insecure.)
2013-07-02 19:34:54 -06:00
Marc Hoersken
009d2336fe lib506.c: Fixed possible use of uninitialized variables 2013-07-01 21:42:15 +02:00
Kamil Dudka
abca89aaa0 url: restore the functionality of 'curl -u :'
This commit fixes a regression introduced in
fddb7b44a7.

Reported by: Markus Moeller
Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html
2013-06-30 20:13:14 +02:00
Daniel Stenberg
d689376cb0 digest: append the timer to the random for the nonce 2013-06-25 11:37:27 +02:00
Daniel Stenberg
98b0d66eb4 digest: improve nonce generation
Use the new improved Curl_rand() to generate better random nonce for
Digest auth.
2013-06-25 11:28:22 +02:00
Daniel Stenberg
9c2853f2ae curl.1: fix typo in --xattr description
Bug: http://curl.haxx.se/bug/view.cgi?id=1252
Reported-by: Jean-Noël Rouvignac
2013-06-25 10:41:16 +02:00
Daniel Stenberg
aff7562922 RELEASE-NOTES: synced with 365c5ba395
The 10 first bug fixes for the pending release...
2013-06-25 10:35:21 +02:00
Daniel Stenberg
365c5ba395 formpost: better random boundaries
When doing multi-part formposts, libcurl used a pseudo-random value that
was seeded with time(). This turns out to be bad for users who formpost
data that is provided with users who then can guess how the boundary
string will look like and then they can forge a different formpost part
and trick the receiver.

My advice to such implementors is (still even after this change) to not
rely on the boundary strings being cryptographically strong. Fix your
code and logic to not depend on them that much!

I moved the Curl_rand() function into the sslgen.c source file now to be
able to take advantage of the SSL library's random function if it
provides one. If not, try to use the RANDOM_FILE for seeding and as a
last resort keep the old logic, just modified to also add microseconds
which makes it harder to properly guess the exact seed.

The formboundary() function in formdata.c is now using 64 bit entropy
for the boundary and therefore the string of dashes was reduced by 4
letters and there are 16 hex digits following it. The total length is
thus still the same.

Bug: http://curl.haxx.se/bug/view.cgi?id=1251
Reported-by: "Floris"
2013-06-25 09:55:49 +02:00
Daniel Stenberg
cb1aa8b0e3 printf: make sure %x are treated unsigned
When using %x, the number must be treated as unsigned as otherwise it
would get sign-extended on for example 64bit machines and do wrong
output. This problem showed when doing printf("%08x", 0xffeeddcc) on a
64bit host.
2013-06-25 09:55:49 +02:00
Daniel Stenberg
d3d5c4a40e tests: add test1395 to the tarball 2013-06-24 09:25:58 +02:00
Daniel Stenberg
6117d4025e SIGPIPE: don't use 'data' in sigpipe restore
Follow-up fix from 7d80ed64e4.

The SessionHandle may not be around to use when we restore the sigpipe
sighandler so we store the no_signal boolean in the local struct to know
if/how to restore.
2013-06-24 09:02:49 +02:00
Daniel Stenberg
d23745f7c9 TODO: 1.8 Modified buffer size approach
Thoughts around buffer sizes and what might be possible to do...
2013-06-23 22:49:06 +02:00
Daniel Stenberg
ad47d8e263 c-ares: improve error message on failed resolve
When the c-ares based resolver backend failed to resolve a name, it
tried to show the name that failed from existing structs. This caused
the wrong output and shown hostname when for example --interface
[hostname] was used and that name resolving failed.

Now we use the hostname used in the actual resolve attempt in the error
message as well.

Bug: http://curl.haxx.se/bug/view.cgi?id=1191
Reported-by: Kim Vandry
2013-06-23 20:25:38 +02:00
Daniel Stenberg
8a7a277c08 ossl_recv: check for an OpenSSL error, don't assume
When we recently started to treat a zero return code from SSL_read() as
an error we also got false positives - which primarily looks to be
because the OpenSSL documentation is wrong and a zero return code is not
at all an error case in many situations.

Now ossl_recv() will check with ERR_get_error() to see if there is a
stored error and only then consider it to be a true error if SSL_read()
returned zero.

Bug: http://curl.haxx.se/bug/view.cgi?id=1249
Reported-by: Nach M. S.
Patch-by: Nach M. S.
2013-06-23 12:05:21 +02:00
Nick Zitzmann
0030fbd382 Merge branch 'master' of https://github.com/bagder/curl 2013-06-22 15:16:05 -06:00
Nick Zitzmann
f3052c8a81 darwinssl: fix crash that started happening in Lion
Something (a recent security update maybe?) changed in Lion, and now it
has changed SSLCopyPeerTrust such that it may return noErr but also give
us a null trust, which caught us off guard and caused an eventual crash.
2013-06-22 15:13:36 -06:00
Daniel Stenberg
7d80ed64e4 SIGPIPE: ignored while inside the library
... and restore the ordinary handling again when it returns. This is
done for curl_easy_perform() and curl_easy_cleanup() only for now - and
only when built to use OpenSSL as backend as this is the known culprit
for the spurious SIGPIPEs people have received.

Bug: http://curl.haxx.se/bug/view.cgi?id=1180
Reported by: Lluís Batlle i Rossell
2013-06-22 22:35:06 +02:00
Daniel Stenberg
a2e0ce86ba KNOWN_BUGS: #83 unable to load non-default openssl engines 2013-06-22 22:24:36 +02:00
Daniel Stenberg
6fab0bd9f1 test1396: invoke the correct test tool!
This erroneously run unit test 1310 instead of 1396!
2013-06-22 22:20:31 +02:00
Kamil Dudka
02964ed630 test1230: avoid using hard-wired port number
... to prevent failure when a non-default -b option is given
2013-06-22 22:12:49 +02:00
Kamil Dudka
6f3e7aabdc curl-config.in: replace tabs by spaces 2013-06-22 22:08:42 +02:00
Nick Zitzmann
631e3e13a9 darwinssl: reform OS-specific #defines
This doesn't need to be in the release notes. I cleaned up a lot of the #if
lines in the code to use MAC_OS_X_VERSION_MIN_REQUIRED and
MAC_OS_X_VERSION_MAX_ALLOWED instead of checking for whether things like
__MAC_10_6 or whatever were defined, because for some SDKs Apple has released
they were defined out of place.
2013-06-22 12:23:26 -06:00
Alessandro Ghedini
832c195179 docs: fix typo in curl_easy_getinfo manpage 2013-06-22 18:28:18 +02:00
Daniel Stenberg
7877619f85 dotdot: introducing dot file path cleanup
RFC3986 details how a path part passed in as part of a URI should be
"cleaned" from dot sequences before getting used. The described
algorithm is now implemented in lib/dotdot.c with the accompanied test
case in test 1395.

Bug: http://curl.haxx.se/bug/view.cgi?id=1200
Reported-by: Alex Vinnik
2013-06-22 14:15:07 +02:00
Daniel Stenberg
ec248b590d bump: start working towards what most likely will become 7.32.0 2013-06-22 14:13:28 +02:00
Daniel Stenberg
4846b5e9fe THANKS: added 24 new contributors from the 7.31.0 release 2013-06-22 13:52:27 +02:00
Daniel Stenberg
85c710e11e RELEASE-NOTES: synced with 0de7249bb3 - 7.31.0 2013-06-22 11:30:31 +02:00
Daniel Stenberg
0de7249bb3 unit1396: unit tests to verify curl_easy_(un)escape 2013-06-22 11:21:35 +02:00
Daniel Stenberg
192c4f788d Curl_urldecode: no peeking beyond end of input buffer
Security problem: CVE-2013-2174

If a program would give a string like "%FF" to curl_easy_unescape() but
ask for it to decode only the first byte, it would still parse and
decode the full hex sequence. The function then not only read beyond the
allowed buffer but it would also deduct the *unsigned* counter variable
for how many more bytes there's left to read in the buffer by two,
making the counter wrap. Continuing this, the function would go on
reading beyond the buffer and soon writing beyond the allocated target
buffer...

Bug: http://curl.haxx.se/docs/adv_20130622.html
Reported-by: Timo Sirainen
2013-06-22 11:21:35 +02:00
Guenter Knauf
da0db499fd Use opened body.out file and write content to it. 2013-06-20 22:53:37 +02:00
Daniel Stenberg
88c5c63ffc multi_socket: react on socket close immediately
As a remedy to the problem when a socket gets closed and a new one is
opened with the same file descriptor number and as a result
multi.c:singlesocket() doesn't detect the difference, the new function
Curl_multi_closed() gets told when a socket is closed so that it can be
removed from the socket hash. When the old one has been removed, a new
socket should be detected fine by the singlesocket() on next invoke.

Bug: http://curl.haxx.se/bug/view.cgi?id=1248
Reported-by: Erik Johansson
2013-06-20 22:36:52 +02:00
Daniel Stenberg
a9f5ad0e2a RELEASE-NOTES: synced with e305f5ec71 2013-06-20 22:27:33 +02:00
Daniel Stenberg
e305f5ec71 TODO: mention the DANE patch from March 2013-06-18 09:38:06 +02:00
Daniel Stenberg
7ac3e9f1ba CURLOPT_COOKIELIST: take cookie share lock
When performing COOKIELIST operations the cookie lock needs to be taken
for the cases where the cookies are shared among multiple handles!

Verified by Benjamin Gilbert's updated test 506

Bug: http://curl.haxx.se/bug/view.cgi?id=1215
Reported-by: Benjamin Gilbert
2013-06-17 23:29:05 +02:00
Benjamin Gilbert
03a3dd9ee3 test506: verify that CURLOPT_COOKIELIST takes share lock
It doesn't right now: http://curl.haxx.se/bug/view.cgi?id=1215
2013-06-17 23:28:35 +02:00
Daniel Stenberg
5fc24a5297 TODO: HTTP2/SPDY support 2013-06-15 14:36:35 +02:00
Daniel Stenberg
b1a295ac4e curl_easy_setopt.3: clarify CURLOPT_PROGRESSFUNCTION frequency
Make it clearer that the CURLOPT_PROGRESSFUNCTION callback will be
called more frequently than once per second when things are happening.
2013-06-14 23:17:14 +02:00
Daniel Stenberg
1826c768ab RELEASE-NOTES: synced with 9c3e098259
Mention 7 recent bug fixes and their associated contributors
2013-06-13 23:01:32 +02:00
Daniel Stenberg
9c3e098259 curl_multi_wait.3: clarify the numfds counter 2013-06-13 22:38:53 +02:00
Daniel Stenberg
0feeab7802 curl_easy_perform: avoid busy-looping
When curl_multi_wait() finds no file descriptor to wait for, it returns
instantly and this must be handled gracefully within curl_easy_perform()
or cause a busy-loop. Starting now, repeated fast returns without any
file descriptors is detected and a gradually increasing sleep will be
used (up to a max of 1000 milliseconds) before continuing the loop.

Bug: http://curl.haxx.se/bug/view.cgi?id=1238
Reported-by: Miguel Angel
2013-06-13 19:27:12 +02:00
YAMADA Yasuharu
f24dc09d20 cookies: follow-up fix for path checking
The initial fix to only compare full path names were done in commit
04f52e9b4d but found out to be incomplete. This takes should make the
change more complete and there's now two additional tests to verify
(test 31 and 62).
2013-06-12 11:19:56 +02:00
Sergei Nikulov
9e10963c20 lib1900: use tutil_tvnow instead of gettimeofday
Makes it build on windows
2013-06-12 10:52:23 +02:00
Eric Hu
10b6d81c64 axtls: now done non-blocking 2013-06-12 10:37:32 +02:00
Eric Hu
8026bd7abd test2033: requires NTLM support 2013-06-12 10:34:10 +02:00
Daniel Stenberg
9b8df58169 KNOWN_BUGS: #82 failed build with Borland compiler 2013-06-11 00:21:16 +02:00
Daniel Stenberg
529a2e9110 Curl_output_digest: support auth-int for empty entity body
By always returning the md5 for an empty body when auth-int is asked
for, libcurl now at least sometimes does the right thing.

Bug: http://curl.haxx.se/bug/view.cgi?id=1235
Patched-by: Nach M. S.
2013-06-11 00:08:13 +02:00
Daniel Stenberg
21091549c0 multi_socket: reduce timeout inaccuracy margin
Allow less room for "triggered too early" mistakes by applications /
timers on non-windows platforms. Starting now, we assume that a timeout
call is never made earlier than 3 milliseconds before the actual
timeout. This greatly improves timeout accuracy on Linux.

Bug: http://curl.haxx.se/bug/view.cgi?id=1228
Reported-by: Hang Su
2013-06-11 00:02:29 +02:00
Daniel Stenberg
7b97f03f09 cert_stuff: avoid double free in the PKCS12 code
In the pkcs12 code, we get a list of x509 records returned from
PKCS12_parse but when iterating over the list and passing each to
SSL_CTX_add_extra_chain_cert() we didn't also properly remove them from
the "stack", which made them get freed twice (both in sk_X509_pop_free()
and then later in SSL_CTX_free).

This isn't really documented anywhere...

Bug: http://curl.haxx.se/bug/view.cgi?id=1236
Reported-by: Nikaiw
2013-06-10 23:42:48 +02:00
Daniel Stenberg
ce362e8eb9 cert_stuff: remove code duplication in the pkcs12 logic 2013-06-10 23:04:01 +02:00
Aleksey Tulinov
a4decb49a6 axtls: honor disabled VERIFYHOST
When VERIFYHOST == 0, libcurl should let invalid certificates to pass.
2013-06-08 00:23:05 +02:00
Peter Gal
c53fb36b0c curl_easy_setopt.3: HTTP header with no content
Update the documentation on how to specify a HTTP header with no
content.
2013-06-08 00:15:40 +02:00
Daniel Stenberg
dc19e656b5 RELEASE-NOTES: synced with 87cf677eca
Added 11 bugs and 7 contributors
2013-06-07 10:39:21 +02:00
Daniel Stenberg
87cf677eca lib1500: remove bad check
After curl_multi_wait() returns, this test checked that we got exactly
one file descriptor told to read from, but we cannot be sure that is
true. curl_multi_wait() will sometimes return earlier without any file
descriptor to handle, just just because it is a suitable time to call
*perform().

This problem showed up with commit 29bf0598.

Bug: http://curl.haxx.se/mail/lib-2013-06/0029.html
Reported-by: Fabian Keil
2013-06-06 22:22:14 +02:00
Daniel Stenberg
5657c56f63 tests/Makefile: typo in the perlcheck target
Bug: http://curl.haxx.se/bug/view.cgi?id=1239
Reported-by: Christian Weisgerber
2013-06-04 23:22:11 +02:00
Daniel Stenberg
51b3445e84 test1230: verify CONNECT to a numerical ipv6-address 2013-06-04 22:52:13 +02:00
Daniel Stenberg
a7452b8b8c sws: support extracting test number from CONNECT ipv6-address!
If an ipv6-address is provided to CONNECT, the last hexadecimal group in
the address will be used as the test number! For example the address
"[1234::ff]" would be treated as test case 255.
2013-06-04 22:50:58 +02:00
Daniel Stenberg
0bf5ce77aa curl_multi_wait: only use internal timer if not -1
commit 29bf0598aa introduced a problem when the "internal" timeout is
prefered to the given if shorter, as it didn't consider the case where
-1 was returned. Now the internal timeout is only considered if not -1.

Reported-by: Tor Arntsen
Bug: http://curl.haxx.se/mail/lib-2013-06/0015.html
2013-06-04 13:22:40 +02:00
Dan Fandrich
159d34b58e libcurl-tutorial.3: added a section on IPv6
Also added a (correctly-escaped) backslash to the autoexec.bat
example file and a new Windows character device name with
a colon as examples of other characters that are special
and potentially dangerous (this reverts and reworks commit
7d8d2a54).
2013-06-03 22:44:05 +02:00
Daniel Stenberg
29bf0598aa curl_multi_wait: reduce timeout if the multi handle wants to
If the multi handle's pending timeout is less than what is passed into
this function, it will now opt to use the shorter time anyway since it
is a very good hint that the handle wants to process something in a
shorter time than what otherwise would happen.

curl_multi_wait.3 was updated accordingly to clarify

This is the reason for bug #1224

Bug: http://curl.haxx.se/bug/view.cgi?id=1224
Reported-by: Andrii Moiseiev
2013-06-03 20:27:08 +02:00
Daniel Stenberg
239b58d34d multi_runsingle: switch an if() condition for readability
... because there's an identical check right next to it so using the
operators in the check in the same order increases readability.
2013-06-03 20:23:01 +02:00
Marc Hoersken
74f1810546 curl_schannel.c: Removed variable unused since 35874298e4 2013-06-02 20:21:42 +02:00
Marc Hoersken
f4b08b8f40 curl_setup.h: Fixed redefinition warning using mingw-w64 2013-06-02 15:53:08 +02:00
Daniel Stenberg
6691fdf517 multi_runsingle: add braces to clarify the code 2013-05-30 23:34:33 +02:00
Daniel Stenberg
7d8d2a54ba libcurl-tutorial.3: remove incorrect backslash
A single backslash in the content is not legal nroff syntax.

Reported and fixed by: Eric S. Raymond
Bug: http://curl.haxx.se/bug/view.cgi?id=1234
2013-05-28 13:37:08 +02:00
Daniel Stenberg
9986c6cb2b curl_formadd.3: fixed wrong "end-marker" syntax
Reported and fixed by: Eric S. Raymond
Bug: http://curl.haxx.se/bug/view.cgi?id=1233
2013-05-28 13:35:13 +02:00
Daniel Stenberg
ba9a66663a curl.1: clarify that --silent still outputs data 2013-05-28 11:37:58 +02:00
Daniel Stenberg
ac419bf562 Digest auth: escape user names with \ or " in them
When sending the HTTP Authorization: header for digest, the user name
needs to be escaped if it contains a double-quote or backslash.

Test 1229 was added to verify

Reported and fixed by: Nach M. S
Bug: http://curl.haxx.se/bug/view.cgi?id=1230
2013-05-27 19:45:12 +02:00
Mike Giancola
520833cbe1 ossl_recv: SSL_read() returning 0 is an error too
SSL_read can return 0 for "not successful", according to the open SSL
documentation: http://www.openssl.org/docs/ssl/SSL_read.html
2013-05-22 23:42:33 +02:00
Mike Giancola
e58d9c87f7 ossl_send: SSL_write() returning 0 is an error too
We found that in specific cases if the connection is abruptly closed,
the underlying socket is listed in a close_wait state. We continue to
call the curl_multi_perform, curl_mutli_fdset etc. None of these APIs
report the socket closed / connection finished.  Since we have cases
where the multi connection is only used once, this can pose a problem
for us. I've read that if another connection was to come in, curl would
see the socket as bad and attempt to close it at that time -
unfortunately, this does not work for us.

I found that in specific situations, if SSL_write returns 0, curl did
not recognize the socket as closed (or errored out) and did not report
it to the application. I believe we need to change the code slightly, to
check if ssl_write returns 0. If so, treat it as an error - the same as
a negative return code.

For OpenSSL - the ssl_write documentation is here:
http://www.openssl.org/docs/ssl/SSL_write.html
2013-05-22 23:08:27 +02:00
Daniel Stenberg
84f7991474 KNOWN_BUGS: curl -OJC- fails to resume
Bug: http://curl.haxx.se/bug/view.cgi?id=1169
2013-05-21 23:58:52 +02:00
Daniel Stenberg
85b9dc8023 Curl_cookie_add: handle IPv6 hosts
1 - don't skip host names with a colon in them in an attempt to bail out
on HTTP headers in the cookie file parser. It was only a shortcut anyway
and trying to parse a file with HTTP headers will still be handled, only
slightly slower.

2 - don't skip domain names based on number of dots. The original
netscape cookie spec had this oddity mentioned and while our code
decreased the check to only check for two, the existing cookie spec has
no such dot counting required.

Bug: http://curl.haxx.se/bug/view.cgi?id=1221
Reported-by: Stefan Neis
2013-05-21 23:28:59 +02:00
Daniel Stenberg
7d4d4892d8 curl_easy_setopt.3: expand the PROGRESSFUNCTION section
Explain the callback and its arguments better and with more descriptive
text.
2013-05-20 10:50:51 +02:00
Daniel Stenberg
fc4759af9d tests: add test1394 file to the tarball 2013-05-19 12:44:44 +02:00
Daniel Stenberg
ee84c47655 tarball: include the xmlstream example 2013-05-19 11:21:56 +02:00
David Strauss
ce32176db7 xmlstream: XML stream parsing example source code
Add an XML stream parsing example using Expat. Add missing ignore for
the binary from an unrelated example.
2013-05-19 11:19:28 +02:00
YAMADA Yasuharu
04f52e9b4d cookies: only consider full path matches
I found a bug which cURL sends cookies to the path not to aim at.
For example:
- cURL sends a request to http://example.fake/hoge/
- server returns cookie which with path=/hoge;
  the point is there is NOT the '/' end of path string.
- cURL sends a request to http://example.fake/hogege/ with the cookie.

The reason for this old "feature" is because that behavior is what is
described in the original netscape cookie spec:
http://curl.haxx.se/rfc/cookie_spec.html

The current cookie spec (RFC6265) clarifies the situation:
http://tools.ietf.org/html/rfc6265#section-5.2.4
2013-05-18 22:54:48 +02:00
Eric Hu
100a33f7ff axtls: prevent memleaks on SSL handshake failures 2013-05-16 20:26:42 +02:00
Daniel Stenberg
7ed25ccf0d Revert "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup() usage"
This reverts commit 8ec2cb5544.

We don't have any code anywhere in libcurl (or the curl tool) that use
wcsdup so there's no such memory use to track. It seems to cause mild
problems with the Borland compiler though that we may avoid by reverting
this change again.

Bug: http://curl.haxx.se/mail/lib-2013-05/0070.html
2013-05-12 15:10:01 +02:00
Daniel Stenberg
01eede2662 RELEASE-NOTES: synced with ae26ee3489 2013-05-12 14:36:04 +02:00
Guenter Knauf
ae26ee3489 Updated zlib version in build files. 2013-05-11 17:08:00 +02:00
Renaud Guillard
992bee504d OS X framework: fix invalid symbolic link 2013-05-09 21:51:35 +02:00
Daniel Stenberg
01a2abedd7 nss: give PR_INTERVAL_NO_WAIT instead of -1 to PR_Recv/PR_Send
Reported by: David Strauss
Bug: http://curl.haxx.se/mail/lib-2013-05/0088.html
2013-05-09 11:23:15 +02:00
Daniel Stenberg
a45e3f93e4 libtest: gitignore more binary files 2013-05-08 14:35:45 +02:00
Daniel Stenberg
bdb396ef2a servercert: allow empty subject
Bug: http://curl.haxx.se/bug/view.cgi?id=1220
Patch by: John Gardiner Myers
2013-05-07 23:02:01 +02:00
Steve Holme
6add1901a1 tests: Added new SMTP tests to verify commit 99b4045183 2013-05-07 22:52:43 +02:00
Daniel Stenberg
51b0f09b5e runtests.pl: support nonewline="yes" in client/stdin sections 2013-05-07 22:52:43 +02:00
Daniel Stenberg
8dac7be438 build: fixed unit1394 for debug and metlink builds 2013-05-06 23:28:04 +02:00
Kamil Dudka
bcf1b9dec1 unit1394.c: plug the curl tool unit test in 2013-05-06 15:03:13 +02:00
Jared Jennings
b045d079f8 unit1394.c: basis of a unit test for parse_cert_parameter() 2013-05-06 15:03:13 +02:00
Kamil Dudka
683f2b8323 src/Makefile.am: build static lib for unit tests if enabled 2013-05-06 15:03:12 +02:00
Kamil Dudka
2de20dd9a1 tool_getparam: ensure string termination in parse_cert_parameter() 2013-05-06 15:00:10 +02:00
Kamil Dudka
b47cf4f688 tool_getparam: fix memleak in handling the -E option 2013-05-06 15:00:10 +02:00
Kamil Dudka
a15b2b6c62 tool_getparam: describe what parse_cert_parameter() does
... and de-duplicate the code initializing *passphrase
2013-05-06 15:00:10 +02:00
Kamil Dudka
42e01cff9a curl.1: document escape sequences recognized by -E 2013-05-06 14:32:26 +02:00
Jared Jennings
865d4138a0 curl -E: allow to escape ':' in cert nickname 2013-05-06 14:32:26 +02:00
Marc Hoersken
35874298e4 curl_schannel.c: Fixed invalid memory access during SSL shutdown 2013-05-05 17:57:37 +02:00
Steve Holme
52d72e66c2 smtp: Fix trailing whitespace warning 2013-05-04 18:37:50 +01:00
Steve Holme
f3d10aa0d4 smtp: Fix compilation warning
comparison between signed and unsigned integer expressions
2013-05-04 13:24:05 +01:00
Steve Holme
7632bc911b RELEASE-NOTES: synced with 92ef5f19c8 2013-05-04 10:13:43 +01:00
Steve Holme
92ef5f19c8 smtp: Updated RFC-2821 references to RFC-5321 2013-05-04 10:12:01 +01:00
Steve Holme
99b4045183 smtp: Fixed sending of double CRLF caused by first in EOB
If the mail sent during the transfer contains a terminating <CRLF> then
we should not send the first <CRLF> of the EOB as specified in RFC-5321.

Additionally don't send the <CRLF> if there is "no mail data" as the
DATA command already includes it.
2013-05-04 10:00:33 +01:00
Steve Holme
087f9bb20a tests: Corrected MAIL SIZE for CRLF line endings
... which was missed in commit: f5c3d95384
2013-05-03 20:08:21 +01:00
Steve Holme
e2c7e19144 tests: Corrected infilesize for CRLF line endings
... which was missed in commit: f5c3d95384
2013-05-03 18:27:06 +01:00
Steve Holme
f5c3d95384 tests: Corrected test1406 to be RFC2821 compliant 2013-05-03 18:22:18 +01:00
Steve Holme
6b10f5b963 tests: Corrected test1320 to be RFC2821 compliant 2013-05-02 22:49:16 +01:00
Steve Holme
ee74b77d45 tests: Corrected typo in test909
Introduced in commit: 514817669e
2013-05-02 20:03:50 +01:00
Steve Holme
734bdb68c2 tests: Corrected test909 to be RFC2821 compliant 2013-05-02 18:52:52 +01:00
Steve Holme
514817669e tests: Updated test references to 909 from 1411
...and removed references to libcurl and test1406.
2013-05-02 18:50:00 +01:00
Steve Holme
cb9c0ac7d7 tests: Renamed test1411 to test909 as this is a main SMTP test 2013-05-02 18:46:11 +01:00
Lars Johannesen
1c435295b8 bindlocal: move brace out of #ifdef
The code within #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID wrongly had two
closing braces when it should only have one, so builds without that
define would fail.

Bug: http://curl.haxx.se/mail/lib-2013-05/0000.html
2013-05-01 14:18:47 +02:00
Steve Holme
46d26a0e77 smtp: Tidy up to move the eob counter to the per-request structure
Move the eob counter from the smtp_conn structure to the SMTP structure
as it is associated with a SMTP payload on a per-request basis.
2013-04-30 22:25:23 +01:00
Steve Holme
f4e3cae8a7 TODO: Updated following the addition of CURLOPT_SASL_IR 2013-04-30 00:12:41 +01:00
Steve Holme
b52cf5d2cd smtp: Fixed unknown percentage complete in progress bar
The curl command line utility would display the the completed progress
bar with a percentage of zero as the progress routines didn't know the
size of the transfer.
2013-04-29 22:34:26 +01:00
Daniel Stenberg
073e83b543 ftpserver: silence warnings
Fix regressions in commit b56e3d43e5. Make @data local and filter off
non-numerical digits from $testno in STATUS_imap.
2013-04-29 14:58:08 +02:00
Steve Holme
c3e6d69acb ftpserver.pl: Corrected the imap LOGIN response
...to be more realistic and consistent with the other imap responses.
2013-04-29 12:58:41 +01:00
Steve Holme
b56e3d43e5 tests: Added imap STATUS command test 2013-04-29 12:53:09 +01:00
Steve Holme
f317ffb7bb tests: Corrected the SMTP tests to be RFC2821 compliant
The emails that are sent to the server during these tests were
incorrectly formatted as they contained one or more LF terminated lines
rather than being CRLF terminated as per Section 2.3.7 of RFC-2821.

This wasn't a problem for the test suite as the <stdin> data matched the
<upload> data but anyone using these tests as reference would be sending
incorrect data to a server.
2013-04-28 16:14:58 +01:00
Steve Holme
9ea5145952 email: Tidy up of *_perform_authenticate()
Removed the hard returns from imap and pop3 by using the same style for
sending the authentication string as smtp. Moved the "Other mechanisms
not supported" check in smtp to match that of imap and pop3 to provide
consistency between the three email protocols.
2013-04-28 12:57:42 +01:00
Steve Holme
1d7c38e1f0 smtp: Updated limit check to be more readable like the check in pop3 2013-04-28 12:26:44 +01:00
Steve Holme
18bfc8f2d7 pop3: Added 255 octet limit check when sending initial response
Added 255 octet limit check as per Section 4. Paragraph 8 of RFC-5034.
2013-04-28 12:26:11 +01:00
Steve Holme
945246988d DOCS: Corrected line length of recent Secure Transport changes 2013-04-28 12:17:15 +01:00
Nick Zitzmann
a5c0e20939 darwinssl: add TLS crypto authentication
Users using the Secure Transport (darwinssl) back-end can now use a
certificate and private key to authenticate with a site using TLS. Because
Apple's security system is based around the keychain and does not have any
non-public function to create a SecIdentityRef data structure from data
loaded outside of the Keychain, the certificate and private key have to be
loaded into the Keychain first (using the certtool command line tool or
the Security framework's C API) before we can find it and use it.
2013-04-27 23:15:07 -06:00
Steve Holme
128517649c Corrected version numbers after bump 2013-04-27 23:02:20 +01:00
Daniel Stenberg
219358b93d bump version
Since we're adding new stuff, the next release will bump the minor
version and we're looking forward to 7.31.0
2013-04-27 23:15:35 +02:00
Steve Holme
f133719f73 RELEASE-NOTES: synced with f4e6e201b1 2013-04-27 20:43:55 +01:00
Steve Holme
f4e6e201b1 DOCS: Updated following the addition of CURLOPT_SASL_IR
Documented the the option in curl_easy_setopt() and added it to
symbols-in-versions.
2013-04-27 17:08:08 +01:00
Steve Holme
790b2086d7 tests: Corrected command line arguments in test907 and test908 2013-04-27 16:36:17 +01:00
Steve Holme
f9b691cdb0 tests: Added SMTP AUTH with initial response tests 2013-04-27 13:04:02 +01:00
Steve Holme
4118c30261 tests: Updated SMTP tests to decouple client initial response
Updated test903 and test904 following the addition of CURLOPT_SASL_IR
as the default behaviour of SMTP AUTH responses is now to not include
the initial response. New tests with --sasl-ir support to follow.
2013-04-27 12:32:27 +01:00
Steve Holme
dacbdaab94 imap: Added support for overriding the SASL initial response
In addition to checking for the SASL-IR capability the user can override
the sending of the client's initial response in the AUTHENTICATION
command with the use of CURLOPT_SASL_IR should the server erroneously
not report SASL-IR when it does support it.
2013-04-27 12:12:59 +01:00
Steve Holme
70e30f6caa smtp: Added support for disabling the SASL initial response
Updated the default behaviour of sending the client's initial response in the AUTH
command to not send it and added support for CURLOPT_SASL_IR to allow the user to
specify including the response.

Related Bug: http://curl.haxx.se/mail/lib-2012-03/0114.html
Reported-by: Gokhan Sengun
2013-04-27 12:09:15 +01:00
Steve Holme
7cb6c31370 pop3: Added support for enabling the SASL initial response
Allowed the user to specify whether to send the client's intial response
in the AUTH command via CURLOPT_SASL_IR.
2013-04-27 12:07:39 +01:00
Steve Holme
5d3a031ca7 sasl-ir: Added --sasl-ir option to curl command line tool 2013-04-27 10:03:10 +01:00
Steve Holme
a846fbbe2a sasl-ir: Added CURLOPT_SASL_IR to enable/disable the SASL initial response 2013-04-27 09:58:20 +01:00
Daniel Stenberg
6420672879 curl_easy_init: use less mallocs
By introducing an internal alternative to curl_multi_init() that accepts
parameters to set the hash sizes, easy handles will now use tiny socket
and connection hash tables since it will only ever add a single easy
handle to that multi handle.

This decreased the number mallocs in test 40 (which is a rather simple
and typical easy interface use case) from 1142 to 138. The maximum
amount of memory allocated used went down from 118969 to 78805.
2013-04-26 22:55:55 +02:00
Steve Holme
c4067a5678 ftpserver.pl: Fixed imap logout confirmation data
An IMAP server should response with the BYE continuation response before
confirming the LOGOUT command was successful.
2013-04-26 21:12:36 +01:00
Daniel Stenberg
0523152ad6 ftp_state_pasv_resp: connect through proxy also when set by env
When connecting back to an FTP server after having sent PASV/EPSV,
libcurl sometimes didn't use the proxy properly even though the proxy
was used for the initial connect.

The function wrongly checked for the CURLOPT_PROXY variable to be set,
which made it act wrongly if the proxy information was set with an
environment variable.

Added test case 711 to verify (based on 707 which uses --socks5). Also
added test712 to verify another variation of setting the proxy: with
--proxy socks5://

Bug: http://curl.haxx.se/bug/view.cgi?id=1218
Reported-by: Zekun Ni
2013-04-26 16:49:25 +02:00
Zdenek Pavlas
b37b5233ca url: initialize speed-check data for file:// protocol
... in order to prevent an artificial timeout event based on stale
speed-check data from a previous network transfer.  This commit fixes
a regression caused by 9dd85bced5.

Bug: https://bugzilla.redhat.com/906031
2013-04-26 15:38:22 +02:00
Daniel Stenberg
c68c7e588e test709: clarify the test in the name 2013-04-25 23:42:38 +02:00
Daniel Stenberg
1498a0073e sshserver: disable StrictHostKeyChecking
I couldn't figure out why the host key logic isn't working, but having
it set to yes prevents my SSH-based test cases to run. I also don't see
a strong need to use strict host key checking on this test server.

So I disabled it.
2013-04-25 23:40:31 +02:00
Daniel Stenberg
27777949a0 runtests: log more commands in verbose mode
... to aid tracking down failures
2013-04-25 23:40:01 +02:00
Steve Holme
4dc2d965d6 TODO: Corrected copy/paste typo 2013-04-25 20:18:08 +01:00
Steve Holme
70bbbccc39 TODO: Added new ideas for future SMTP, POP3 and IMAP features 2013-04-25 20:10:09 +01:00
Steve Holme
0dd470fc61 TODO: Updated following the addition of ;auth=<MECH> support 2013-04-25 19:48:34 +01:00
Steve Holme
89acdf50fa DOCS: Minor rewording / clarification of host name protocol detection 2013-04-25 13:30:17 +01:00
Steve Holme
c0d502785f RELEASE-NOTES: synced with a8c92cb608 2013-04-24 19:40:06 +01:00
Steve Holme
a8c92cb608 DOCS: Added reference to IETF draft for SMTP URL Interface
...when mentioning login options. Additional minor clarification of
"Windows builds" to be "Windows builds with SSPI"as a way of enabling
NTLM as Windows builds may be built with OpenSSL to enable NTLM or
without NTLM support altogether.
2013-04-24 19:35:38 +01:00
Linus Nielsen Feltzing
53fda844cc HISTORY: Fix spelling error. 2013-04-23 21:41:38 +02:00
Steve Holme
bbf63b0faa DOCS: Reworked the scheme calculation explanation under CURLOPT_URL 2013-04-23 19:57:58 +01:00
Steve Holme
2af9fd4960 url: Added smtp and pop3 hostnames to the protocol detection list 2013-04-23 19:44:14 +01:00
Daniel Stenberg
2c0d65785f HISTORY: correct some years/dates
Thanks to archive.org's wayback machine I updated this document with
some facts from the early httpget/urlget web page:

http://web.archive.org/web/19980216125115/http://www.inf.ufrgs.br/~sagula/urlget.html
2013-04-23 16:21:29 +02:00
Alessandro Ghedini
d791179d7f tests: add test1511 to check timecond clean-up
Verifies the timecond fix in commit c49ed0b6c0
2013-04-22 22:46:47 +02:00
Alessandro Ghedini
c49ed0b6c0 getinfo.c: reset timecond when clearing session-info variables
Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=705783
Reported-by: Ludovico Cavedon <cavedon@debian.org>
2013-04-22 22:43:32 +02:00
Steve Holme
868d8e6831 DOCS: Added information about login options to CURLOPT_USERPWD 2013-04-22 20:22:12 +01:00
Steve Holme
e3aca1b2ce DOCS: Added information about login options in the URL 2013-04-22 20:22:10 +01:00
Steve Holme
ddac43b38e url: Fixed missing length check in parse_proxy()
Commit 11332577b3 removed the length check that was performed by the
old scanf() code.
2013-04-21 18:29:33 +01:00
Steve Holme
416ecc1584 url: Fixed crash when no username or password supplied for proxy
Fixed an issue in parse_proxy(), introduced in commit 11332577b3,
where an empty username or password (For example: http://:@example.com)
would cause a crash.
2013-04-21 16:55:19 +01:00
Steve Holme
455ba691a7 url: Removed unused text length constants 2013-04-21 12:16:12 +01:00
Steve Holme
11332577b3 url: Updated proxy URL parsing to use parse_login_details() 2013-04-21 12:12:29 +01:00
Steve Holme
702b0dd408 url: Tidy up of setstropt_userpwd() parameters
Updated the naming convention of the login parameters to match those of
other functions.
2013-04-21 10:27:42 +01:00
Steve Holme
e8a9f794f0 url: Tidy up of code and comments following recent changes
Tidy up of variable names and comments in setstropt_userpwd() and
parse_login_details().
2013-04-21 10:23:47 +01:00
Steve Holme
bddf3d4705 url: Simplified setstropt_userpwd() following recent changes
There is no need to perform separate clearing of data if a NULL option
pointer is passed in. Instead this operation can be performed by simply
not calling parse_login_details() and letting the rest of the code do
the work.
2013-04-20 20:04:00 +01:00
Steve Holme
e99c81a07c url: Correction to scope of if statements when setting data 2013-04-20 19:10:10 +01:00
Steve Holme
fe880475ed url: Fixed memory leak in setstropt_userpwd()
setstropt_userpwd() was calling setstropt() in commit fddb7b44a7 to
set each of the login details which would duplicate the strings and
subsequently cause a memory leak.
2013-04-20 18:40:13 +01:00
Steve Holme
5821d5f111 RELEASE-NOTES: synced with d535c4a2e1 2013-04-20 09:56:16 +01:00
Steve Holme
d535c4a2e1 url: Added overriding of URL login options from CURLOPT_USERPWD 2013-04-20 09:18:51 +01:00
Steve Holme
ca8f17a303 tool_paramhlp: Fixed options being included in username
Fix to prevent the options from being displayed when curl requests the
user's password if the following command line is specified:

--user username;options
2013-04-20 09:16:21 +01:00
Steve Holme
fddb7b44a7 url: Added support for parsing login options from the CURLOPT_USERPWD
In addition to parsing the optional login options from the URL, added
support for parsing them from CURLOPT_USERPWD, to allow the following
supported command line:

--user username:password;options
2013-04-20 09:08:28 +01:00
Steve Holme
49184c3723 url: Added bounds checking to parse_login_details()
Added bounds checking when searching for the separator characters within
the login string as this string may not be NULL terminated (For example
it is the login part of a URL). We do this in preference to allocating a
new string to copy the login details into which could then be passed to
parse_login_details() for performance reasons.
2013-04-19 19:37:55 +01:00
Steve Holme
cc7f6a2ddf url: Added size_t cast to pointer based length calculations 2013-04-19 14:11:43 +01:00
Steve Holme
90fe59b829 url: Corrected minor typo in comment 2013-04-19 12:53:59 +01:00
Daniel Stenberg
7b074a460b CURL_CHECK_CA_BUNDLE: don't check for paths when cross-compiling
When cross-compiling we can't scan and detect existing files or paths.

Bug: http://curl.haxx.se/mail/lib-2013-04/0294.html
2013-04-18 23:37:56 +02:00
Ishan SinghLevett
993cdcd6ee usercertinmem.c: add example showing user cert in memory
Relies on CURLOPT_SSL_CTX_FUNCTION, which is OpenSSL specific
2013-04-18 23:07:15 +02:00
Steve Holme
8763374f0e url: Fix chksrc longer than 79 columns warning 2013-04-18 20:21:11 +01:00
Steve Holme
63388fe1f3 url: Fix incorrect variable type for result code 2013-04-18 19:18:02 +01:00
Steve Holme
b75a88aa72 url: Fix compiler warning
signed and unsigned type in conditional expression
2013-04-18 19:14:25 +01:00
Steve Holme
bb20989a63 url: Moved parsing of login details out of parse_url_login()
Separated the parsing of login details from the processing of them in
parse_url_login() ready for use by setstropt_userpwd().
2013-04-18 18:09:53 +01:00
Steve Holme
0d49e408a4 url: Re-factored set_userpass() and parse_url_userpass()
Re-factored these functions to reflect their new behaviour following the
addition of login options.
2013-04-18 17:36:15 +01:00
Steve Holme
90c87f311e url: Reworked URL parsing to allow overriding by CURLOPT_USERPWD 2013-04-18 17:20:43 +01:00
Daniel Stenberg
da06ac7f3f maketgz: make bzip2 creation work with Parallel BZIP2 too
Apparently the previous usage didn't work with that implementation,
while this updated version works with at least both Parallel BZIP2
v1.1.8 and regular bzip "Version 1.0.6, 6-Sept-2010".
2013-04-18 11:13:56 +02:00
Linus Nielsen Feltzing
6d9236e805 Add tests/http_pipe.py to the tarball build 2013-04-18 10:55:41 +02:00
Steve Holme
c306d2e42f smtp: Re-factored all perform based functions
Standardised the naming of all perform based functions to be in the form
smtp_perform_something().
2013-04-16 19:48:20 +01:00
Steve Holme
f737e3a3dd smtp: Added description comments to all perform based functions 2013-04-16 19:44:53 +01:00
Steve Holme
686586b0f9 smtp: Moved smtp_quit() to be with the other perform functions 2013-04-16 19:44:52 +01:00
Steve Holme
e621a5f6ea smtp: Moved smtp_rcpt_to() to be with the other perform functions 2013-04-16 19:44:49 +01:00
Steve Holme
8093f9541e smtp: Moved smtp_mail() to be with the other perform functions 2013-04-16 19:44:47 +01:00
Wouter Van Rooy
68e7fb499d curl-config: don't output static libs when they are disabled
Curl-config outputs static libraries even when they are disabled in
configure.

This causes problems with the build of pycurl.
2013-04-16 16:07:41 +02:00
Dave Reisner
d9569720dd docs/libcurl: fix formatting in manpage
Commit c3ea3eb6 introduced some minor cosmetic errors in
curl_mutli_socket_action(3).
2013-04-16 09:52:12 +02:00
Paul Howarth
1c40685d32 Add extra libs for lib1900 and lib2033 test programs
These are needed in cases where clock_gettime is used, from librt.
2013-04-15 23:06:10 +02:00
Dan Fandrich
31c6e7af6a FAQ: mention that the network connection can be monitored
Also note the prohibition on sharing handles across threads.
2013-04-15 22:26:18 +02:00
Steve Holme
552ba67bb1 pop3: Added missing comment for pop3_state_apop_resp() 2013-04-15 20:27:49 +01:00
Steve Holme
651254dcc7 smtp: Updated the coding style of smtp_state_servergreet_resp()
Updated the coding style, in this function, to be consistant with other
response functions rather then performing a hard return on failure.
2013-04-15 20:27:47 +01:00
Steve Holme
26bdafcbf9 pop3: Updated the coding style of pop3_state_servergreet_resp()
Updated the coding style, in this function, to be consistent with other
response functions rather then performing a hard return on failure.
2013-04-15 20:27:45 +01:00
Steve Holme
02dc9e788f pop3: Re-factored all perform based functions
Standardised the naming of all perform based functions to be in the form
pop3_perform_something() following the changes made to IMAP.
2013-04-14 10:06:10 +01:00
Steve Holme
e11c6e9961 pop3: Added description comments to all perform based functions 2013-04-14 10:06:08 +01:00
Steve Holme
e4eaa92728 pop3: Moved pop3_quit() to be with the other perform functions 2013-04-14 10:06:07 +01:00
Steve Holme
577f8e5ac6 pop3: Moved pop3_command() to be with the other perform functions
Started to apply the same tidy up to the POP3 code as applied to the
IMAP code in the 7.30.0 release.
2013-04-14 10:06:05 +01:00
Steve Holme
95ba6cdd54 RELEASE-NOTES: Removed erroneous spaces 2013-04-13 18:35:16 +01:00
Steve Holme
7ce6cb9ab4 RELEASE-NOTES: synced with 8723cade21 2013-04-13 16:43:30 +01:00
Steve Holme
8723cade21 smtp: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication mechanism in
the URL as per Internet-Draft 'draft-earhart-url-smtp-00'.
2013-04-13 16:23:00 +01:00
Steve Holme
d956d9db47 pop3: Reworked authentication type constants
... to use left-shifted values, like those defined in curl.h, rather
than 16-bit hexadecimal values.
2013-04-13 16:20:48 +01:00
Steve Holme
ecf93ac986 pop3: Small consistency tidy up 2013-04-13 16:16:23 +01:00
Steve Holme
b3a01be2f3 pop3: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication type and SASL
mechanism in the URL as per RFC-2384.
2013-04-13 16:16:21 +01:00
Steve Holme
00045a3009 imap: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication mechanism in
the URL as per RFC-5092.
2013-04-13 16:11:27 +01:00
Steve Holme
3f7188dd94 sasl: Reworked SASL mechanism constants
... to use left-shifted values, like those defined in curl.h, rather
than 16-bit hexadecimal values.
2013-04-13 13:29:50 +01:00
Steve Holme
720218fea1 sasl: Added predefined preferred mechanism values
In preparation for the upcoming changes to IMAP, POP3 and SMTP added
preferred mechanism values.
2013-04-13 13:11:37 +01:00
Steve Holme
73aa95592f url: Added support for parsing login options from the URL
As well as parsing the username and password from the URL, added support
for parsing the optional options part from the login details, to allow
the following supported URL format:

schema://username:password;options@example.com/path?q=foobar

This will only be used by IMAP, POP3 and SMTP at present but any
protocol that may be given login options in the URL will be able to
add support for them.
2013-04-13 10:49:42 +01:00
Steve Holme
ad3fdbc0a4 smtp: Fix compiler warning
warning: unused variable 'smtp' introduced in commit 73cbd21b5e.
2013-04-13 00:06:19 +01:00
Steve Holme
73cbd21b5e smtp: Moved parsing of url path into separate function 2013-04-12 23:15:51 +01:00
Daniel Stenberg
c5ba0c2f54 FTP: handle a 230 welcome response
...instead of the 220 we otherwise expect.

Made the ftpserver.pl support sending a custom "welcome" and then
created test 1219 to verify this fix with such a 230 welcome.

Bug: http://curl.haxx.se/mail/lib-2013-02/0102.html
Reported by: Anders Havn
2013-04-12 23:59:37 +02:00
Daniel Stenberg
edddf394b8 configure: try pthread_create without -lpthread
For libc variants without a spearate pthread lib (like bionic), try
using pthreads without the pthreads lib first and only if that fails try
the -lpthread linker flag.

Bug: http://curl.haxx.se/bug/view.cgi?id=1216
Reported by: Duncan
2013-04-12 22:58:28 +02:00
Daniel Stenberg
61d259f950 FTP: access files in root dir correctly
Accessing a file with an absolute path in the root dir but with no
directory specified was not handled correctly. This fix comes with four
new test cases that verify it.

Bug: http://curl.haxx.se/mail/lib-2013-04/0142.html
Reported by: Sam Deane
2013-04-12 22:43:13 +02:00
Steve Holme
c01735865f pop3: Reworked the function description for Curl_pop3_write() 2013-04-12 20:22:14 +01:00
Steve Holme
ca46c5dbe2 pop3: Added function description to pop3_parse_custom_request() 2013-04-12 20:22:12 +01:00
Steve Holme
2da127abb5 pop3: Moved utility functions to end of pop3.c 2013-04-12 20:22:10 +01:00
Nick Zitzmann
bc33f2200d darwinssl: add TLS session resumption
This ought to speed up additional TLS handshakes, at least in theory.
2013-04-12 12:20:10 -06:00
Steve Holme
fd399cde00 imap: Added function description to imap_parse_custom_request() 2013-04-12 18:27:51 +01:00
Steve Holme
00c74019f4 imap: Moved utility functions to end of imap.c (Part 3/3)
Moved imap_is_bchar() be with the other utility based functions.
2013-04-12 18:24:46 +01:00
Steve Holme
9d0063befa imap: Moved utility functions to end of imap.c (Part 2/3)
Moved imap_parse_url_path() and imap_parse_custom_request() to the end of the
file allowing all utility functions to be grouped together.
2013-04-12 18:24:44 +01:00
Steve Holme
01e55ebb26 imap: Moved utility functions to end of imap.c (Part 1/3)
Moved imap_atom() and imap_sendf() to the end of the file allowing all
utility functions to be grouped together.
2013-04-12 18:24:43 +01:00
Steve Holme
4bbad1dac7 imap: Corrected function description for imap_connect() 2013-04-12 18:14:43 +01:00
Kamil Dudka
ddbda328b3 tests: prevent test206, test1060, and test1061 from failing
... in case runtests.pl is invoked with non-default -b option

Fixes a regression caused by 1e29d275c6.
2013-04-12 14:25:58 +02:00
David Strauss
8ffbeeda80 libcurl-share.3: update what it does and does not share.
Update sharing interface documentation to provide exhaustive list of
what it does and does not share.
2013-04-12 13:35:29 +02:00
Daniel Stenberg
1d1ffaf912 THANKS: remove duplicated names 2013-04-12 12:37:47 +02:00
Daniel Stenberg
e0cff02061 bump: start working towards next release 2013-04-12 11:30:32 +02:00
Daniel Stenberg
7fe95bb0d5 THANKS: added people from the 7.30.0 RELEASE-NOTES 2013-04-12 11:30:12 +02:00
301 changed files with 17123 additions and 3118 deletions

View File

@@ -103,7 +103,7 @@ if test ! -z $SDK32; then
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
cd Versions
ln -fs ${FRAMEWORK_VERSION} Current
ln -fs $(basename "${FRAMEWORK_VERSION}") Current
echo Testing for SDK64
if test -d $SDK64_DIR; then

View File

@@ -148,12 +148,24 @@ vc-ssl-zlib: $(VC)
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
vc-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl-zlib
vc-x64-ssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
vc-x64-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib
vc-ssl-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-dll

View File

@@ -1,11 +1,11 @@
Curl and libcurl 7.30.0
Curl and libcurl 7.32.0
Public curl releases: 132
Public curl releases: 134
Command line options: 152
curl_easy_setopt() options: 199
Public functions in libcurl: 58
Known libcurl bindings: 42
Contributors: 1005
Contributors: 1049
***
krb4 support is up for removal. If you care about it at all, speak up
@@ -14,75 +14,56 @@ Curl and libcurl 7.30.0
This release includes the following changes:
o imap: Changed response tag generation to be completely unique
o imap: Added support for SASL-IR extension
o imap: Added support for the list command
o imap: Added support for the append command
o imap: Added custom request parsing
o imap: Added support to the fetch command for UID and SECTION properties
o imap: Added parsing and verification of the UIDVALIDITY mailbox attribute
o darwinssl: Make certificate errors less techy
o imap/pop3/smtp: Added support for the STARTTLS capability
o checksrc: ban use of sprintf, vsprintf, strcat, strncat and gets
o curl_global_init() now accepts the CURL_GLOBAL_ACK_EINTR flag [10]
o Added CURLMOPT_MAX_HOST_CONNECTIONS, CURLMOPT_MAX_TOTAL_CONNECTIONS for
new multi interface connection handling
o Added CURLMOPT_MAX_PIPELINE_LENGTH, CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE,
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLMOPT_PIPELINING_SITE_BL and
CURLMOPT_PIPELINING_SERVER_BL for new pipelining control [15]
o curl: allow timeouts to accept decimal values
o OS400: add slist and certinfo EBCDIC support
o OS400: new SSL backend GSKit
o CURLOPT_XFERINFOFUNCTION: introducing a new progress callback
o LIBCURL-STRUCTS: new document
This release includes the following bugfixes:
o SECURITY ADVISORY: cookie tailmatching to avoid cross-domain leakage [25]
o darwinssl: Fix build under Leopard
o DONE: consider callback-aborted transfers premature [1]
o ntlm: Fixed memory leaks
o smtp: Fixed an issue when processing EHLO failure responses
o pop3: Fixed incorrect return value from pop3_endofresp()
o pop3: Fixed SASL authentication capability detection
o pop3: Fixed blocking SSL connect when connecting via POP3S
o imap: Fixed memory leak when performing multiple selects
o nss: fix misplaced code enabling non-blocking socket mode
o AddFormData: prevent only directories from being posted [2]
o darwinssl: fix infinite loop if server disconnected abruptly [3]
o metalink: fix improbable crash parsing metalink filename
o show proper host name on failed resolve
o MacOSX-Framework: Make script work in Xcode 4.0 and later
o strlcat: remove function [4]
o darwinssl: Fix send glitchiness with data > 32 or so KB [5]
o polarssl: better 1.1.x and 1.2.x support
o various documentation improvements
o multi: NULL pointer reference when closing an unused multi handle [9]
o SOCKS: fix socks proxy when noproxy matched [7]
o install-sh: updated to support multiple source files as arguments [6]
o PolarSSL: added human readable error strings
o resolver_error: remove wrong error message output
o docs: updates HTML index and general improvements
o curlbuild.h.dist: enhance non-configure GCC ABI detection logic
o sasl: Fixed null pointer reference when decoding empty digest challenge [8]
o easy: do not ignore poll() failures other than EINTR
o darwinssl: disable ECC ciphers under Mountain Lion by default
o CONNECT: count received headers [11]
o build: fixes for VMS
o CONNECT: clear 'rewindaftersend' on success [12]
o HTTP proxy: insert slash in URL if missing [13]
o hiperfifo: updated to use current libevent API [14]
o getinmemory.c: abort the transfer nicely if not enough memory
o improved win32 memorytracking
o corrected proxy header response headers count [16]
o FTP quote operations on re-used connection [17]
o tcpkeepalive on win32 [18]
o tcpkeepalive on Mac OS X [23]
o easy: acknowledge the CURLOPT_MAXCONNECTS option properly [19]
o easy interface: restore default MAXCONNECTS to 5
o win32: don't set SO_SNDBUF for windows vista or later versions [20]
o HTTP: made cookie sort function more deterministic
o winssl: Fixed memory leak if connection was not successful
o FTP: wait on both connections during active STOR state [21]
o connect: treat a failed local bind of an interface as a non-fatal error [22]
o darwinssl: disable insecure ciphers by default
o FTP: handle "rubbish" in front of directory name in 257 responses [24]
o mk-ca-bundle: Fixed lost OpenSSL output with "-t"
o dotdot: introducing dot file path cleanup [1]
o docs: fix typo in curl_easy_getinfo manpage
o test1230: avoid using hard-wired port number
o test1396: invoke the correct test tool
o SIGPIPE: ignored while inside the library [2]
o darwinssl: fix crash that started happening in Lion
o OpenSSL: check for read errors, don't assume [3]
o c-ares: improve error message on failed resolve [4]
o printf: make sure %x are treated unsigned
o formpost: better random boundaries [5]
o url: restore the functionality of 'curl -u :' [6]
o curl.1: fix typo in --xattr description [7]
o digest: improve nonce generation
o configure: automake 1.14 compatibility tweak
o curl.1: document the --post303 option in the man page
o curl.1: document the --sasl-ir option in the man page
o setup-vms.h: sk_pop symbol tweak
o tool_paramhlp: try harder to catch negatives
o cmake: Fix for MSVC2010 project generation [8]
o asyn-ares: Don't blank ares servers if none configured
o curl_multi_wait: set revents for extra fds
o Reinstate "WIN32 MemoryTracking: track wcsdup() _wcsdup() and _tcsdup()
o ftp_do_more: consider DO_MORE complete when server connects back [9]
o curl_easy_perform: gradually increase the delay time [10]
o curl: fix symbolic names for CURLUSESSL_* enum in --libcurl output
o curl: fix upload of a zip file in OpenVMS [11]
o build: fix linking on Solaris 10 [12]
o curl_formadd: CURLFORM_FILECONTENT wrongly rejected some option combos [13]
o curl_formadd: fix file upload on VMS [14]
o curl_easy_pause: on unpause, trigger mulit-socket handling [15]
o md5 & metalink: use better build macros on Apple operating systems [16]
o darwinssl: fix build error in crypto authentication under Snow Leopard [16]
o curl: make --progress-bar update the line less frequently [17]
o configure: don't error out on variable confusions (CFLAGS, LDFLAGS etc)
o mk-ca-bundle: skip more untrusted certificates
o formadd: wrong pointer for file name when CURLFORM_BUFFERPTR used [18]
o FTP: when EPSV gets a 229 but fails to connect, retry with PASV
o mk-ca-bundle.1: don't install on make install [19]
o VMS: lots of updates and fixes of the build procedure
o global dns cache: didn't work (regression)
o global dns cache: fix memory leak
o
This release includes the following known bugs:
@@ -91,43 +72,34 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Kamil Dudka, Steve Holme, Nick Zitzmann, Patricia Muscalu, Dan Fandrich,
Gisle Vanem, Guenter Knauf, Yang Tse, Oliver Gondža, Aki Koskinen,
Alexander Klauer, Kim Vandry, Willem Sparreboom, Jeremy Huddleston,
Bruno de Carvalho, Rainer Jung, Jeremy Huddleston, Kim Vandry, Jiri Hruska,
Alexander Klauer, Saran Neti, Alessandro Ghedini, Linus Nielsen Feltzing,
Martin Jansen, John E. Malmberg, Tom Grace, Patrick Monnerat,
Zdenek Pavlas, Myk Taylor, Cédric Deltheil, Robert Wruck, Sam Deane,
Clemens Gruber, Marc Hoersken, Tomas Mlcoch, Fredrik Thulin, Steven Gu,
Andrew Kurushin, Christian Hägele, Daniel Theron, Bill Middlecamp,
Richard Michael, Yamada Yasuharu
Alex Vinnik, Alessandro Ghedini, Nick Zitzmann, Kamil Dudka,
Lluis Batlle i Rossell, Nach M. S., Kim Vandry, Ben Greear, Dan Fandrich,
Dave Reisner, Evgeny Turnaev, Guenter Knauf, John E. Malmberg, Marc Hoersken,
Patrick Monnerat, Sergei Nikulov, Yang Tse, Andreas Malzahn, Clemens Gruber,
Jean-Noel Rouvignac, Markus Moeller, Fabian Keil, Dagobert Michelsen,
Byrial Jensen, Justin Karneges, Edward Rudd, Marc Doughty, Konstantin Isakov,
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = http://curl.haxx.se/bug/view.cgi?id=1184
[2] = http://curl.haxx.se/mail/archive-2013-02/0040.html
[3] = http://curl.haxx.se/mail/lib-2013-03/0014.html
[4] = http://curl.haxx.se/bug/view.cgi?id=1192
[5] = http://curl.haxx.se/mail/lib-2013-02/0145.html
[6] = http://curl.haxx.se/bug/view.cgi?id=1195
[7] = http://curl.haxx.se/bug/view.cgi?id=1190
[8] = http://curl.haxx.se/bug/view.cgi?id=1193
[9] = http://curl.haxx.se/bug/view.cgi?id=1194
[10] = http://curl.haxx.se/bug/view.cgi?id=1168
[11] = http://curl.haxx.se/bug/view.cgi?id=1204
[12] = https://groups.google.com/d/msg/msysgit/B31LNftR4BI/KhRTz0iuGmUJ
[13] = http://curl.haxx.se/bug/view.cgi?id=1206
[14] = http://curl.haxx.se/bug/view.cgi?id=1199
[15] = http://daniel.haxx.se/blog/2013/03/26/better-pipelining-in-libcurl-7-30-0/
[16] = http://curl.haxx.se/bug/view.cgi?id=1204
[17] = http://curl.haxx.se/mail/lib-2013-03/0319.html
[18] = http://curl.haxx.se/bug/view.cgi?id=1209
[19] = http://curl.haxx.se/bug/view.cgi?id=1212
[20] = http://curl.haxx.se/bug/view.cgi?id=1188
[21] = http://curl.haxx.se/bug/view.cgi?id=1183
[22] = http://curl.haxx.se/bug/view.cgi?id=1189
[23] = http://curl.haxx.se/bug/view.cgi?id=1214
[24] = http://curl.haxx.se/mail/lib-2013-04/0113.html
[25] = http://curl.haxx.se/docs/adv_20130412.html
[1] = http://curl.haxx.se/bug/view.cgi?id=1200
[2] = http://curl.haxx.se/bug/view.cgi?id=1180
[3] = http://curl.haxx.se/bug/view.cgi?id=1249
[4] = http://curl.haxx.se/bug/view.cgi?id=1191
[5] = http://curl.haxx.se/bug/view.cgi?id=1251
[6] = http://curl.haxx.se/mail/archive-2013-06/0052.html
[7] = http://curl.haxx.se/bug/view.cgi?id=1252
[8] = http://curl.haxx.se/mail/lib-2013-07/0046.html
[9] = http://curl.haxx.se/mail/lib-2013-07/0115.html
[10] = http://curl.haxx.se/mail/lib-2013-07/0103.html
[11] = http://curl.haxx.se/bug/view.cgi?id=496
[12] = http://curl.haxx.se/bug/view.cgi?id=1217
[13] = http://curl.haxx.se/mail/lib-2013-07/0258.html
[14] = http://curl.haxx.se/bug/view.cgi?id=758
[15] = http://curl.haxx.se/mail/lib-2013-07/0239.html
[16] = http://curl.haxx.se/bug/view.cgi?id=1255
[17] = http://curl.haxx.se/mail/archive-2013-07/0031.html
[18] = http://curl.haxx.se/bug/view.cgi?id=1262
[19] = http://curl.haxx.se/mail/lib-2013-08/0057.html

View File

@@ -2619,8 +2619,10 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
fi
capath="$want_capath"
ca="no"
else
dnl neither of --with-ca-* given
elif test "x$cross_compiling" != "xyes"; then
dnl NOT cross-compiling and...
dnl neither of the --with-ca-* options are provided
dnl first try autodetecting a CA bundle , then a CA path
dnl both autodetections can be skipped by --without-ca-*
ca="no"
@@ -2656,10 +2658,11 @@ AC_HELP_STRING([--without-ca-path], [Don't use a default CA path]),
fi
done
fi
else
dnl no option given and cross-compiling
AC_MSG_WARN([skipped the ca-cert path detection when cross-compiling])
fi
if test "x$ca" != "xno"; then
CURL_CA_BUNDLE='"'$ca'"'
AC_DEFINE_UNQUOTED(CURL_CA_BUNDLE, "$ca", [Location of default ca bundle])

View File

@@ -126,7 +126,7 @@ fi
dnl figure out the libcurl version
CURLVERSION=`$SED -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' ${srcdir}/include/curl/curlver.h`
XC_CHECK_PROG_CC
AM_INIT_AUTOMAKE
XC_AUTOMAKE
AC_MSG_CHECKING([curl version])
AC_MSG_RESULT($CURLVERSION)
@@ -3158,14 +3158,26 @@ if test "$want_thres" = "yes"; then
AC_CHECK_HEADER(pthread.h,
[ AC_DEFINE(HAVE_PTHREAD_H, 1, [if you have <pthread.h>])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pthread"
AC_CHECK_LIB(pthread, pthread_create,
[ AC_MSG_NOTICE([using POSIX threaded DNS lookup])
AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup])
USE_THREADS_POSIX=1
curl_res_msg="threaded"
],
[ CFLAGS="$save_CFLAGS"])
dnl first check for function without lib
AC_CHECK_FUNC(pthread_create, [USE_THREADS_POSIX=1] )
dnl if it wasn't found without lib, search for it in pthread lib
if test "$USE_THREADS_POSIX" != "1"
then
CFLAGS="$CFLAGS -pthread"
AC_CHECK_LIB(pthread, pthread_create,
[USE_THREADS_POSIX=1],
[ CFLAGS="$save_CFLAGS"])
fi
if test "x$USE_THREADS_POSIX" = "x1"
then
AC_DEFINE(USE_THREADS_POSIX, 1, [if you want POSIX threaded DNS lookup])
curl_res_msg="POSIX threaded"
fi
])
fi
@@ -3338,6 +3350,11 @@ dnl yes or no
ENABLE_SHARED="$enable_shared"
AC_SUBST(ENABLE_SHARED)
dnl to let curl-config output the static libraries correctly
ENABLE_STATIC="$enable_static"
AC_SUBST(ENABLE_STATIC)
dnl
dnl For keeping supported features and protocols also in pkg-config file
dnl since it is more cross-compile friendly than curl-config
@@ -3514,6 +3531,8 @@ AC_OUTPUT
CURL_GENERATE_CONFIGUREHELP_PM
XC_AMEND_DISTCLEAN([lib src tests/unit tests/server tests/libtest docs/examples])
AC_MSG_NOTICE([Configured to build curl/libcurl:
curl version: ${CURLVERSION}

View File

@@ -155,7 +155,12 @@ while test $# -gt 0; do
;;
--static-libs)
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
if test "X@ENABLE_STATIC@" != "Xno" ; then
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
else
echo "curl was built with static libraries disabled" >&2
exit 1
fi
;;
--configure)

View File

@@ -79,9 +79,9 @@
1.3 What To Read
Source code, the man pages, the INTERNALS document, TODO, KNOWN_BUGS, the
most recent CHANGES. Just lurking on the libcurl mailing list is gonna give
you a lot of insights on what's going on right now. Asking there is a good
idea too.
most recent CHANGES. Just lurking on the curl-library mailing list is gonna
give you a lot of insights on what's going on right now. Asking there is a
good idea too.
2. cURL Coding Standards
@@ -98,12 +98,12 @@
2.2 Indenting
Please try using the same indenting levels and bracing method as all the
other code already does. It makes the source code a lot easier to follow if
all of it is written using the same style. We don't ask you to like it, we
just ask you to follow the tradition! ;-) This mainly means: 2-level indents,
using spaces only (no tabs) and having the opening brace ({) on the same line
as the if() or while().
Use the same indenting levels and bracing method as all the other code
already does. It makes the source code easier to follow if all of it is
written using the same style. We don't ask you to like it, we just ask you to
follow the tradition! ;-) This mainly means: 2-level indents, using spaces
only (no tabs) and having the opening brace ({) on the same line as the if()
or while().
Also note that we use if() and while() with no space before the parenthesis.
@@ -151,6 +151,9 @@
description exactly what they correct so that all patches can be selectively
applied by the maintainer or other interested parties.
Also, separate patches enable bisecting much better when we track problems in
the future.
2.9 Patch Against Recent Sources
Please try to get the latest available sources to make your patches
@@ -178,6 +181,10 @@
test case that verifies that it works as documented. If every submitter also
posts a few test cases, it won't end up as a heavy burden on a single person!
If you don't have test cases or perhaps you have done something that is very
hard to write tests for, do explain exactly how you have otherwise tested and
verified your changes.
3. Pushing Out Your Changes
3.1 Write Access to git Repository

View File

@@ -728,7 +728,7 @@ FAQ
When passing on a URL to curl to use, it may respond that the particular
protocol is not supported or disabled. The particular way this error message
is phrased is because curl doesn't make a distinction internally of whether
a particular protocol is not supported (ie never got any code added that
a particular protocol is not supported (i.e. never got any code added that
knows how to speak that protocol) or if it was explicitly disabled. curl can
be built to only support a given set of protocols, and the rest would then
be disabled or not supported.
@@ -1055,11 +1055,11 @@ FAQ
4.19 Why doesn't cURL return an error when the network cable is unplugged?
Unplugging the cable is not an error situation. The TCP/IP protocol stack
Unplugging a cable is not an error situation. The TCP/IP protocol stack
was designed to be fault tolerant, so even though there may be a physical
break somewhere the connection shouldn't be affected, just possibly
delayed. Eventually, the physical break will be fixed or the data will be
re-routed around the physical problem.
re-routed around the physical problem through another path.
In such cases, the TCP/IP stack is responsible for detecting when the
network connection is irrevocably lost. Since with some protocols it is
@@ -1077,6 +1077,12 @@ FAQ
falls too low, and --connect-timeout and --max-time can be used to put an
overall timeout on the connection phase or the entire transfer.
A libcurl-using application running in a known physical environment (e.g.
an embedded device with only a single network connection) may want to act
immediately if its lone network connection goes down. That can be achieved
by having the application monitor the network connection on its own using an
OS-specific mechanism, then signalling libcurl to abort (see also item 5.13).
5. libcurl Issues
@@ -1086,7 +1092,9 @@ FAQ
We have written the libcurl code specifically adjusted for multi-threaded
programs. libcurl will use thread-safe functions instead of non-safe ones if
your system has such.
your system has such. Note that you must never share the same handle in
multiple threads.
If you use a OpenSSL-powered libcurl in a multi-threaded environment, you
need to provide one or two locking functions:

View File

@@ -7,19 +7,19 @@
How cURL Became Like This
In the second half of 1997, Daniel Stenberg came up with the idea to make
Towards the end of 1996, Daniel Stenberg came up with the idea to make
currency-exchange calculations available to Internet Relay Chat (IRC)
users. All the necessary data are published on the Web; he just needed to
automate their retrieval.
Daniel simply adopted an existing command-line open-source tool, httpget, that
Brazilian Rafael Sagula had written. After a few minor adjustments, it did
just what he needed.
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
a few minor adjustments, it did just what he needed. HttpGet 1.0 was released
on April 8th 1997 with brand new HTTP proxy support.
Soon, he found currencies on a GOPHER site, so support for that had to go in,
and not before long FTP download support was added as well. The name of the
project was changed to urlget to better fit what it actually did now, since
the http-only days were already passed.
We soon found and fixed support for getting currencies over GOPHER. Once FTP
download support was added, the name of the project was changed and urlget 2.0
was released in August 1997. The http-only days were already passed.
The project slowly grew bigger. When upload capabilities were added and the
name once again was misleading, a second name change was made and on March 20,

View File

@@ -220,7 +220,7 @@ Win32
adjust as necessary. It is also possible to override these paths with
environment variables, for example:
set ZLIB_PATH=c:\zlib-1.2.7
set ZLIB_PATH=c:\zlib-1.2.8
set OPENSSL_PATH=c:\openssl-0.9.8y
set LIBSSH2_PATH=c:\libssh2-1.4.3
@@ -323,7 +323,7 @@ Win32
documentation on how to compile zlib. Define the ZLIB_PATH environment
variable to the location of zlib.h and zlib.lib, for example:
set ZLIB_PATH=c:\zlib-1.2.7
set ZLIB_PATH=c:\zlib-1.2.8
Then run 'nmake vc-zlib' in curl's root directory.
@@ -1045,7 +1045,7 @@ PORTS
- Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1
- AVR32 Linux
- ARM Android 1.5, 2.1
- ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
- ARM INTEGRITY
- ARM iOS
- Cell Linux
@@ -1116,6 +1116,7 @@ GNU GSS http://www.gnu.org/software/gss/
GnuTLS http://www.gnu.org/software/gnutls/
Heimdal http://www.pdc.kth.se/heimdal/
libidn http://www.gnu.org/software/libidn/
libmetalink https://launchpad.net/libmetalink/
libssh2 http://www.libssh2.org/
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
NSS http://www.mozilla.org/projects/security/pki/nss/

View File

@@ -111,6 +111,9 @@ Windows vs Unix
Library
=======
(See LIBCURL-STRUCTS for a separate document describing all major internal
structs and their purposes.)
There are plenty of entry points to the library, namely each publicly defined
function that libcurl offers to applications. All of those functions are
rather small and easy-to-follow. All the ones prefixed with 'curl_easy' are
@@ -135,16 +138,18 @@ Library
options is documented in the man page. This function mainly sets things in
the 'SessionHandle' struct.
curl_easy_perform() does a whole lot of things:
curl_easy_perform() is just a wrapper function that makes use of the multi
API. It basically curl_multi_init(), curl_multi_add_handle(),
curl_multi_wait(), and curl_multi_perform() until the transfer is done and
then returns.
It starts off in the lib/easy.c file by calling Curl_perform() and the main
work then continues in lib/url.c. The flow continues with a call to
Curl_connect() to connect to the remote site.
Some of the most important key functions in url.c are called from multi.c
when certain key steps are to be made in the transfer operation.
o Curl_connect()
... analyzes the URL, it separates the different components and connects to
the remote host. This may involve using a proxy and/or using SSL. The
Analyzes the URL, it separates the different components and connects to the
remote host. This may involve using a proxy and/or using SSL. The
Curl_resolv() function in lib/hostip.c is used for looking up host names
(it does then use the proper underlying method, which may vary between
platforms and builds).
@@ -160,10 +165,7 @@ Library
o Curl_do()
Curl_do() makes sure the proper protocol-specific function is called. The
functions are named after the protocols they handle. Curl_ftp(),
Curl_http(), Curl_dict(), etc. They all reside in their respective files
(ftp.c, http.c and dict.c). HTTPS is handled by Curl_http() and FTPS by
Curl_ftp().
functions are named after the protocols they handle.
The protocol-specific functions of course deal with protocol-specific
negotiations and setup. They have access to the Curl_sendf() (from
@@ -182,10 +184,9 @@ Library
be called with some basic info about the upcoming transfer: what socket(s)
to read/write and the expected file transfer sizes (if known).
o Transfer()
o Curl_readwrite()
Curl_perform() then calls Transfer() in lib/transfer.c that performs the
entire file transfer.
Called during the transfer of the actual protocol payload.
During transfer, the progress functions in lib/progress.c are called at a
frequent interval (or at the user's choice, a specified callback might get
@@ -207,33 +208,11 @@ Library
used. This function is only used when we are certain that no more transfers
is going to be made on the connection. It can be also closed by force, or
it can be called to make sure that libcurl doesn't keep too many
connections alive at the same time (there's a default amount of 5 but that
can be changed with the CURLOPT_MAXCONNECTS option).
connections alive at the same time.
This function cleans up all resources that are associated with a single
connection.
Curl_perform() is the function that does the main "connect - do - transfer -
done" loop. It loops if there's a Location: to follow.
When completed, the curl_easy_cleanup() should be called to free up used
resources. It runs Curl_disconnect() on all open connections.
A quick roundup on internal function sequences (many of these call
protocol-specific function-pointers):
Curl_connect - connects to a remote site and does initial connect fluff
This also checks for an existing connection to the requested site and uses
that one if it is possible.
Curl_do - starts a transfer
Curl_handler::do_it() - transfers data
Curl_done - ends a transfer
Curl_disconnect - disconnects from a remote site. This is called when the
disconnect is really requested, which doesn't necessarily have to be
exactly after curl_done in case we want to keep the connection open for
a while.
HTTP(S)
@@ -316,48 +295,38 @@ Persistent Connections
hold connection-oriented data. It is meant to hold the root data as well as
all the options etc that the library-user may choose.
o The 'SessionHandle' struct holds the "connection cache" (an array of
pointers to 'connectdata' structs). There's one connectdata struct
allocated for each connection that libcurl knows about. Note that when you
use the multi interface, the multi handle will hold the connection cache
and not the particular easy handle. This of course to allow all easy handles
in a multi stack to be able to share and re-use connections.
pointers to 'connectdata' structs).
o This enables the 'curl handle' to be reused on subsequent transfers.
o When we are about to perform a transfer with curl_easy_perform(), we first
check for an already existing connection in the cache that we can use,
otherwise we create a new one and add to the cache. If the cache is full
already when we add a new connection, we close one of the present ones. We
select which one to close dependent on the close policy that may have been
previously set.
o When the transfer operation is complete, we try to leave the connection
open. Particular options may tell us not to, and protocols may signal
closure on connections and then we don't keep it open of course.
o When libcurl is told to perform a transfer, it first checks for an already
existing connection in the cache that we can use. Otherwise it creates a
new one and adds that the cache. If the cache is full already when a new
conncetion is added added, it will first close the oldest unused one.
o When the transfer operation is complete, the connection is left
open. Particular options may tell libcurl not to, and protocols may signal
closure on connections and then they won't be kept open of course.
o When curl_easy_cleanup() is called, we close all still opened connections,
unless of course the multi interface "owns" the connections.
You do realize that the curl handle must be re-used in order for the
persistent connections to work.
The curl handle must be re-used in order for the persistent connections to
work.
multi interface/non-blocking
============================
We make an effort to provide a non-blocking interface to the library, the
multi interface. To make that interface work as good as possible, no
low-level functions within libcurl must be written to work in a blocking
manner.
The multi interface is a non-blocking interface to the library. To make that
interface work as good as possible, no low-level functions within libcurl
must be written to work in a blocking manner. (There are still a few spots
violating this rule.)
One of the primary reasons we introduced c-ares support was to allow the name
resolve phase to be perfectly non-blocking as well.
The ultimate goal is to provide the easy interface simply by wrapping the
multi interface functions and thus treat everything internally as the multi
interface is the single interface we have.
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
and adjust the code to allow non-blocking operations even on multi-stage
protocols. They are built around state machines that return when they could
block waiting for data. The DICT, LDAP and TELNET protocols are crappy
examples and they are subject for rewrite in the future to better fit the
libcurl protocol family.
The FTP and the SFTP/SCP protocols are examples of how we adapt and adjust
the code to allow non-blocking operations even on multi-stage command-
response protocols. They are built around state machines that return when
they would otherwise block waiting for data. The DICT, LDAP and TELNET
protocols are crappy examples and they are subject for rewrite in the future
to better fit the libcurl protocol family.
SSL libraries
=============
@@ -408,12 +377,12 @@ API/ABI
Client
======
main() resides in src/main.c together with most of the client code.
main() resides in src/tool_main.c.
src/tool_hugehelp.c is automatically generated by the mkhelp.pl perl script
to display the complete "manual" and the src/urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that
the {} and [] expansion stuff is there.
to display the complete "manual" and the src/tool_urlglob.c file holds the
functions used for the URL-"globbing" support. Globbing in the sense that the
{} and [] expansion stuff is there.
The client mostly messes around to setup its 'config' struct properly, then
it calls the curl_easy_*() functions of the library and when it gets back
@@ -425,8 +394,8 @@ Client
curl_easy_getinfo() function to extract useful information from the curl
session.
Recent versions may loop and do all this several times if many URLs were
specified on the command line or config file.
It may loop and do all this several times if many URLs were specified on the
command line or config file.
Memory Debugging
================

View File

@@ -3,6 +3,25 @@ join in and help us correct one or more of these! Also be sure to check the
changelog of the current development status, as one or more of these problems
may have been fixed since this was written!
83. curl is unable to load non-default openssl engines, because openssl isn't
initialized properly. This seems to require OpenSSL_config() or
CONF_modules_load_file() to be used by libcurl but the first seems to not
work and we've gotten not reports from tests with the latter. Possibly we
need to discuss with OpenSSL developers how this is supposed to be done. We
need users with actual external openssl engines for testing to work on this.
http://curl.haxx.se/bug/view.cgi?id=1208
82. When building with the Windows Borland compiler, it fails because the
"tlib" tool doesn't support hyphens (minus signs) in file names and we have
such in the build.
http://curl.haxx.se/bug/view.cgi?id=1222
81. When using -J (with -O), automaticly resumed downloading together with "-C
-" fails. Without -J the same command line works! This happens because the
resume logic is worked out before the target file name (and thus its
pre-transfer size) has been figured out!
http://curl.haxx.se/bug/view.cgi?id=1169
80. Curl doesn't recognize certificates in DER format in keychain, but it
works with PEM.
http://curl.haxx.se/bug/view.cgi?id=3439999
@@ -85,13 +104,6 @@ may have been fixed since this was written!
CURLOPT_FAILONERROR with FTP to detect if a file exists or not, but it is
not working: http://curl.haxx.se/mail/lib-2008-07/0295.html
57. On VMS-Alpha: When using an http-file-upload the file is not sent to the
Server with the correct content-length. Sending a file with 511 or less
bytes, content-length 512 is used. Sending a file with 513 - 1023 bytes,
content-length 1024 is used. Files with a length of a multiple of 512 Bytes
show the correct content-length. Only these files work for upload.
http://curl.haxx.se/bug/view.cgi?id=2057858
56. When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP
server using the multi interface, the commands are not being sent correctly
and instead the connection is "cancelled" (the operation is considered done)
@@ -169,12 +181,6 @@ may have been fixed since this was written!
We probably have even more bugs and lack of features when a SOCKS proxy is
used.
22. Sending files to a FTP server using curl on VMS, might lead to curl
complaining on "unaligned file size" on completion. The problem is related
to VMS file structures and the perceived file sizes stat() returns. A
possible fix would involve sending a "STRU VMS" command.
http://curl.haxx.se/bug/view.cgi?id=1156287
21. FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
clearly describes how this should be done:

245
docs/LIBCURL-STRUCTS Normal file
View File

@@ -0,0 +1,245 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Structs in libcurl
This document should cover 7.32.0 pretty accurately, but will make sense even
for older and later versions as things don't change drastically that often.
1. The main structs in libcurl
1.1 SessionHandle
1.2 connectdata
1.3 Curl_multi
1.4 Curl_handler
1.5 conncache
1.6 Curl_share
1.7 CookieInfo
==============================================================================
1. The main structs in libcurl
1.1 SessionHandle
The SessionHandle handle struct is the one returned to the outside in the
external API as a "CURL *". This is usually known as an easy handle in API
documentations and examples.
Information and state that is related to the actual connection is in the
'connectdata' struct. When a transfer is about to be made, libcurl will
either create a new connection or re-use an existing one. The particular
connectdata that is used by this handle is pointed out by
SessionHandle->easy_conn.
Data and information that regard this particular single transfer is put in
the SingleRequest sub-struct.
When the SessionHandle struct is added to a multi handle, as it must be in
order to do any transfer, the ->multi member will point to the Curl_multi
struct it belongs to. The ->prev and ->next members will then be used by the
multi code to keep a linked list of SessionHandle structs that are added to
that same multi handle. libcurl always uses multi so ->multi *will* point to
a Curl_multi when a transfer is in progress.
->mstate is the multi state of this particular SessionHandle. When
multi_runsingle() is called, it will act on this handle according to which
state it is in. The mstate is also what tells which sockets to return for a
speicific SessionHandle when curl_multi_fdset() is called etc.
The libcurl source code generally use the name 'data' for the variable that
points to the SessionHandle.
1.2 connectdata
A general idea in libcurl is to keep connections around in a connection
"cache" after they have been used in case they will be used again and then
re-use an existing one instead of creating a new as it creates a significant
performance boost.
Each 'connectdata' identifies a single physical conncetion to a server. If
the connection can't be kept alive, the connection will be closed after use
and then this struct can be removed from the cache and freed.
Thus, the same SessionHandle can be used multiple times and each time select
another connectdata struct to use for the connection. Keep this in mind, as
it is then important to consider if options or choices are based on the
connection or the SessionHandle.
Functions in libcurl will assume that connectdata->data points to the
SessionHandle that uses this connection.
As a special complexity, some protocols supported by libcurl require a
special disconnect procedure that is more than just shutting down the
socket. It can involve sending one or more commands to the server before
doing so. Since connections are kept in the connection cache after use, the
original SessionHandle may no longer be around when the time comes to shut
down a particular connection. For this purpose, libcurl holds a special
dummy 'closure_handle' SessionHandle in the Curl_multi struct to
FTP uses two TCP connections for a typical transfer but it keeps both in
this single struct and thus can be considered a single connection for most
internal concerns.
The libcurl source code generally use the name 'conn' for the variable that
points to the connectdata.
1.3 Curl_multi
Internally, the easy interface is implemented as a wrapper around multi
interface functions. This makes everything multi interface.
Curl_multi is the multi handle struct exposed as "CURLM *" in external APIs.
This struct holds a list of SessionHandle structs that have been added to
this handle with curl_multi_add_handle(). The start of the list is ->easyp
and ->num_easy is a counter of added SessionHandles.
->msglist is a linked list of messages to send back when
curl_multi_info_read() is called. Basically a node is added to that list
when an individual SessionHandle's transfer has completed.
->hostcache points to the name cache. It is a hash table for looking up name
to IP. The nodes have a limited life time in there and this cache is meant
to reduce the time for when the same name is wanted within a short period of
time.
->timetree points to a tree of SessionHandles, sorted by the remaining time
until it should be checked - normally some sort of timeout. Each
SessionHandle has one node in the tree.
->sockhash is a hash table to allow fast lookups of socket descriptor to
which SessionHandle that uses that descriptor. This is necessary for the
multi_socket API.
->conn_cache points to the connection cache. It keeps track of all
connections that are kept after use. The cache has a maximum size.
->closure_handle is described in the 'connectdata' section.
The libcurl source code generally use the name 'multi' for the variable that
points to the Curl_multi struct.
1.4 Curl_handler
Each unique protocol that is supported by libcurl needs to provide at least
one Curl_handler struct. It defines what the protocol is called and what
functions the main code should call to deal with protocol specific issues.
In general, there's a source file named [protocol].c in which there's a
"struct Curl_handler Curl_handler_[protocol]" declared. In url.c there's
then the main array with all individual Curl_handler structs pointed to from
a single array which is scanned through when a URL is given to libcurl to
work with.
->scheme is the URL scheme name, usually spelled out in uppercase. That's
"HTTP" or "FTP" etc. SSL versions of the protcol need its own Curl_handler
setup so HTTPS separate from HTTP.
->setup_connection is called to allow the protocol code to allocate protocol
specific data that then gets associated with that SessionHandle for the rest
of this transfer. It gets freed again at the end of the transfer. It will be
called before the 'connectdata' for the transfer has been selected/created.
Most protocols will allocate its private 'struct [PROTOCOL]' here and assign
SessionHandle->req.protop to point to it.
->connect_it allows a protocol to do some specific actions after the TCP
connect is done, that can still be considered part of the connection phase.
Some protocols will alter the connectdata->recv[] and connectdata->send[]
function pointers in this function.
->connecting is similarly a function that keeps getting called as long as the
protocol considers itself still in the connecting phase.
->do_it is the function called to issue the transfer request. What we call
the DO action internally. If the DO is not enough and things need to be kept
getting done for the entier DO sequence to complete, ->doing is then usually
also provided. Each protocol that needs to do multiple commands or similar
for do/doing need to implement their own state machines (see SCP, SFTP,
FTP). Some protocols (only FTP and only due to historical reasons) has a
separate piece of the DO state called DO_MORE.
->doing keeps getting called while issudeing the transfer request command(s)
->done gets called when the transfer is complete and DONE. That's after the
main data has been transferred.
->do_more gets called doring the DO_MORE state. The FTP protocol uses this
state when setting up the second connection.
->proto_getsock
->doing_getsock
->domore_getsock
->perform_getsock
Functions that return socket information. Which socket(s) to wait for which
action(s) during the particular multi state.
->disconnect is called immediately before the TCP connection is shutdown.
->readwrite gets called during transfer to allow the protocol to do extra
reads/writes
->defport is the default report TCP or UDP port this protocol uses
->protocol is one or more bits in the CURLPROTO_* set. The SSL versions have
their "base" protocol set and then the SSL variation. Like "HTTP|HTTPS".
->flags is a bitmask with additional information about the protocol that will
make it get treated differently by the generic engine:
PROTOPT_SSL - will make it connect and negotiate SSL
PROTOPT_DUAL - this protocol uses two connections
PROTOPT_CLOSEACTION - this protocol has actions to do before closing the
connection. This flag is no longer used by code, yet still set for a bunch
protocol handlers.
PROTOPT_DIRLOCK - "direction lock". The SSH protocols set this bit to
limit which "direction" of socket actions that the main engine will
concern itself about.
PROTOPT_NONETWORK - a protocol that doesn't use network (read file:)
PROTOPT_NEEDSPWD - this protocol needs a password and will use a default
one unless one is provided
PROTOPT_NOURLQUERY - this protocol can't handle a query part on the URL
(?foo=bar)
1.5 conncache
Is a hash table with connections for later re-use. Each SessionHandle has
a pointer to its connection cache. Each multi handle sets up a connection
cache that all added SessionHandles share by default.
1.6 Curl_share
The libcurl share API allocates a Curl_share struct, exposed to the external
API as "CURLSH *".
The idea is that the struct can have a set of own versions of caches and
pools and then by providing this struct in the CURLOPT_SHARE option, those
specific SessionHandles will use the caches/pools that this share handle
holds.
Then individual SessionHandle structs can be made to share specific things
that they otherwise wouldn't, such as cookies.
The Curl_share struct can currently hold cookies, DNS cache and the SSL
session cache.
1.7 CookieInfo
This is the main cookie struct. It holds all known cookies and related
information. Each SessionHandle has its own private CookieInfo even when
they are added to a multi handle. They can be made to share cookies by using
the share API.

View File

@@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2012, 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
@@ -22,7 +22,8 @@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1 mk-ca-bundle.1
man_MANS = curl.1 curl-config.1
noinst_man_MANS = mk-ca-bundle.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
@@ -36,7 +37,7 @@ EXTRA_DIST = MANUAL BUGS CONTRIBUTE FAQ FEATURES INTERNALS SSLCERTS \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS \
KNOWN_BUGS BINDINGS $(man_MANS) $(HTMLPAGES) HISTORY INSTALL \
$(PDFPAGES) LICENSE-MIXING README.netware DISTRO-DILEMMA INSTALL.devcpp \
MAIL-ETIQUETTE HTTP-COOKIES
MAIL-ETIQUETTE HTTP-COOKIES LIBCURL-STRUCTS
MAN2HTML= roffit < $< >$@

View File

@@ -13,14 +13,15 @@ Adam Tkac
Adrian Schuur
Adriano Meirelles
Ajit Dhumale
Aki Koskinen
Akos Pasztory
Alan Pinstein
Albert Chin
Albert Chin-A-Young
Albert Choy
Ale Vesely
Alejandro Alvarez
Aleksandar Milivojevic
Aleksey Tulinov
Alessandro Ghedini
Alessandro Vesely
Alex Bligh
@@ -31,6 +32,7 @@ Alex Suykov
Alex Vinnik
Alex aka WindEagle
Alexander Beedie
Alexander Klauer
Alexander Kourakos
Alexander Krasnostavsky
Alexander Lazic
@@ -46,11 +48,13 @@ Amol Pattekar
Amr Shahin
Anatoli Tubman
Anders Gustafsson
Anders Havn
Andi Jahja
Andre Guibert de Bruet
Andreas Damm
Andreas Faerber
Andreas Farber
Andreas Malzahn
Andreas Ntaflos
Andreas Olsson
Andreas Rieke
@@ -64,9 +68,11 @@ Andrew Biggs
Andrew Bushnell
Andrew Francis
Andrew Fuller
Andrew Kurushin
Andrew Moise
Andrew Wansink
Andrew de los Reyes
Andrii Moiseiev
Andrés García
Andy Cedilnik
Andy Serpa
@@ -101,12 +107,14 @@ Ben Van Hof
Ben Winslow
Benbuck Nason
Benjamin Gerard
Benjamin Gilbert
Benjamin Johnson
Bernard Leak
Bernhard Reutner-Fischer
Bertrand Demiddelaer
Bill Egert
Bill Hoffman
Bill Middlecamp
Bjoern Sikora
Bjorn Augustsson
Bjorn Reese
@@ -133,6 +141,7 @@ Bruce Mitchener
Bruno de Carvalho
Bryan Henderson
Bryan Kemp
Byrial Jensen
Cameron Kaiser
Camille Moncelier
Caolan McNamara
@@ -153,13 +162,13 @@ Chris Maltby
Chris Mumford
Chris Smowton
Christian Grothoff
Christian Hagele
Christian Hägele
Christian Krause
Christian Kurz
Christian Robottom Reis
Christian Schmitz
Christian Vogt
Christian Weisgerber
Christophe Demory
Christophe Legry
Christopher Conroy
@@ -169,6 +178,7 @@ Christopher Stone
Ciprian Badescu
Claes Jakobsson
Clarence Gardner
Clemens Gruber
Clifford Wolf
Cody Jones
Colin Hogben
@@ -180,10 +190,10 @@ Craig A West
Craig Davison
Craig Markwardt
Cris Bailiff
Cristian Rodriguez
Cristian Rodríguez
Curt Bogmine
Cyrill Osterwalder
Cédric Deltheil
Dag Ekengren
Dagobert Michelsen
Damien Adant
@@ -231,6 +241,7 @@ David Odin
David Phillips
David Rosenstrauch
David Shaw
David Strauss
David Tarendash
David Thiel
David Wright
@@ -263,6 +274,7 @@ Douglas R. Horner
Douglas Steinwand
Dov Murik
Duane Cathey
Duncan
Duncan Mac-Vicar Prett
Dustin Boswell
Dylan Ellicott
@@ -271,6 +283,7 @@ Early Ehlinger
Ebenezer Ikonne
Edin Kadribasic
Eduard Bloch
Edward Rudd
Edward Sheldrake
Eelco Dolstra
Eetu Ojanen
@@ -288,15 +301,18 @@ Eric Lavigne
Eric Melville
Eric Mertens
Eric Rautman
Eric S. Raymond
Eric Thelin
Eric Vergnaud
Eric Wong
Eric Young
Erick Nuwendam
Erik Johansson
Erwan Legrand
Erwin Authried
Eugene Kotlyarov
Evan Jordan
Evgeny Turnaev
Eygene Ryabinkin
Fabian Hiernaux
Fabian Keil
@@ -317,6 +333,7 @@ Fred Machado
Fred New
Fred Noz
Frederic Lepied
Fredrik Thulin
Gabriel Kuri
Gabriel Sjoberg
Garrett Holmstrom
@@ -360,6 +377,7 @@ Gwenole Beauchesne
Götz Babin-Ebell
Hamish Mackenzie
Hang Kin Lau
Hang Su
Hanno Kranzhoff
Hans Steegers
Hans-Jurgen May
@@ -394,6 +412,7 @@ Immanuel Gregoire
Ingmar Runge
Ingo Ralf Blum
Ingo Wilken
Ishan SinghLevett
Jack Zhang
Jacky Lam
Jacob Meuser
@@ -415,6 +434,7 @@ Jan Koen Annot
Jan Kunder
Jan Schaumann
Jan Van Boghout
Jared Jennings
Jared Lundell
Jari Sundell
Jason Glasgow
@@ -429,6 +449,7 @@ Jean-Claude Chauve
Jean-Francois Bertrand
Jean-Louis Lemaire
Jean-Marc Ranger
Jean-Noel Rouvignac
Jean-Philippe Barrette-LaPierre
Jeff Connelly
Jeff Johnson
@@ -438,6 +459,7 @@ Jeff Pohlmeyer
Jeff Weber
Jeffrey Pohlmeyer
Jeremy Friesner
Jeremy Huddleston
Jerome Muffat-Meridol
Jerome Vouillon
Jerry Wu
@@ -449,8 +471,8 @@ Jim Drash
Jim Freeman
Jim Hollinger
Jim Meyering
Jiri Jaburek
Jiri Hruska
Jiri Jaburek
Jocelyn Jaubert
Joe Halpin
Joe Malicki
@@ -465,6 +487,7 @@ John Bradshaw
John Crow
John Dennis
John E. Malmberg
John Gardiner Myers
John Janssen
John Joseph Bachir
John Kelly
@@ -506,6 +529,7 @@ Julien Royer
Jun-ichiro itojun Hagino
Jurij Smakov
Justin Fletcher
Justin Karneges
Jörg Mueller-Tolk
Jörn Hartroth
Kai Engert
@@ -534,10 +558,12 @@ Kevin Lussier
Kevin Reed
Kevin Roth
Kim Rinnewitz
Kim Vandry
Kimmo Kinnunen
Kjell Ericson
Kjetil Jacobsen
Klevtsov Vadim
Konstantin Isakov
Kris Kennaway
Krishnendu Majumdar
Krister Johansen
@@ -550,6 +576,7 @@ Larry Fahnoe
Lars Buitinck
Lars Gustafsson
Lars J. Aas
Lars Johannesen
Lars Nilsson
Lars Torben Wilson
Lau Hang Kin
@@ -572,6 +599,7 @@ Loren Kirkby
Luca Altea
Luca Alteas
Lucas Adamski
Ludovico Cavedon
Lukasz Czekierda
Luke Amery
Luke Call
@@ -583,6 +611,7 @@ Mandy Wu
Manfred Schwarb
Manuel Massing
Marc Boucher
Marc Doughty
Marc Hoersken
Marc Kleine-Budde
Marcel Raad
@@ -614,6 +643,7 @@ Martin C. Martin
Martin Drasar
Martin Hager
Martin Hedenfalk
Martin Jansen
Martin Lemke
Martin Skinner
Martin Storsjo
@@ -661,12 +691,14 @@ Michal Gorny
Michal Kowalczyk
Michal Marek
Michele Bini
Miguel Angel
Mihai Ionescu
Mikael Johansson
Mikael Sennerholm
Mike Bytnar
Mike Crowe
Mike Dobbs
Mike Giancola
Mike Hommey
Mike Power
Mike Protts
@@ -676,6 +708,8 @@ Mitz Wark
Mohamed Lrhazi
Mohun Biswas
Moonesamy
Myk Taylor
Nach M. S.
Nathan Coulter
Nathan O'Sullivan
Nathanael Nerode
@@ -709,6 +743,7 @@ Ofer
Olaf Flebbe
Olaf Stueben
Olaf Stüben
Oliver Gondža
Olivier Berger
Oren Tirosh
Ori Avtalion
@@ -720,6 +755,7 @@ Pascal Terjan
Pasha Kuznetsov
Pat Ray
Patrice Guerin
Patricia Muscalu
Patrick Bihan-Faou
Patrick Monnerat
Patrick Scott
@@ -742,6 +778,7 @@ Pedro Neves
Pete Su
Peter Bray
Peter Forret
Peter Gal
Peter Heuchert
Peter Hjalmarsson
Peter Korsgaard
@@ -779,6 +816,7 @@ Quinn Slack
Rafa Muyo
Rafael Sagula
Rainer Canavan
Rainer Jung
Rainer Koenig
Rajesh Naganathan
Ralf S. Engelschall
@@ -793,6 +831,7 @@ Reinout van Schouwen
Renato Botelho
Renaud Chaillat
Renaud Duhaut
Renaud Guillard
Rene Bernhardt
Rene Rebe
Reuven Wachtfogel
@@ -806,6 +845,7 @@ Richard Bramante
Richard Clayton
Richard Cooper
Richard Gorton
Richard Michael
Richard Prescott
Richard Silverman
Rick Jones
@@ -822,6 +862,7 @@ Robert Iakobashvili
Robert Olson
Robert Schumann
Robert Weaver
Robert Wruck
Robin Cornelius
Robin Johnson
Robin Kay
@@ -846,6 +887,7 @@ Ryan Schmidt
S. Moonesamy
Salvador Dávila
Salvatore Sorrentino
Sam Deane
Sam Listopad
Sampo Kellomaki
Samuel Díaz García
@@ -856,6 +898,7 @@ Sandor Feldi
Santhana Todatry
Saqib Ali
Sara Golemon
Saran Neti
Saul good
Scott Bailey
Scott Barrett
@@ -888,6 +931,7 @@ Stan van de Burgt
Stanislav Ivochkin
Stefan Esser
Stefan Krause
Stefan Neis
Stefan Teleman
Stefan Tomanek
Stefan Ulrich
@@ -906,6 +950,7 @@ Steve Oliphant
Steve Roskowski
Steven Bazyl
Steven G. Johnson
Steven Gu
Steven M. Schweda
Steven Parkes
Stoned Elipot
@@ -934,6 +979,7 @@ Tim Harder
Tim Heckman
Tim Newsome
Tim Sneddon
Timo Sirainen
Tinus van den Berg
Tobias Rundström
Toby Peterson
@@ -943,6 +989,7 @@ Todd Ouska
Todd Vierling
Tom Benoist
Tom Donovan
Tom Grace
Tom Lee
Tom Mattison
Tom Moers
@@ -994,9 +1041,12 @@ Wesley Laxton
Wesley Miaw
Wez Furlong
Wilfredo Sanchez
Willem Sparreboom
Wojciech Zwiefka
Wouter Van Rooy
Wu Yongzheng
Xavier Bouchoux
Yamada Yasuharu
Yang Tse
Yarram Sunil
Yehoshua Hershberg
@@ -1004,6 +1054,8 @@ Yukihiro Kawada
Yuriy Sosov
Yves Arrouye
Yves Lejeune
Zdenek Pavlas
Zekun Ni
Zmey Petroff
Zvi Har'El
nk

133
docs/TODO
View File

@@ -16,8 +16,8 @@
1.3 struct lifreq
1.4 signal-based resolver timeouts
1.5 get rid of PATH_MAX
1.6 progress callback without doubles
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
1.7 Modified buffer size approach
2. libcurl - multi interface
2.1 More non-blocking
@@ -38,6 +38,7 @@
5.1 Better persistency for HTTP 1.0
5.2 support FF3 sqlite cookie files
5.3 Rearrange request header order
5.4 HTTP2/SPDY
6. TELNET
6.1 ditch stdin
@@ -46,19 +47,18 @@
6.4 send data in chunks
7. SMTP
7.1 Specify the preferred authentication mechanism
7.2 Initial response
7.3 Pipelining
7.4 Graceful base64 decoding failure
7.1 Pipelining
7.2 Graceful base64 decoding failure
7.3 Enhanced capability support
8. POP3
8.1 auth= in URLs
8.2 Initial response
8.3 Graceful base64 decoding failure
8.1 Pipelining
8.2 Graceful base64 decoding failure
8.3 Enhanced capability support
9. IMAP
9.1 auth= in URLs
9.2 Graceful base64 decoding failure
9.1 Graceful base64 decoding failure
9.2 Enhanced capability support
10. LDAP
10.1 SASL based authentication mechanisms
@@ -157,16 +157,7 @@
we need libssh2 to properly tell us when we pass in a too small buffer and
its current API (as of libssh2 1.2.7) doesn't.
1.6 progress callback without doubles
The progress callback was introduced way back in the days and the choice to
use doubles in the arguments was possibly good at the time. Today the doubles
only confuse users and make the amounts less precise. We should introduce
another progress callback option that take precedence over the old one and
have both co-exist for a forseeable time until we can remove the double-using
one.
1.7 Happy Eyeball dual stack connect
1.6 Happy Eyeball dual stack connect
In order to make alternative technologies not suffer when transitioning, like
when introducing IPv6 as an alternative to IPv4 and there are more than one
@@ -178,6 +169,28 @@
http://tools.ietf.org/html/rfc6555
1.7 Modified buffer size approach
Current libcurl allocates a fixed 16K size buffer for download and an
additional 16K for upload. They are always unconditionally part of the easy
handle. If CRLF translations are requested, an additional 32K "scratch
buffer" is allocated. A total of 64K transfer buffers in the worst case.
First, while the handles are not actually in use these buffers could be freed
so that lingering handles just kept in queues or whatever waste less memory.
Secondly, SFTP is a protocol that needs to handle many ~30K blocks at once
since each need to be individually acked and therefore libssh2 must be
allowed to send (or receive) many separate ones in parallel to achieve high
transfer speeds. A current libcurl build with a 16K buffer makes that
impossible, but one with a 512K buffer will reach MUCH faster transfers. But
allocating 512K unconditionally for all buffers just in case they would like
to do fast SFTP transfers at some point is not a good solution either.
Dynamically allocate buffer size depending on protocol in use in combination
with freeing it after each individual transfer? Other suggestions?
2. libcurl - multi interface
2.1 More non-blocking
@@ -269,6 +282,25 @@
headers use a default value so only headers that need to be moved have to be
specified.
5.4 HTTP2/SPDY
The first drafts for HTTP2 have been published
(http://tools.ietf.org/html/draft-ietf-httpbis-http2-03) and is so far based
on SPDY (http://www.chromium.org/spdy) designs and experiences. Chances are
it will end up in that style. Chrome and Firefox already support SPDY and
lots of web services do.
It would make sense to implement SPDY support now and later transition into
or add HTTP2 support as well.
We should base or HTTP2/SPDY work on a 3rd party library for the protocol
fiddling. The Spindy library (http://spindly.haxx.se/) was an attempt to make
such a library with an API suitable for use by libcurl but that effort has
more or less stalled. spdylay (https://github.com/tatsuhiro-t/spdylay) may
be a better option, either used directly or wrapped with a more spindly-like
API.
6. TELNET
6.1 ditch stdin
@@ -295,65 +327,54 @@ to provide the data to send.
7. SMTP
7.1 Specify the preferred authentication mechanism
Add the ability to specify the preferred authentication mechanism or a list
of mechanisms that should be used. Not only that, but the order that is
returned by the server during the EHLO response should be honored by curl.
7.2 Initial response
Add the ability for the user to specify whether the initial response is
included in the AUTH command. Some email servers, such as Microsoft
Exchange, can work with either whilst others need to have the initial
response sent separately:
http://curl.haxx.se/mail/lib-2012-03/0114.html
7.3 Pipelining
7.1 Pipelining
Add support for pipelining emails.
7.4 Graceful base64 decoding failure
7.2 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC4954.
7.3 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the EHLO command.
8. POP3
8.1 auth= in URLs
8.1 Pipelining
Being able to specify the preferred authentication mechanism in the URL as
per RFC2384.
Add support for pipelining commands.
8.2 Initial response
Add the ability for the user to specify whether the initial response is
included in the AUTH command as per RFC5034.
8.3 Graceful base64 decoding failure
8.2 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC5034.
8.3 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPA command.
9. IMAP
9.1 auth= in URLs
Being able to specify the preferred authentication mechanism in the URL as
per RFC5092.
9.2 Graceful base64 decoding failure
9.1 Graceful base64 decoding failure
Rather than shutting down the session and returning an error when the
decoding of a base64 encoded authentication response fails, we should
gracefully shutdown the authentication process by sending a * response to the
server as per RFC3501.
9.2 Enhanced capability support
Add the ability, for an application that uses libcurl, to obtain the list of
capabilities returned from the CAPABILITY command.
10. LDAP
10.1 SASL based authentication mechanisms
@@ -429,6 +450,12 @@ to provide the data to send.
keys and certs over DNS using DNSSEC as an alternative to the CA model.
http://www.rfc-editor.org/rfc/rfc6698.txt
An initial patch was posted by Suresh Krishnaswamy on March 7th 2013
(http://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple
approach. See Daniel's comments:
http://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the
correct library to base this development on.
13. GnuTLS
13.1 SSL engine stuff

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2012, 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
@@ -230,7 +230,9 @@ server sends an unsupported encoding, curl will report an error.
.IP "--connect-timeout <seconds>"
Maximum time in seconds that you allow the connection to the server to take.
This only limits the connection phase, once curl has connected this option is
of no more use. See also the \fI-m, --max-time\fP option.
of no more use. Since 7.32.0, this option accepts decimal values, but the
actual timeout will decrease in accuracy as the specified timeout increases in
decimal precision. See also the \fI-m, --max-time\fP option.
If this option is used several times, the last one will be used.
.IP "--create-dirs"
@@ -388,7 +390,15 @@ curl the nickname of the certificate to use within the NSS database defined
by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
loaded. If you want to use a file from the current directory, please precede
it with "./" prefix, in order to avoid confusion with a nickname.
it with "./" prefix, in order to avoid confusion with a nickname. If the
nickname contains ":", it needs to be preceded by "\\" so that it is not
recognized as password delimiter. If the nickname contains "\\", it needs to
be escaped as "\\\\" so that it is not recognized as an escape character.
(iOS and Mac OS X only) If curl is built against Secure Transport, then the
certificate string must match the name of a certificate that's in the system or
user keychain. The private key corresponding to the certificate, and
certificate chain (if any), must also be present in the keychain.
If this option is used several times, the last one will be used.
.IP "--engine <name>"
@@ -805,7 +815,10 @@ Basic authentication).
.IP "-m, --max-time <seconds>"
Maximum time in seconds that you allow the whole operation to take. This is
useful for preventing your batch jobs from hanging for hours due to slow
networks or links going down. See also the \fI--connect-timeout\fP option.
networks or links going down. Since 7.32.0, this option accepts decimal
values, but the actual timeout will decrease in accuracy as the specified
timeout increases in decimal precision. See also the \fI--connect-timeout\fP
option.
If this option is used several times, the last one will be used.
.IP "--mail-auth <address>"
@@ -1038,6 +1051,13 @@ ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.19.1)
.IP "--post303"
(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
into GET requests when following a 303 redirection. The non-RFC behaviour is
ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.26.0)
.IP "--proto <protocols>"
Tells curl to use the listed protocols for its initial retrieval. Protocols
are evaluated left to right, are comma separated, and are each a protocol
@@ -1272,8 +1292,12 @@ Set this option to zero to not timeout retries. (Added in 7.12.3)
If this option is used several times, the last one will be used.
.IP "-s, --silent"
Silent or quiet mode. Don't show progress meter or error messages. Makes
Curl mute.
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl
mute. It will still output the data you ask for, potentially even to the
terminal/stdout unless you redirect it.
.IP "--sasl-ir"
Enable initial response in SASL authentication.
(Added in 7.31.0)
.IP "-S, --show-error"
When used with \fI-s\fP it makes curl show an error message if it fails.
.IP "--ssl"
@@ -1669,7 +1693,7 @@ If this option is used several times, the last one will be used.
.IP "--xattr"
When saving output to a file, this option tells curl to store certain file
metadata in extened file attributes. Currently, the URL is stored in the
metadata in extended file attributes. Currently, the URL is stored in the
xdg.origin.url attribute and, for HTTP, the content type is stored in
the mime_type attribute. If the file system does not support extended
attributes, a warning is issued.
@@ -1689,7 +1713,7 @@ speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
if not set.
If this option is used several times, the last one will be used.
.IP "-z/--time-cond <date expression>|<file>"
.IP "-z, --time-cond <date expression>|<file>"
(HTTP/FTP) Request a file that has been modified later than the given time and
date, or one that has been modified before that time. The <date expression>
can be all sorts of date strings or if it doesn't match any internal ones, it

View File

@@ -43,3 +43,5 @@ simplessl
smtp-multi
smtp-tls
url2file
usercertinmem
xmlstream

View File

@@ -13,4 +13,4 @@ COMPLICATED_EXAMPLES = curlgtk.c curlx.c htmltitle.cpp cacertinmem.c \
ftpuploadresume.c ghiper.c hiperfifo.c htmltidy.c multithread.c \
opensslthreadlock.c sampleconv.c synctime.c threaded-ssl.c evhiperfifo.c \
smooth-gtk-thread.c version-check.pl href_extractor.c asiohiper.cpp \
multi-uv.c
multi-uv.c xmlstream.c usercertinmem.c

View File

@@ -27,14 +27,14 @@
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-spi-winidn
##
## Hint: you can also set environment vars to control the build, f.e.:
## set ZLIB_PATH=c:/zlib-1.2.7
## set ZLIB_PATH=c:/zlib-1.2.8
## set ZLIB=1
#
###########################################################################
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.7
ZLIB_PATH = ../../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH

View File

@@ -14,7 +14,7 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.7
ZLIB_PATH = ../../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.

View File

@@ -78,4 +78,5 @@ 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.

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, 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
@@ -30,9 +30,10 @@ struct myprogress {
CURL *curl;
};
static int progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
@@ -48,7 +49,9 @@ static int progress(void *p,
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
fprintf(stderr, "UP: %g of %g DOWN: %g of %g\r\n",
fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
@@ -56,6 +59,19 @@ static int progress(void *p,
return 0;
}
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
return xferinfo(p,
(curl_off_t)dltotal,
(curl_off_t)dlnow,
(curl_off_t)ultotal,
(curl_off_t)ulnow);
}
int main(void)
{
CURL *curl;
@@ -68,9 +84,28 @@ int main(void)
prog.curl = curl;
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/");
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0, no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl, but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback, making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
/* pass the struct pointer into the xferinfo function, note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endif
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);

View File

@@ -54,23 +54,22 @@ int main(void)
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
/* open the files */
headerfile = fopen(headerfilename,"w");
headerfile = fopen(headerfilename,"wb");
if (headerfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
bodyfile = fopen(bodyfilename,"w");
bodyfile = fopen(bodyfilename,"wb");
if (bodyfile == NULL) {
curl_easy_cleanup(curl_handle);
return -1;
}
/* we want the headers to this file handle */
/* we want the headers be written to this file handle */
curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, headerfile);
/*
* Notice here that if you want the actual data sent anywhere else but
* stdout, you should consider using the CURLOPT_WRITEDATA option. */
/* we want the body be written to this file handle instead of stdout */
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
/* get it! */
curl_easy_perform(curl_handle);
@@ -78,6 +77,9 @@ int main(void)
/* close the header file */
fclose(headerfile);
/* close the body file */
fclose(bodyfile);
/* cleanup curl stuff */
curl_easy_cleanup(curl_handle);

View File

@@ -0,0 +1,211 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* Example using an in memory PEM user certificate and RSA key to retrieve an
* https page.
* Written by Ishan SinghLevett, based on Theo Borm's cacertinmem.c.
* Note this example does not use a CA certificate, however one should be used
* if you want a properly secure connection
*/
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <curl/curl.h>
#include <stdio.h>
static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
{
fwrite(ptr,size,nmemb,stream);
return(nmemb*size);
}
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
X509 *cert = NULL;
BIO *bio = NULL;
BIO *kbio = NULL;
RSA *rsa = NULL;
int ret;
const char *mypem = /* www.cacert.org */
"-----BEGIN CERTIFICATE-----\n"\
"MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290\n"\
"IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB\n"\
"IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA\n"\
"Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO\n"\
"BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi\n"\
"MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ\n"\
"ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC\n"\
"CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ\n"\
"8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6\n"\
"zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y\n"\
"fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7\n"\
"w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc\n"\
"G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k\n"\
"epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q\n"\
"laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ\n"\
"QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU\n"\
"fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826\n"\
"YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w\n"\
"ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY\n"\
"gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe\n"\
"MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0\n"\
"IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy\n"\
"dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw\n"\
"czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0\n"\
"dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl\n"\
"aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC\n"\
"AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg\n"\
"b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB\n"\
"ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc\n"\
"nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg\n"\
"18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c\n"\
"gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl\n"\
"Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY\n"\
"sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T\n"\
"SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF\n"\
"CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum\n"\
"GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk\n"\
"zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW\n"\
"omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD\n"\
"-----END CERTIFICATE-----\n";
/*replace the XXX with the actual RSA key*/
const char *mykey =
"-----BEGIN RSA PRIVATE KEY-----\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"\
"-----END RSA PRIVATE KEY-----\n";
(void)curl; /* avoid warnings */
(void)parm; /* avoid warnings */
/* get a BIO */
bio = BIO_new_mem_buf((char *)mypem, -1);
if (bio == NULL) {
printf("BIO_new_mem_buf failed\n");
}
/* use it to read the PEM formatted certificate from memory into an X509
* structure that SSL can use
*/
cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
if (cert == NULL) {
printf("PEM_read_bio_X509 failed...\n");
}
/*tell SSL to use the X509 certificate*/
ret = SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert);
if (ret != 1) {
printf("Use certificate failed\n");
}
/*create a bio for the RSA key*/
kbio = BIO_new_mem_buf((char *)mykey, -1);
if (kbio == NULL) {
printf("BIO_new_mem_buf failed\n");
}
/*read the key bio into an RSA object*/
rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);
if (rsa == NULL) {
printf("Failed to create key bio\n");
}
/*tell SSL to use the RSA key from memory*/
ret = SSL_CTX_use_RSAPrivateKey((SSL_CTX*)sslctx, rsa);
if (ret != 1) {
printf("Use Key failed\n");
}
/* all set to go */
return CURLE_OK ;
}
int main(void)
{
CURL *ch;
CURLcode rv;
rv = curl_global_init(CURL_GLOBAL_ALL);
ch = curl_easy_init();
rv = curl_easy_setopt(ch,CURLOPT_VERBOSE, 0L);
rv = curl_easy_setopt(ch,CURLOPT_HEADER, 0L);
rv = curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);
rv = curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);
rv = curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);
rv = curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);
rv = curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);
rv = curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);
rv = curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");
/* both VERIFYPEER and VERIFYHOST are set to 0 in this case because there is
no CA certificate*/
rv = curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER, 0L);
rv = curl_easy_setopt(ch,CURLOPT_SSL_VERIFYHOST, 0L);
rv = curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
rv = curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
/* first try: retrieve page without user certificate and key -> will fail
*/
rv = curl_easy_perform(ch);
if (rv==CURLE_OK) {
printf("*** transfer succeeded ***\n");
}
else {
printf("*** transfer failed ***\n");
}
/* second try: retrieve page using user certificate and key -> will succeed
* load the certificate and key by installing a function doing the necessary
* "modifications" to the SSL CONTEXT just before link init
*/
rv = curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
rv = curl_easy_perform(ch);
if (rv==CURLE_OK) {
printf("*** transfer succeeded ***\n");
}
else {
printf("*** transfer failed ***\n");
}
curl_easy_cleanup(ch);
curl_global_cleanup();
return rv;
}

158
docs/examples/xmlstream.c Normal file
View File

@@ -0,0 +1,158 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* Stream-parse a document using the streaming Expat parser.
* Written by David Strauss
*
* Expat => http://www.libexpat.org/
*
* gcc -Wall -I/usr/local/include xmlstream.c -lcurl -lexpat -o xmlstream
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <expat.h>
#include <curl/curl.h>
struct MemoryStruct {
char *memory;
size_t size;
};
struct ParserStruct {
int ok;
size_t tags;
size_t depth;
struct MemoryStruct characters;
};
static void startElement(void *userData, const XML_Char *name, const XML_Char **atts)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
state->tags++;
state->depth++;
/* Get a clean slate for reading in character data. */
free(state->characters.memory);
state->characters.memory = NULL;
state->characters.size = 0;
}
static void characterDataHandler(void *userData, const XML_Char *s, int len)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
struct MemoryStruct *mem = &state->characters;
mem->memory = realloc(mem->memory, mem->size + len + 1);
if(mem->memory == NULL) {
/* Out of memory. */
fprintf(stderr, "Not enough memory (realloc returned NULL).\n");
state->ok = 0;
return;
}
memcpy(&(mem->memory[mem->size]), s, len);
mem->size += len;
mem->memory[mem->size] = 0;
}
static void endElement(void *userData, const XML_Char *name)
{
struct ParserStruct *state = (struct ParserStruct *) userData;
state->depth--;
printf("%5lu %10lu %s\n", state->depth, state->characters.size, name);
}
static size_t parseStreamCallback(void *contents, size_t length, size_t nmemb, void *userp)
{
XML_Parser parser = (XML_Parser) userp;
size_t real_size = length * nmemb;
struct ParserStruct *state = (struct ParserStruct *) XML_GetUserData(parser);
/* Only parse if we're not already in a failure state. */
if (state->ok && XML_Parse(parser, contents, real_size, 0) == 0) {
int error_code = XML_GetErrorCode(parser);
fprintf(stderr, "Parsing response buffer of length %lu failed with error code %d (%s).\n",
real_size, error_code, XML_ErrorString(error_code));
state->ok = 0;
}
return real_size;
}
int main(void)
{
CURL *curl_handle;
CURLcode res;
XML_Parser parser;
struct ParserStruct state;
/* Initialize the state structure for parsing. */
memset(&state, 0, sizeof(struct ParserStruct));
state.ok = 1;
/* Initialize a namespace-aware parser. */
parser = XML_ParserCreateNS(NULL, '\0');
XML_SetUserData(parser, &state);
XML_SetElementHandler(parser, startElement, endElement);
XML_SetCharacterDataHandler(parser, characterDataHandler);
/* Initalize a libcurl handle. */
curl_global_init(CURL_GLOBAL_ALL ^ CURL_GLOBAL_SSL);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://www.w3schools.com/xml/simple.xml");
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, parseStreamCallback);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)parser);
printf("Depth Characters Closing Tag\n");
/* Perform the request and any follow-up parsing. */
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else if (state.ok) {
/* Expat requires one final call to finalize parsing. */
if (XML_Parse(parser, NULL, 0, 1) == 0) {
int error_code = XML_GetErrorCode(parser);
fprintf(stderr, "Finalizing parsing failed with error code %d (%s).\n",
error_code, XML_ErrorString(error_code));
}
else {
printf(" --------------\n");
printf(" %lu tags total\n", state.tags);
}
}
/* Clean up. */
free(state.characters.memory);
XML_ParserFree(parser);
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
return 0;
}

View File

@@ -232,7 +232,7 @@ Pass a pointer to a char pointer to receive a pointer to a string holding the
most recent RTSP Session ID.
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CLIENT_CSEQ
Pass a pointer to a long to receive the next CSeq that will be used by the
application.
@@ -244,7 +244,7 @@ by the application.
unimplemented).\fP
Applications wishing to resume an RTSP session on another connection should
retreive this info before closing the active connection.
retrieve this info before closing the active connection.
.IP CURLINFO_RTSP_CSEQ_RECV
Pass a pointer to a long to receive the most recently received CSeq from the
server. If your application encounters a \fICURLE_RTSP_CSEQ_ERROR\fP then you

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, 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
@@ -68,6 +68,18 @@ code means something wrong occurred after the new state was set. See the
.SH AVAILABILITY
This function was added in libcurl 7.18.0. Before this version, there was no
explicit support for pausing transfers.
.SH "USAGE WITH THE MULTI-SOCKET INTERFACE"
Before libcurl 7.32.0, when a specific handle was unpaused with this function,
there was no particular forced rechecking or similar of the socket's state,
which made the continuation of the transfer get delayed until next
multi-socket call invoke or even longer. Alternatively, the user could
forcibly call for example curl_multi_socket_all(3) - with a rather hefty
performance penalty.
Starting in libcurl 7.32.0, unpausing a transfer will schedule a timeout
trigger for that handle 1 millisecond into the future, so that a
curl_multi_socket_action( ... CURL_SOCKET_TIMEOUT) can be used immediately
afterwards to get the transfer going again as desired.
.SH "MEMORY USE"
When pausing a read by returning the magic return code from a write callback,
the read data is already in libcurl's internal buffers so it'll have to keep

View File

@@ -342,15 +342,34 @@ argument in the closesocket callback set with
The default value of this parameter is unspecified.
(Option added in 7.21.7)
.IP CURLOPT_PROGRESSFUNCTION
Pass a pointer to a function that matches the following prototype: \fBint
function(void *clientp, double dltotal, double dlnow, double ultotal, double
ulnow); \fP. This function gets called by libcurl instead of its internal
equivalent with a frequent interval during operation (roughly once per second
or sooner) no matter if data is being transferred or not. Unknown/unused
argument values passed to the callback will be set to zero (like if you only
download data, the upload size will remain 0). Returning a non-zero value from
this callback will cause libcurl to abort the transfer and return
\fICURLE_ABORTED_BY_CALLBACK\fP.
Pass a pointer to a function that matches the following prototype:
\fBint function(void *clientp, double dltotal, double dlnow, double ultotal,
double ulnow);\fP
This function gets called by libcurl instead of its internal equivalent with a
frequent interval. While data is being transferred it will be called very
frequently, and during slow periods like when nothing is being transferred it
can slow down to about one call per second.
\fIclientp\fP is the pointer set with \fICURLOPT_PROGRESSDATA\fP, it is not
actually used by libcurl but is only passed along from the application to the
callback.
The callback gets told how much data libcurl will transfer and has
transferred, in number of bytes. \fIdltotal\fP is the total number of bytes
libcurl expects to download in this transfer. \fIdlnow\fP is the number of
bytes downloaded so far. \fIultotal\fP is the total number of bytes libcurl
expects to upload in this transfer. \fIulnow\fP is the number of bytes
uploaded so far.
Unknown/unused argument values passed to the callback will be set to zero
(like if you only download data, the upload size will remain 0). Many times
the callback will be called one or more times first, before it knows the data
sizes so a program must be made to handle that.
Returning a non-zero value from this callback will cause libcurl to abort the
transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
If you transfer data with the multi interface, this function will not be
called during periods of idleness unless you call the appropriate libcurl
@@ -358,10 +377,54 @@ function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
.IP CURLOPT_XFERINFOFUNCTION
Pass a pointer to a function that matches the following prototype:
.nf
\fBint function(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow);\fP
.fi
This function gets called by libcurl instead of its internal equivalent with a
frequent interval. While data is being transferred it will be called very
frequently, and during slow periods like when nothing is being transferred it
can slow down to about one call per second.
\fIclientp\fP is the pointer set with \fICURLOPT_XFERINFODATA\fP, it is only
passed along from the application to the callback.
The callback gets told how much data libcurl will transfer and has
transferred, in number of bytes. \fIdltotal\fP is the total number of bytes
libcurl expects to download in this transfer. \fIdlnow\fP is the number of
bytes downloaded so far. \fIultotal\fP is the total number of bytes libcurl
expects to upload in this transfer. \fIulnow\fP is the number of bytes
uploaded so far.
Unknown/unused argument values passed to the callback will be set to zero
(like if you only download data, the upload size will remain 0). Many times
the callback will be called one or more times first, before it knows the data
sizes so a program must be made to handle that.
Returning a non-zero value from this callback will cause libcurl to abort the
transfer and return \fICURLE_ABORTED_BY_CALLBACK\fP.
If you transfer data with the multi interface, this function will not be
called during periods of idleness unless you call the appropriate libcurl
function that performs transfers.
\fICURLOPT_NOPROGRESS\fP must be set to 0 to make this function actually
get called.
(Added in 7.32.0)
.IP CURLOPT_PROGRESSDATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_PROGRESSFUNCTION\fP.
The default value of this parameter is unspecified.
.IP CURLOPT_XFERINFODATA
Pass a pointer that will be untouched by libcurl and passed as the first
argument in the progress callback set with \fICURLOPT_XFERINFOFUNCTION\fP.
The default value of this parameter is unspecified. This option is an alias
for CURLOPT_PROGRESSDATA. (Added in 7.32.0)
.IP CURLOPT_HEADERFUNCTION
Pass a pointer to a function that matches the following prototype:
\fBsize_t function( void *ptr, size_t size, size_t nmemb, void
@@ -620,12 +683,20 @@ scheme://host:port/path
For a greater explanation of the format please see RFC3986.
If the given URL lacks the scheme, or protocol, part ("http://" or "ftp://"
etc), libcurl will attempt to resolve which protocol to use based on the
given host mame. If the protocol is not supported, libcurl will return
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) when you call \fIcurl_easy_perform(3)\fP
or \fIcurl_multi_perform(3)\fP. Use \fIcurl_version_info(3)\fP for detailed
information on which protocols are supported.
If the given URL lacks the scheme (such as "http://" or "ftp://" etc) then
libcurl will attempt to resolve the protocol based on one of the following
given host names:
HTTP, FTP, DICT, LDAP, IMAP, POP3 or SMTP
(POP3 and SMTP added in 7.31.0)
Should the protocol, either that specified by the scheme or deduced by libcurl
from the host name, not be supported by libcurl then
(\fICURLE_UNSUPPORTED_PROTOCOL\fP) will be returned from either the
\fIcurl_easy_perform(3)\fP or \fIcurl_multi_perform(3)\fP functions when you
call them. Use \fIcurl_version_info(3)\fP for detailed information of which
protocols are supported by the build of libcurl you are using.
The host part of the URL contains the address of the server that you want to
connect to. This can be the fully qualified domain name of the server, the
@@ -640,17 +711,23 @@ http://192.168.0.1/
http://[2001:1890:1112:1::20]/
It is also possible to specify the user name and password as part of the
host, for some protocols, when connecting to servers that require
authentication.
For example the following types of authentication support this:
It is also possible to specify the user name, password and any supported login
options as part of the host, for the following protocols, when connecting to
servers that require authentication:
http://user:password@www.example.com
ftp://user:password@ftp.example.com
pop3://user:password@mail.example.com
imap://user:password;options@mail.example.com
pop3://user:password;options@mail.example.com
smtp://user:password;options@mail.example.com
At present only IMAP, POP3 and SMTP support login options as part of the host.
For more information about the login options in URL syntax please see RFC2384,
RFC5092 and IETF draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
The port is optional and when not specified libcurl will use the default port
based on the determined or specified protocol: 80 for HTTP, 21 for FTP and 25
@@ -1040,8 +1117,8 @@ the full path name to the file you want libcurl to use as .netrc file. If this
option is omitted, and \fICURLOPT_NETRC\fP is set, libcurl will attempt to
find a .netrc file in the current user's home directory. (Added in 7.10.9)
.IP CURLOPT_USERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection. Use \fICURLOPT_HTTPAUTH\fP to decide the authentication method.
Pass a char * as parameter, pointing to a zero terminated login details string
for the connection. The format of which is: [user name]:[password];[options].
When using NTLM, you can set the domain by prepending it to the user name and
separating the domain and name with a forward (/) or backward slash (\\). Like
@@ -1054,10 +1131,18 @@ and password information to hosts using the initial host name (unless
\fICURLOPT_UNRESTRICTED_AUTH\fP is set), so if libcurl follows locations to
other hosts it will not send the user and password to those. This is enforced
to prevent accidental information leakage.
At present only IMAP, POP3 and SMTP support login options as part of the
details string. For more information about the login options please see
RFC2384, RFC5092 and IETF draft draft-earhart-url-smtp-00.txt (Added in 7.31.0).
Use \fICURLOPT_HTTPAUTH\fP to specify the authentication method for HTTP based
connections.
.IP CURLOPT_PROXYUSERPWD
Pass a char * as parameter, which should be [user name]:[password] to use for
the connection to the HTTP proxy. Use \fICURLOPT_PROXYAUTH\fP to decide
the authentication method.
the connection to the HTTP proxy.
Use \fICURLOPT_PROXYAUTH\fP to specify the authentication method.
.IP CURLOPT_USERNAME
Pass a char * as parameter, which should be pointing to the zero terminated
user name to use for the transfer.
@@ -1134,7 +1219,7 @@ Microsoft. It uses a challenge-response and hash concept similar to Digest, to
prevent the password from being eavesdropped.
You need to build libcurl with either OpenSSL, GnuTLS or NSS support for this
option to work, or build libcurl on Windows.
option to work, or build libcurl on Windows with SSPI support.
.IP CURLAUTH_NTLM_WB
NTLM delegating to winbind helper. Authentication is performed by a separate
binary application that is executed when needed. The name of the application
@@ -1195,6 +1280,15 @@ actual name and password with the \fICURLOPT_PROXYUSERPWD\fP option. The
bitmask can be constructed by or'ing together the bits listed above for the
\fICURLOPT_HTTPAUTH\fP option. As of this writing, only Basic, Digest and NTLM
work. (Added in 7.10.7)
.IP CURLOPT_SASL_IR
Pass a long. If the value is 1, curl will send the initial response to the
server in the first authentication packet in order to reduce the number of
ping pong requests. Only applicable to supporting SASL authentication
mechanisms and to the IMAP, POP3 and SMTP protocols. (Added in 7.31.0)
Note: Whilst IMAP supports this option there is no need to explicitly set it,
as libcurl can determine the feature itself when the server supports the
SASL-IR CAPABILITY.
.SH HTTP OPTIONS
.IP CURLOPT_AUTOREFERER
Pass a parameter set to 1 to enable this. When enabled, libcurl will
@@ -1392,10 +1486,12 @@ internally, your added one will be used instead. If you add a header with no
content as in 'Accept:' (no data on the right side of the colon), the
internally used header will get disabled. Thus, using this option you can add
new headers, replace internal headers and remove internal headers. To add a
header with no content, make the content be two quotes: \&"". The headers
included in the linked list must not be CRLF-terminated, because curl adds
CRLF after each header item. Failure to comply with this will result in
strange bugs because the server will most likely ignore part of the headers
header with no content (nothing to the right side of the colon), use the
form 'MyHeader;' (note the ending semicolon).
The headers included in the linked list must not be CRLF-terminated, because
curl adds CRLF after each header item. Failure to comply with this will result
in strange bugs because the server will most likely ignore part of the headers
you specified.
The first line in a request (containing the method, usually a GET or POST) is
@@ -2208,6 +2304,12 @@ changed with \fICURLOPT_SSLCERTTYPE\fP.
With NSS this can also be the nickname of the certificate you wish to
authenticate with. If you want to use a file from the current directory, please
precede it with "./" prefix, in order to avoid confusion with a nickname.
(iOS and Mac OS X only) With Secure Transport, this string must match the name
of a certificate that's in the system or user keychain. You should encode this
string in UTF-8 format in case it contains non-ASCII characters. The private
key corresponding to the certificate, and certificate chain (if any), must
also be present in the keychain. (Added in 7.31.0)
.IP CURLOPT_SSLCERTTYPE
Pass a pointer to a zero terminated string as parameter. The string should be
the format of your certificate. Supported formats are "PEM" and "DER". (Added
@@ -2216,6 +2318,10 @@ in 7.9.3)
Pass a pointer to a zero terminated string as parameter. The string should be
the file name of your private key. The default format is "PEM" and can be
changed with \fICURLOPT_SSLKEYTYPE\fP.
(iOS and Mac OS X only) This option is ignored if curl was built against Secure
Transport. Secure Transport expects the private key to be already present in
the keychain containing the certificate.
.IP CURLOPT_SSLKEYTYPE
Pass a pointer to a zero terminated string as parameter. The string should be
the format of your private key. Supported formats are "PEM", "DER" and "ENG".

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, 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
@@ -42,7 +42,7 @@ After the \fIlastitem\fP pointer follow the real arguments.
The pointers \fIfirstitem\fP and \fIlastitem\fP should both be pointing to
NULL in the first call to this function. All list-data will be allocated by
the function itself. You must call \fIcurl_formfree(3)\fP on the
\fIfirstitem\P after the form post has been done to free the resources.
\fIfirstitem\fP after the form post has been done to free the resources.
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header.
You can disable this header with \fICURLOPT_HTTPHEADER\fP as usual.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, 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
@@ -29,9 +29,9 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle);
.ad
.SH DESCRIPTION
Adds a standard easy handle to the multi stack. This function call will make
this \fImulti_handle\fP control the specified \fIeasy_handle\fP.
Furthermore, libcurl now initiates the connection associated with the
specified \fIeasy_handle\fP.
this \fImulti_handle\fP control the specified \fIeasy_handle\fP. Furthermore,
libcurl now initiates the connection associated with the specified
\fIeasy_handle\fP.
When an easy handle has been added to a multi stack, you can not and you must
not use \fIcurl_easy_perform(3)\fP on that handle!
@@ -41,6 +41,12 @@ cache (CURLOPT_DNS_USE_GLOBAL_CACHE), it will be made to use the DNS cache
that is shared between all easy handles within the multi handle when
\fIcurl_multi_add_handle(3)\fP is called.
If you have CURLMOPT_TIMERFUNCTION set in the multi handle (and you really
should if you're working event-based with \fIcurl_multi_socket_action(3)\fP
and friends), that callback will be called from within this function to ask
for an updated timer so that your main event loop will get the activity on
this handle to get started.
The easy handle will remain added until you remove it again with
\fIcurl_multi_remove_handle(3)\fP. You should remove the easy handle from the
multi stack before you terminate first the easy handle and then the multi

View File

@@ -74,9 +74,9 @@ The socket \fBcallback\fP function uses a prototype like this
int action, /* see values below */
void *userp, /* private callback pointer */
void *socketp); /* private socket pointer,
\fBNULL\fI if not
\fBNULL\fP if not
previously assigned with
\fIcurl_multi_assign(3)\fP */
\fBcurl_multi_assign(3)\fP */
.fi
The callback MUST return 0.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2012, 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
@@ -36,12 +36,17 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
This function polls on all file descriptors used by the curl easy handles
contained in the given multi handle set. It will block until activity is
detected on at least one of the handles or \fItimeout_ms\fP has passed.
Alternatively, if the multi handle has a pending internal timeout that has a
shorter expiry time than \fItimeout_ms\fP, that shorter time will be used
instead to make sure timeout accuracy is reasonably kept.
The calling application may pass additional curl_waitfd structures which are
similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call.
On completion, if \fInumfds\fP is supplied, it will be populated with the
number of file descriptors on which interesting events occured.
total number of file descriptors on which interesting events occured. This
number can include both libcurl internal descriptors as well as descriptors
provided in \fIextra_fds\fP.
If no extra file descriptors are provided and libcurl has no file descriptor
to offer to wait for, this function will return immediately.

View File

@@ -34,8 +34,10 @@ The share interface was added to enable sharing of data between curl
\&"handles".
.SH "ONE SET OF DATA - MANY TRANSFERS"
You can have multiple easy handles share data between them. Have them update
and use the \fBsame\fP cookie database or DNS cache! This way, each single
transfer will take advantage from data updates made by the other transfer(s).
and use the \fBsame\fP cookie database, DNS cache, TLS session cache! This
way, each single transfer will take advantage from data updates made by the
other transfer(s). The sharing interface, however, does not share active or
persistent connections between different easy handles.
.SH "SHARE OBJECT"
You create a shared object with \fIcurl_share_init(3)\fP. It returns a handle
for a newly created one.

View File

@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
.\" * Copyright (C) 1998 - 2011, 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
@@ -1157,13 +1157,13 @@ and install a CURLOPT_OPENSOCKETFUNCTION callback function in which addresses
are sanitized before use.
.IP "Private Resources"
A user who can control the DNS server of a domain being passed in within
a URL can change the address of the host to a local, private address
which the libcurl application will then use. e.g. The innocuous URL
http://fuzzybunnies.example.com/ could actually resolve to the IP address
of a server behind a firewall, such as 127.0.0.1 or 10.1.2.3
Apps can mitigate against this by setting a CURLOPT_OPENSOCKETFUNCTION
and checking the address before a connection.
A user who can control the DNS server of a domain being passed in within a URL
can change the address of the host to a local, private address which a
server-side libcurl-using application could then use. e.g. the innocuous URL
http://fuzzybunnies.example.com/ could actually resolve to the IP address of a
server behind a firewall, such as 127.0.0.1 or 10.1.2.3. Apps can mitigate
against this by setting a CURLOPT_OPENSOCKETFUNCTION and checking the address
before a connection.
All the malicious scenarios regarding redirected URLs apply just as well
to non-redirected URLs, if the user is allowed to specify an arbitrary URL
@@ -1178,6 +1178,19 @@ IP address and port number for a server local to the app running libcurl
but behind a firewall. Apps can mitigate against this by using the
CURLOPT_FTP_SKIP_PASV_IP option or CURLOPT_FTPPORT.
.IP "IPv6 Addresses"
libcurl will normally handle IPv6 addresses transparently and just as easily
as IPv4 addresses. That means that a sanitizing function that filters out
addressses like 127.0.0.1 isn't sufficient--the equivalent IPv6 addresses ::1,
::, 0:00::0:1, ::127.0.0.1 and ::ffff:7f00:1 supplied somehow by an attacker
would all bypass a naive filter and could allow access to undesired local
resources. IPv6 also has special address blocks like link-local and site-local
that generally shouldn't be accessed by a server-side libcurl-using
application. A poorly-configured firewall installed in a data center,
organization or server may also be configured to limit IPv4 connections but
leave IPv6 connections wide open. In some cases, the CURL_IPRESOLVE_V4 option
can be used to limit resolved addresses to IPv4 only and bypass these issues.
.IP Uploads
When uploading, a redirect can cause a local (or remote) file to be
overwritten. Apps must not allow any unsanitized URL to be passed in
@@ -1250,7 +1263,7 @@ using the Content-disposition: header to generate a file name. An application
could also use CURLINFO_EFFECTIVE_URL to generate a file name from a
server-supplied redirect URL. Special care must be taken to sanitize such
names to avoid the possibility of a malicious server supplying one like
"/etc/passwd", "\autoexec.bat" or even ".bashrc".
"/etc/passwd", "\\autoexec.bat", "prn:" or even ".bashrc".
.IP "Server Certificates"
A secure application should never use the CURLOPT_SSL_VERIFYPEER option to
@@ -1263,10 +1276,15 @@ validated certificates is potentially as insecure as a plain HTTP connection.
On a related issue, be aware that even in situations like when you have
problems with libcurl and ask someone for help, everything you reveal in order
to get best possible help might also impose certain security related
risks. Host names, user names, paths, operating system specifics, etc (not to
risks. Host names, user names, paths, operating system specifics, etc. (not to
mention passwords of course) may in fact be used by intruders to gain
additional information of a potential target.
Be sure to limit access to application logs if they could hold private or
security-related data. Besides the obvious candidates like user names and
passwords, things like URLs, cookies or even file names could also hold
sensitive data.
To avoid this problem, you must of course use your common sense. Often, you
can just edit out the sensitive data or just search/replace your true
information with faked data.
@@ -1347,10 +1365,10 @@ automatically share a lot of the data that otherwise would be kept on a
per-easy handle basis when the easy interface is used.
The DNS cache is shared between handles within a multi handle, making
subsequent name resolvings faster and the connection pool that is kept to
better allow persistent connections and connection re-use is shared. If you're
using the easy interface, you can still share these between specific easy
handles by using the share interface, see \fIlibcurl-share(3)\fP.
subsequent name resolving faster, and the connection pool that is kept to
better allow persistent connections and connection re-use is also shared. If
you're using the easy interface, you can still share these between specific
easy handles by using the share interface, see \fIlibcurl-share(3)\fP.
Some things are never shared automatically, not within multi handles, like for
example cookies so the only way to share that is with the share interface.

View File

@@ -428,7 +428,7 @@ CURLOPT_POSTREDIR 7.19.1
CURLOPT_PREQUOTE 7.9.5
CURLOPT_PRIVATE 7.10.3
CURLOPT_PROGRESSDATA 7.1
CURLOPT_PROGRESSFUNCTION 7.1
CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
CURLOPT_PROTOCOLS 7.19.4
CURLOPT_PROXY 7.1
CURLOPT_PROXYAUTH 7.10.7
@@ -456,6 +456,7 @@ CURLOPT_RTSP_SERVER_CSEQ 7.20.0
CURLOPT_RTSP_SESSION_ID 7.20.0
CURLOPT_RTSP_STREAM_URI 7.20.0
CURLOPT_RTSP_TRANSPORT 7.20.0
CURLOPT_SASL_IR 7.31.0
CURLOPT_SEEKDATA 7.18.0
CURLOPT_SEEKFUNCTION 7.18.0
CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
@@ -524,6 +525,8 @@ CURLOPT_WRITEDATA 7.9.7
CURLOPT_WRITEFUNCTION 7.1
CURLOPT_WRITEHEADER 7.1
CURLOPT_WRITEINFO 7.1
CURLOPT_XFERINFODATA 7.32.0
CURLOPT_XFERINFOFUNCTION 7.32.0
CURLPAUSE_ALL 7.18.0
CURLPAUSE_CONT 7.18.0
CURLPAUSE_RECV 7.18.0

View File

@@ -60,11 +60,16 @@ unlink (remove) certdata.txt after processing
be verbose and print out processed CAs
.SH EXIT STATUS
Returns 0 on success. Returns 1 if it fails to download data.
.SH CERTDATA FORMAT
The file format used by Mozilla for this trust information seems to be documented here:
.nf
http://p11-glue.freedesktop.org/doc/storing-trust-policy/storing-trust-existing.html
.fi
.SH SEE ALSO
.BR curl (1)
.SH HISTORY
\fBmk-ca-bundle\fP is a command line tool that is shipped as part of every
curl and libcurl release (see http://curl.haxx.se/). It was originally based
on the parse-certs script written by Roland Krikava and was later much
improved by Guenter Knauf. This manual page was written by Jan Schaumann
\&<jschauma@netmeister.org>.
improved by Guenter Knauf. This manual page was initially written by Jan
Schaumann \&<jschauma@netmeister.org>.

View File

@@ -156,12 +156,22 @@ struct curl_httppost {
HTTPPOST_CALLBACK posts */
};
/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
deprecated but was the only choice up until 7.31.0 */
typedef int (*curl_progress_callback)(void *clientp,
double dltotal,
double dlnow,
double ultotal,
double ulnow);
/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
7.32.0, it avoids floating point and provides more detailed information. */
typedef int (*curl_xferinfo_callback)(void *clientp,
curl_off_t dltotal,
curl_off_t dlnow,
curl_off_t ultotal,
curl_off_t ulnow);
#ifndef CURL_MAX_WRITE_SIZE
/* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better.
@@ -968,13 +978,16 @@ typedef enum {
/* 55 = OBSOLETE */
/* Function that will be called instead of the internal progress display
/* DEPRECATED
* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_progress_callback
* prototype defines. */
CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
/* Data passed to the progress callback */
/* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
callbacks */
CINIT(PROGRESSDATA, OBJECTPOINT, 57),
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
/* We want the referrer field set automatically when following locations */
CINIT(AUTOREFERER, LONG, 58),
@@ -1527,9 +1540,17 @@ typedef enum {
/* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
CINIT(SSL_OPTIONS, LONG, 216),
/* set the SMTP auth originator */
/* Set the SMTP auth originator */
CINIT(MAIL_AUTH, OBJECTPOINT, 217),
/* Enable/disable SASL initial response */
CINIT(SASL_IR, LONG, 218),
/* Function that will be called instead of the internal progress display
* function. This function should be defined as the curl_xferinfo_callback
* prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

View File

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

View File

@@ -94,6 +94,10 @@ add_library(
${HHEADERS} ${CSOURCES}
)
if(MSVC AND CURL_STATICLIB)
set_target_properties(${LIB_NAME} PROPERTIES STATIC_LIBRARY_FLAGS ${CMAKE_EXE_LINKER_FLAGS})
endif()
target_link_libraries(${LIB_NAME} ${CURL_LIBS})
if(WIN32)
@@ -108,14 +112,6 @@ setup_curl_dependencies(${LIB_NAME})
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
if(MSVC)
if(NOT BUILD_RELEASE_DEBUG_DIRS)
# Ugly workaround to remove the "/debug" or "/release" in each output
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "../")
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "../")
endif()
endif()
if(WIN32)
if(NOT CURL_STATICLIB)
# Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib"

View File

@@ -83,7 +83,7 @@ CFLAGS += -dWANT_IDN_PROTOTYPES
!ifdef %zlib_root
ZLIB_ROOT = $(%zlib_root)
!else
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.7
ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.8
!endif
!ifdef %libssh2_root

View File

@@ -141,7 +141,7 @@ libcurl_la_CFLAGS_EXTRA += $(CFLAG_CURL_SYMBOL_HIDING)
endif
libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LIBCURL_LIBS)
libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS)
libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA)
libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS

View File

@@ -22,7 +22,7 @@ BCCDIR = $(MAKEDIR)\..
# Edit the path below to point to the base of your Zlib sources.
!ifndef ZLIB_PATH
ZLIB_PATH = ..\..\zlib-1.2.7
ZLIB_PATH = ..\..\zlib-1.2.8
!endif
# Edit the path below to point to the base of your OpenSSL package.
@@ -52,7 +52,7 @@ LDFLAGS = -q -lq -laa -tWD
SRCDIR = .
OBJDIR = .\BCC_objs
INCDIRS = -I.;..\include
LINKLIB = $(BCCDIR)\lib\cw32mt.lib
LINKLIB = $(BCCDIR)\lib\cw32mt.lib $(BCCDIR)\lib\ws2_32.lib
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
# By default SSPI support is enabled for BCC
@@ -88,8 +88,24 @@ LINKLIB = $(LINKLIB) $(OPENSSL_PATH)\out32\ssleay32.lib $(OPENSSL_PATH)\out32\l
# Makefile.inc provides the CSOURCES and HHEADERS defines
!include Makefile.inc
OBJECTS = $(CSOURCES:.c=.obj)
PREPROCESSED = $(CSOURCES:.c=.int)
# Borland's command line librarian program TLIB version 4.5 is not capable
# of building a library when any of its objects contains an hypen in its
# name, due to a command line parsing bug. In order to workaround this, we
# build source files with hyphens in their name as objects with underscores
# using explicit compilation build rules instead of implicit ones.
NOHYPHEN = $(CSOURCES:-=_)
OBJECTS = $(NOHYPHEN:.c=.obj)
PREPROCESSED = $(NOHYPHEN:.c=.int)
# Borland's command line compiler (BCC32) version 5.5.1 integrated
# preprocessor has a bug which results in silently generating wrong
# definitions for libcurl macros such as CURL_OFF_T_C, on the other
# hand Borland's command line preprocessor (CPP32) version 5.5.1 does
# not have the bug and achieves proper results. In order to avoid the
# silent bug we first preprocess source files and later compile the
# preprocessed result.
.c.obj:
@-$(RM) $(@R).int
@@ -98,6 +114,21 @@ PREPROCESSED = $(CSOURCES:.c=.int)
all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL)
asyn_ares.obj: asyn-ares.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
asyn_thread.obj: asyn-thread.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
non_ascii.obj: non-ascii.c
@-$(RM) $(@R).int
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(?)
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
clean:
cd $(OBJDIR)
@-$(RM) $(OBJECTS)
@@ -122,7 +153,10 @@ $(LIBCURL_LIB): $(OBJECTS)
$(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
@-$(RM) $(LIBCURL_DLL)
@-$(RM) $(LIBCURL_IMPLIB)
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) $**
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) @&&!
$(**: = ^
)
!
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)

View File

@@ -13,7 +13,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
netrc.c getinfo.c transfer.c strequal.c easy.c security.c krb4.c \
curl_fnmatch.c fileinfo.c ftplistparser.c wildcard.c krb5.c \
memdebug.c http_chunks.c strtok.c connect.c llist.c hash.c multi.c \
content_encoding.c share.c http_digest.c md4.c md5.c curl_rand.c \
content_encoding.c share.c http_digest.c md4.c md5.c \
http_negotiate.c inet_pton.c strtoofft.c strerror.c amigaos.c \
hostasyn.c hostip4.c hostip6.c hostsyn.c inet_ntop.c parsedate.c \
select.c gtls.c sslgen.c tftp.c splay.c strdup.c socks.c ssh.c nss.c \
@@ -25,12 +25,13 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
curl_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_ntlm_msgs.c \
curl_sasl.c curl_schannel.c curl_multibyte.c curl_darwinssl.c \
hostcheck.c bundles.c conncache.c pipeline.c
hostcheck.c bundles.c conncache.c pipeline.c dotdot.c x509asn1.c \
gskit.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
if2ip.h speedcheck.h urldata.h curl_ldap.h ssluse.h escape.h telnet.h \
getinfo.h strequal.h krb4.h memdebug.h http_chunks.h curl_rand.h \
getinfo.h strequal.h krb4.h memdebug.h http_chunks.h \
curl_fnmatch.h wildcard.h fileinfo.h ftplistparser.h strtok.h \
connect.h llist.h hash.h content_encoding.h share.h curl_md4.h \
curl_md5.h http_digest.h http_negotiate.h inet_pton.h amigaos.h \
@@ -44,4 +45,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
asyn.h curl_ntlm.h curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h \
curl_ntlm_msgs.h curl_sasl.h curl_schannel.h curl_multibyte.h \
curl_darwinssl.h hostcheck.h bundles.h conncache.h curl_setup_once.h \
multihandle.h setup-vms.h pipeline.h
multihandle.h setup-vms.h pipeline.h dotdot.h x509asn1.h gskit.h

View File

@@ -7,14 +7,14 @@
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
##
## Hint: you can also set environment vars to control the build, f.e.:
## set ZLIB_PATH=c:/zlib-1.2.7
## set ZLIB_PATH=c:/zlib-1.2.8
## set ZLIB=1
#
###########################################################################
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH

View File

@@ -14,7 +14,7 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.

View File

@@ -73,7 +73,7 @@ LIBSSH2_PATH = ../../libssh2-1.4.3
!ENDIF
!IFNDEF ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.7
ZLIB_PATH = ../../zlib-1.2.8
!ENDIF
!IFNDEF MACHINE
@@ -103,23 +103,24 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
#############################################################
## Nothing more to do below this line!
CCNODBG = cl.exe /O2 /DNDEBUG
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
CFLAGSLIB = /DCURL_STATICLIB
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL= zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
CFLAGS = $(CFLAGS)
CCNODBG = cl.exe /O2 /DNDEBUG
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
CFLAGSSSL = /DUSE_SSLEAY /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSWINSSL = /DUSE_SCHANNEL
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
CFLAGSLIB = /DCURL_STATICLIB
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo /machine:$(MACHINE)
SSLLIBS = libeay32.lib ssleay32.lib
ZLIBLIBSDLL = zdll.lib
ZLIBLIBS = zlib.lib
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
CFLAGS = $(CFLAGS)
CFGSET = FALSE
CFGSET = FALSE
!IFDEF WINDOWS_SSPI
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
@@ -189,6 +190,18 @@ CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
######################
# release-winssl-zlib
!IF "$(CFG)" == "release-winssl-zlib"
TARGET = $(LIBCURL_STA_LIB_REL)
DIROBJ = $(CFG)
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
CFGSET = TRUE
!ENDIF
######################
# release-ssl-ssh2-zlib
@@ -515,7 +528,6 @@ X_OBJS= \
$(DIROBJ)\curl_ntlm_core.obj \
$(DIROBJ)\curl_ntlm_msgs.obj \
$(DIROBJ)\curl_ntlm_wb.obj \
$(DIROBJ)\curl_rand.obj \
$(DIROBJ)\curl_rtmp.obj \
$(DIROBJ)\curl_sasl.obj \
$(DIROBJ)\curl_schannel.obj \
@@ -523,6 +535,7 @@ X_OBJS= \
$(DIROBJ)\curl_threads.obj \
$(DIROBJ)\cyassl.obj \
$(DIROBJ)\dict.obj \
$(DIROBJ)\dotdot.obj \
$(DIROBJ)\easy.obj \
$(DIROBJ)\escape.obj \
$(DIROBJ)\file.obj \

View File

@@ -35,8 +35,8 @@ USER_CFLAGS:=
# directories where to seek for includes and libraries
OPENSSL_INC := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3/include
OPENSSL_LIB := D:/libraries/openssl/openssl-0.9.8y-vxWorks6.3
ZLIB_INC := D:/libraries/zlib/zlib-1.2.7-VxWorks6.3/zlib-1.2.7
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.7-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
ZLIB_INC := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/zlib-1.2.8
ZLIB_LIB := D:/libraries/zlib/zlib-1.2.8-VxWorks6.3/binaries/vxworks_3.1_gnu/Debug/lib
ARES_INC :=
ARES_LIB :=

View File

@@ -315,6 +315,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct ResolverResults *res = (struct ResolverResults *)
conn->async.os_specific;
CURLcode rc = CURLE_OK;
*dns = NULL;
@@ -325,19 +326,19 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
/* temp_ai ownership is moved to the connection, so we need not free-up
them */
res->temp_ai = NULL;
destroy_async_data(&conn->async);
if(!conn->async.dns) {
failf(data, "Could not resolve %s: %s (%s)",
conn->bits.proxy?"proxy":"host",
conn->host.dispname,
ares_strerror(conn->async.status));
return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
failf(data, "Could not resolve: %s (%s)",
conn->async.hostname, ares_strerror(conn->async.status));
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
CURLE_COULDNT_RESOLVE_HOST;
}
*dns = conn->async.dns;
else
*dns = conn->async.dns;
destroy_async_data(&conn->async);
}
return CURLE_OK;
return rc;
}
/*
@@ -415,37 +416,12 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(entry)
*entry = conn->async.dns;
if(!conn->async.dns) {
/* a name was not resolved */
if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
if(conn->bits.proxy) {
failf(data, "Resolving proxy timed out: %s", conn->proxy.dispname);
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Resolving host timed out: %s", conn->host.dispname);
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else if(conn->async.done) {
if(conn->bits.proxy) {
failf(data, "Could not resolve proxy: %s (%s)", conn->proxy.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_PROXY;
}
else {
failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
ares_strerror(conn->async.status));
rc = CURLE_COULDNT_RESOLVE_HOST;
}
}
else
rc = CURLE_OPERATION_TIMEDOUT;
if(rc)
/* close the connection, since we can't return failure here without
cleaning up this connection properly */
cleaning up this connection properly.
TODO: remove this action from here, it is not a name resolver decision.
*/
conn->bits.close = TRUE;
}
return rc;
}
@@ -614,8 +590,19 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
char *servers)
{
CURLcode result = CURLE_NOT_BUILT_IN;
int ares_result;
/* If server is NULL or empty, this would purge all DNS servers
* from ares library, which will cause any and all queries to fail.
* So, just return OK if none are configured and don't actually make
* any changes to c-ares. This lets c-ares use it's defaults, which
* it gets from the OS (for instance from /etc/resolv.conf on Linux).
*/
if(!(servers && servers[0]))
return CURLE_OK;
#if (ARES_VERSION >= 0x010704)
int ares_result = ares_set_servers_csv(data->state.resolver, servers);
ares_result = ares_set_servers_csv(data->state.resolver, servers);
switch(ares_result) {
case ARES_SUCCESS:
result = CURLE_OK;
@@ -632,7 +619,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
}
#else /* too old c-ares version! */
(void)data;
(void)servers;
(void)(ares_result);
#endif
return result;
}

View File

@@ -41,26 +41,12 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
#include <unistd.h>
/* The last #include file should be: */
#include "memdebug.h"
#include "hostcheck.h"
/* SSL_read is opied from axTLS compat layer */
static int SSL_read(SSL *ssl, void *buf, int num)
{
uint8_t *read_buf;
int ret;
while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
if(ret > SSL_OK) {
memcpy(buf, read_buf, ret > num ? num : ret);
}
return ret;
}
/* Global axTLS init, called from Curl_ssl_init() */
int Curl_axtls_init(void)
{
@@ -131,31 +117,40 @@ static CURLcode map_error_to_curl(int axtls_err)
static Curl_recv axtls_recv;
static Curl_send axtls_send;
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
*/
CURLcode
Curl_axtls_connect(struct connectdata *conn,
int sockindex)
static void free_ssl_structs(struct ssl_connect_data *connssl)
{
if(connssl->ssl) {
ssl_free (connssl->ssl);
connssl->ssl = NULL;
}
if(connssl->ssl_ctx) {
ssl_ctx_free(connssl->ssl_ctx);
connssl->ssl_ctx = NULL;
}
}
/*
* For both blocking and non-blocking connects, this function sets up the
* ssl context and state. This function is called after the TCP connect
* has completed.
*/
static CURLcode connect_prep(struct connectdata *conn, int sockindex)
{
struct SessionHandle *data = conn->data;
SSL_CTX *ssl_ctx;
SSL *ssl;
SSL *ssl = NULL;
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
int i, ssl_fcn_return;
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
const char *peer_CN;
uint32_t dns_altname_index;
const char *dns_altname;
int8_t found_subject_alt_names = 0;
int8_t found_subject_alt_name_matching_conn = 0;
/* Assuming users will not compile in custom key/cert to axTLS */
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
/* Assuming users will not compile in custom key/cert to axTLS.
* Also, even for blocking connects, use axTLS non-blocking feature.
*/
uint32_t client_option = SSL_NO_DEFAULT_KEY |
SSL_SERVER_VERIFY_LATER |
SSL_CONNECT_IN_PARTS;
if(conn->ssl[sockindex].state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
@@ -184,6 +179,9 @@ Curl_axtls_connect(struct connectdata *conn,
return CURLE_SSL_CONNECT_ERROR;
}
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
conn->ssl[sockindex].ssl = NULL;
/* Load the trusted CA cert bundle file */
if(data->set.ssl.CAfile) {
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
@@ -191,7 +189,6 @@ Curl_axtls_connect(struct connectdata *conn,
infof(data, "error reading ca cert file %s \n",
data->set.ssl.CAfile);
if(data->set.ssl.verifypeer) {
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -225,7 +222,6 @@ Curl_axtls_connect(struct connectdata *conn,
if(cert_types[i] == 0) {
failf(data, "%s is not x509 or pkcs12 format",
data->set.str[STRING_CERT]);
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CERTPROBLEM;
}
}
@@ -250,7 +246,6 @@ Curl_axtls_connect(struct connectdata *conn,
if(key_types[i] == 0) {
failf(data, "Failure: %s is not a supported key file",
data->set.str[STRING_KEY]);
Curl_axtls_close(conn, sockindex);
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -271,14 +266,25 @@ Curl_axtls_connect(struct connectdata *conn,
else
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
/* Check to make sure handshake was ok. */
ssl_fcn_return = ssl_handshake_status(ssl);
if(ssl_fcn_return != SSL_OK) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
infof (data, "handshake completed successfully\n");
conn->ssl[sockindex].ssl = ssl;
return CURLE_OK;
}
/*
* For both blocking and non-blocking connects, this function finalizes the
* SSL connection.
*/
static CURLcode connect_finish(struct connectdata *conn, int sockindex)
{
struct SessionHandle *data = conn->data;
SSL *ssl = conn->ssl[sockindex].ssl;
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
const char *peer_CN;
uint32_t dns_altname_index;
const char *dns_altname;
int8_t found_subject_alt_names = 0;
int8_t found_subject_alt_name_matching_conn = 0;
/* 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?
@@ -289,7 +295,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(ssl_verify_cert(ssl) != SSL_OK) {
Curl_axtls_close(conn, sockindex);
failf(data, "server cert verify failed");
return CURLE_SSL_CONNECT_ERROR;
return CURLE_PEER_FAILED_VERIFICATION;
}
}
else
@@ -306,7 +312,6 @@ Curl_axtls_connect(struct connectdata *conn,
* this, but a couple fields are available.
*/
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
risk of an inifite loop */
for(dns_altname_index = 0; ; dns_altname_index++) {
@@ -326,20 +331,29 @@ Curl_axtls_connect(struct connectdata *conn,
/* RFC2818 checks */
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;
if(data->set.ssl.verifyhost) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tsubjectAltName(s) do not match %s\n",
conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
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) {
/* Similar behaviour to the OpenSSL interface */
Curl_axtls_close(conn, sockindex);
failf(data, "unable to obtain common name from peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
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;
}
else
infof(data, "unable to obtain common name from peer certificate");
}
else {
if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
@@ -359,8 +373,6 @@ Curl_axtls_connect(struct connectdata *conn,
/* General housekeeping */
conn->ssl[sockindex].state = ssl_connection_complete;
conn->ssl[sockindex].ssl = ssl;
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
conn->recv[sockindex] = axtls_recv;
conn->send[sockindex] = axtls_send;
@@ -374,6 +386,107 @@ Curl_axtls_connect(struct connectdata *conn,
return CURLE_OK;
}
/*
* Use axTLS's non-blocking connection feature to open an SSL connection.
* This is called after a TCP connection is already established.
*/
CURLcode Curl_axtls_connect_nonblocking(
struct connectdata *conn,
int sockindex,
bool *done)
{
CURLcode conn_step;
int ssl_fcn_return;
*done = FALSE;
/* connectdata is calloc'd and connecting_state is only changed in this
function, so this is safe, as the state is effectively initialized. */
if(conn->ssl[sockindex].connecting_state == ssl_connect_1) {
conn_step = connect_prep(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
conn->ssl[sockindex].connecting_state = ssl_connect_2;
}
if(conn->ssl[sockindex].connecting_state == ssl_connect_2) {
/* Check to make sure handshake was ok. */
if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) {
ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
else {
return CURLE_OK; /* Return control to caller for retries */
}
}
infof (conn->data, "handshake completed successfully\n");
conn->ssl[sockindex].connecting_state = ssl_connect_3;
}
if(conn->ssl[sockindex].connecting_state == ssl_connect_3) {
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Reset connect state */
conn->ssl[sockindex].connecting_state = ssl_connect_1;
*done = TRUE;
return CURLE_OK;
}
/* Unrecognized state. Things are very bad. */
conn->ssl[sockindex].state = ssl_connection_none;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
/* Return value perhaps not strictly correct, but distinguishes the issue.*/
return CURLE_BAD_FUNCTION_ARGUMENT;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic for a blocking connect.
*/
CURLcode
Curl_axtls_connect(struct connectdata *conn,
int sockindex)
{
CURLcode conn_step = connect_prep(conn, sockindex);
int ssl_fcn_return;
SSL *ssl = conn->ssl[sockindex].ssl;
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Check to make sure handshake was ok. */
while(ssl_handshake_status(ssl) != SSL_OK) {
ssl_fcn_return = ssl_read(ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
usleep(10000);
}
infof (conn->data, "handshake completed successfully\n");
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
return CURLE_OK;
}
/* return number of sent (non-SSL) bytes */
static ssize_t axtls_send(struct connectdata *conn,
@@ -407,7 +520,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
infof(conn->data, " Curl_axtls_close\n");
if(connssl->ssl) {
/* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
axTLS compat layer does nothing for SSL_shutdown */
@@ -415,13 +528,7 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
equivalent. ssl_free and ssl_ctx_free close things.
SSL_set_connect_state(connssl->handle); */
ssl_free (connssl->ssl);
connssl->ssl = NULL;
}
if(connssl->ssl_ctx) {
ssl_ctx_free (connssl->ssl_ctx);
connssl->ssl_ctx = NULL;
}
free_ssl_structs(connssl);
}
/*
@@ -436,8 +543,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data;
char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
to be at least 120 bytes long. */
uint8_t *buf;
ssize_t nread;
infof(conn->data, " Curl_axtls_shutdown\n");
@@ -457,9 +563,10 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
sizeof(buf));
notify alert from the server. buf is managed internally by
axTLS and will be released upon calling ssl_free via
free_ssl_structs. */
nread = (ssize_t)ssl_read(connssl->ssl, &buf);
if(nread < SSL_OK) {
failf(data, "close notify alert not received during shutdown");
@@ -476,8 +583,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
retval = -1;
}
ssl_free (connssl->ssl);
connssl->ssl = NULL;
free_ssl_structs(connssl);
}
return retval;
}
@@ -490,26 +596,36 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
{
struct ssl_connect_data *connssl = &conn->ssl[num];
ssize_t ret = 0;
uint8_t *read_buf;
infof(conn->data, " axtls_recv\n");
*err = CURLE_OK;
if(connssl) {
ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf, (int)buffersize);
/* axTLS isn't terribly generous about error reporting */
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
team approves proposed fix. */
if(ret == -3 ) {
ret = ssl_read(connssl->ssl, &read_buf);
if(ret > SSL_OK) {
/* ssl_read returns SSL_OK if there is more data to read, so if it is
larger, then all data has been read already. */
memcpy(buf, read_buf,
(size_t)ret > buffersize ? buffersize : (size_t)ret);
}
else if(ret == SSL_OK) {
/* more data to be read, signal caller to call again */
*err = CURLE_AGAIN;
ret = -1;
}
else if(ret == -3) {
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
team approves proposed fix. */
Curl_axtls_close(conn, num);
}
else if(ret < 0) {
failf(conn->data, "axTLS recv error (%d)", (int)ret);
else {
failf(conn->data, "axTLS recv error (%d)", ret);
*err = map_error_to_curl(ret);
return -1;
ret = -1;
}
}
*err = CURLE_OK;
return ret;
}

View File

@@ -30,6 +30,10 @@
int Curl_axtls_init(void);
int Curl_axtls_cleanup(void);
CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_axtls_connect_nonblocking(
struct connectdata *conn,
int sockindex,
bool *done);
/* tell axTLS to close down all open information regarding connections (and
thus session ID caching etc) */
@@ -47,6 +51,7 @@ int Curl_axtls_check_cxn(struct connectdata *conn);
#define curlssl_init Curl_axtls_init
#define curlssl_cleanup Curl_axtls_cleanup
#define curlssl_connect Curl_axtls_connect
#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking
#define curlssl_session_free(x) Curl_axtls_session_free(x)
#define curlssl_close_all Curl_axtls_close_all
#define curlssl_close Curl_axtls_close

View File

@@ -277,21 +277,27 @@
/* Define if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
strdup(). */
#define __cplusplus__strings__
/* Define if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define if you have the `strcmpi' function. */
#undef HAVE_STRCMPI
#define HAVE_STRCMPI
/* Define if you have the `stricmp' function. */
#define HAVE_STRICMP
/* Define if you have the `strdup' function. */
#undef HAVE_STRDUP
#define HAVE_STRDUP
/* Define if you have the `strftime' function. */
#define HAVE_STRFTIME
/* Define if you have the `stricmp' function. */
#undef HAVE_STRICMP
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H
@@ -525,6 +531,9 @@
/* Define to use the QsoSSL package. */
#define USE_QSOSSL
/* Define to use the GSKit package. */
#undef USE_GSKIT
/* Use the system keyring as the default CA bundle. */
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"

View File

@@ -38,8 +38,6 @@
/* The last #include file should be: */
#include "memdebug.h"
#define CONNECTION_HASH_SIZE 97
static void free_bundle_hash_entry(void *freethis)
{
struct connectbundle *b = (struct connectbundle *) freethis;
@@ -47,7 +45,7 @@ static void free_bundle_hash_entry(void *freethis)
Curl_bundle_destroy(b);
}
struct conncache *Curl_conncache_init(void)
struct conncache *Curl_conncache_init(int size)
{
struct conncache *connc;
@@ -55,7 +53,7 @@ struct conncache *Curl_conncache_init(void)
if(!connc)
return NULL;
connc->hash = Curl_hash_alloc(CONNECTION_HASH_SIZE, Curl_hash_str,
connc->hash = Curl_hash_alloc(size, Curl_hash_str,
Curl_str_key_compare, free_bundle_hash_entry);
if(!connc->hash) {

View File

@@ -27,7 +27,7 @@ struct conncache {
size_t num_connections;
};
struct conncache *Curl_conncache_init(void);
struct conncache *Curl_conncache_init(int size);
void Curl_conncache_destroy(struct conncache *connc);

View File

@@ -413,23 +413,22 @@ static CURLcode bindlocal(struct connectdata *conn,
if(af == AF_INET6) {
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
char *scope_ptr = strchr(myhost, '%');
if(scope_ptr) *(scope_ptr++) = 0;
if(scope_ptr)
*(scope_ptr++) = 0;
#endif
if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
si6->sin6_family = AF_INET6;
si6->sin6_port = htons(port);
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
if(scope_ptr) {
/* The "myhost" string either comes from Curl_if2ip or
from Curl_printable_address. The latter returns only
numeric scope IDs and the former returns none at all.
So the scope ID, if present, is known to be numeric */
if(scope_ptr)
/* The "myhost" string either comes from Curl_if2ip or from
Curl_printable_address. The latter returns only numeric scope
IDs and the former returns none at all. So the scope ID, if
present, is known to be numeric */
si6->sin6_scope_id = atoi(scope_ptr);
}
}
#endif
sizeof_sa = sizeof(struct sockaddr_in6);
}
sizeof_sa = sizeof(struct sockaddr_in6);
}
else
#endif
@@ -1145,7 +1144,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
if(sockfd == CURL_SOCKET_BAD) {
/* no good connect was made */
failf(data, "couldn't connect to %s at %s:%d",
failf(data, "couldn't connect to %s at %s:%ld",
conn->bits.proxy?"proxy":"host",
conn->bits.proxy?conn->proxy.name:conn->host.name, conn->port);
return CURLE_COULDNT_CONNECT;
@@ -1240,7 +1239,7 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
* 'conn' can be NULL, beware!
*/
int Curl_closesocket(struct connectdata *conn,
curl_socket_t sock)
curl_socket_t sock)
{
if(conn && conn->fclosesocket) {
if((sock == conn->sock[SECONDARYSOCKET]) &&
@@ -1252,7 +1251,13 @@ int Curl_closesocket(struct connectdata *conn,
else
return conn->fclosesocket(conn->closesocket_client, sock);
}
return sclose(sock);
sclose(sock);
if(conn)
/* tell the multi-socket code about this */
Curl_multi_closed(conn, sock);
return 0;
}
/*

View File

@@ -89,6 +89,7 @@ Example set of cookies:
#include "strequal.h"
#include "strtok.h"
#include "sendf.h"
#include "slist.h"
#include "curl_memory.h"
#include "share.h"
#include "strtoofft.h"
@@ -106,6 +107,8 @@ static void freecookie(struct Cookie *co)
free(co->domain);
if(co->path)
free(co->path);
if(co->spath)
free(co->spath);
if(co->name)
free(co->name);
if(co->value)
@@ -143,6 +146,116 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
return FALSE;
}
/*
* matching cookie path and url path
* RFC6265 5.1.4 Paths and Path-Match
*/
static bool pathmatch(const char* cookie_path, const char* request_uri)
{
size_t cookie_path_len;
size_t uri_path_len;
char* uri_path = NULL;
char* pos;
bool ret = FALSE;
/* cookie_path must not have last '/' separator. ex: /sample */
cookie_path_len = strlen(cookie_path);
if(1 == cookie_path_len) {
/* cookie_path must be '/' */
return TRUE;
}
uri_path = strdup(request_uri);
if(!uri_path)
return FALSE;
pos = strchr(uri_path, '?');
if(pos)
*pos = 0x0;
/* #-fragments are already cut off! */
if(0 == strlen(uri_path) || uri_path[0] != '/') {
free(uri_path);
uri_path = strdup("/");
if(!uri_path)
return FALSE;
}
/* here, RFC6265 5.1.4 says
4. Output the characters of the uri-path from the first character up
to, but not including, the right-most %x2F ("/").
but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
without redirect.
Ignore this algorithm because /hoge is uri path for this case
(uri path is not /).
*/
uri_path_len = strlen(uri_path);
if(uri_path_len < cookie_path_len) {
ret = FALSE;
goto pathmatched;
}
/* not using checkprefix() because matching should be case-sensitive */
if(strncmp(cookie_path, uri_path, cookie_path_len)) {
ret = FALSE;
goto pathmatched;
}
/* The cookie-path and the uri-path are identical. */
if(cookie_path_len == uri_path_len) {
ret = TRUE;
goto pathmatched;
}
/* here, cookie_path_len < url_path_len */
if(uri_path[cookie_path_len] == '/') {
ret = TRUE;
goto pathmatched;
}
ret = FALSE;
pathmatched:
free(uri_path);
return ret;
}
/*
* cookie path sanitize
*/
static char *sanitize_cookie_path(const char *cookie_path)
{
size_t len;
char *new_path = strdup(cookie_path);
if(!new_path)
return NULL;
/* some stupid site sends path attribute with '"'. */
if(new_path[0] == '\"') {
memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
}
if(new_path[strlen(new_path) - 1] == '\"') {
new_path[strlen(new_path) - 1] = 0x0;
}
/* RFC6265 5.2.4 The Path Attribute */
if(new_path[0] != '/') {
/* Let cookie-path be the default-path. */
free(new_path);
new_path = strdup("/");
return new_path;
}
/* convert /hoge/ to /hoge */
len = strlen(new_path);
if(1 < len && new_path[len - 1] == '/') {
new_path[len - 1] = 0x0;
}
return new_path;
}
/*
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
*/
@@ -184,6 +297,9 @@ static void strstore(char **str, const char *newstr)
*
* Add a single cookie line to the cookie keeping object.
*
* Be aware that sometimes we get an IP-only host name, and that might also be
* a numerical IPv6 address.
*
***************************************************************************/
struct Cookie *
@@ -288,72 +404,39 @@ Curl_cookie_add(struct SessionHandle *data,
badcookie = TRUE; /* out of memory bad */
break;
}
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
break;
}
}
else if(Curl_raw_equal("domain", name)) {
/* note that this name may or may not have a preceding dot, but
we don't care about that, we treat the names the same anyway */
const char *domptr=whatptr;
const char *nextptr;
int dotcount=1;
/* Count the dots, we need to make sure that there are enough
of them. */
/* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0])
/* don't count the initial dot, assume it */
domptr++;
whatptr++; /* ignore preceding dot */
do {
nextptr = strchr(domptr, '.');
if(nextptr) {
if(domptr != nextptr)
dotcount++;
domptr = nextptr+1;
if(!domain || tailmatch(whatptr, domain)) {
const char *tailptr=whatptr;
if(tailptr[0] == '.')
tailptr++;
strstore(&co->domain, tailptr); /* don't prefix w/dots
internally */
if(!co->domain) {
badcookie = TRUE;
break;
}
} while(nextptr);
/* The original Netscape cookie spec defined that this domain name
MUST have three dots (or two if one of the seven holy TLDs),
but it seems that these kinds of cookies are in use "out there"
so we cannot be that strict. I've therefore lowered the check
to not allow less than two dots. */
if(dotcount < 2) {
/* Received and skipped a cookie with a domain using too few
dots. */
badcookie=TRUE; /* mark this as a bad cookie */
infof(data, "skipped cookie with illegal dotcount domain: %s\n",
whatptr);
co->tailmatch=TRUE; /* we always do that if the domain name was
given */
}
else {
/* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0])
whatptr++; /* ignore preceding dot */
if(!domain || tailmatch(whatptr, domain)) {
const char *tailptr=whatptr;
if(tailptr[0] == '.')
tailptr++;
strstore(&co->domain, tailptr); /* don't prefix w/dots
internally */
if(!co->domain) {
badcookie = TRUE;
break;
}
co->tailmatch=TRUE; /* we always do that if the domain name was
given */
}
else {
/* we did not get a tailmatch and then the attempted set domain
is not a domain to which the current host belongs. Mark as
bad. */
badcookie=TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
whatptr);
}
/* we did not get a tailmatch and then the attempted set domain
is not a domain to which the current host belongs. Mark as
bad. */
badcookie=TRUE;
infof(data, "skipped cookie with bad tailmatch domain: %s\n",
whatptr);
}
}
else if(Curl_raw_equal("version", name)) {
@@ -461,6 +544,9 @@ Curl_cookie_add(struct SessionHandle *data,
if(co->path) {
memcpy(co->path, path, pathlen);
co->path[pathlen]=0; /* zero terminate */
co->spath = sanitize_cookie_path(co->path);
if(!co->spath)
badcookie = TRUE; /* out of memory bad */
}
else
badcookie = TRUE;
@@ -512,12 +598,6 @@ Curl_cookie_add(struct SessionHandle *data,
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
/* Here's a quick check to eliminate normal HTTP-headers from this */
if(!firstptr || strchr(firstptr, ':')) {
free(co);
return NULL;
}
/* Now loop through the fields and init the struct we already have
allocated */
for(ptr=firstptr, fields=0; ptr && !badcookie;
@@ -552,12 +632,21 @@ Curl_cookie_add(struct SessionHandle *data,
co->path = strdup(ptr);
if(!co->path)
badcookie = TRUE;
else {
co->spath = sanitize_cookie_path(co->path);
if(!co->spath) {
badcookie = TRUE; /* out of memory bad */
}
}
break;
}
/* this doesn't look like a path, make one up! */
co->path = strdup("/");
if(!co->path)
badcookie = TRUE;
co->spath = strdup("/");
if(!co->spath)
badcookie = TRUE;
fields++; /* add a field and fall down to secure */
/* FALLTHROUGH */
case 3:
@@ -628,14 +717,14 @@ Curl_cookie_add(struct SessionHandle *data,
if(replace_old) {
/* the domains were identical */
if(clist->path && co->path) {
if(Curl_raw_equal(clist->path, co->path)) {
if(clist->spath && co->spath) {
if(Curl_raw_equal(clist->spath, co->spath)) {
replace_old = TRUE;
}
else
replace_old = FALSE;
}
else if(!clist->path && !co->path)
else if(!clist->spath && !co->spath)
replace_old = TRUE;
else
replace_old = FALSE;
@@ -664,6 +753,8 @@ Curl_cookie_add(struct SessionHandle *data,
free(clist->domain);
if(clist->path)
free(clist->path);
if(clist->spath)
free(clist->spath);
if(clist->expirestr)
free(clist->expirestr);
@@ -858,10 +949,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
/* now check the left part of the path with the cookies path
requirement */
if(!co->path ||
/* not using checkprefix() because matching should be
case-sensitive */
!strncmp(co->path, path, strlen(co->path)) ) {
if(!co->spath || pathmatch(co->spath, path) ) {
/* and now, we know this is a match and we should create an
entry for the return-linked-list */
@@ -1145,9 +1233,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
curl_slist_free_all(list);
return NULL;
}
beg = curl_slist_append(list, line);
free(line);
beg = Curl_slist_append_nodup(list, line);
if(!beg) {
free(line);
curl_slist_free_all(list);
return NULL;
}

View File

@@ -29,7 +29,8 @@ struct Cookie {
struct Cookie *next; /* next in the chain */
char *name; /* <this> = value */
char *value; /* name = <this> */
char *path; /* path = <this> */
char *path; /* path = <this> which is in Set-Cookie: */
char *spath; /* sanitized cookie path */
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */

View File

@@ -38,9 +38,54 @@
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CommonCrypto/CommonDigest.h>
/* The Security framework has changed greatly between iOS and different OS X
versions, and we will try to support as many of them as we can (back to
Leopard and iOS 5) by using macros and weak-linking.
IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
you must build this project against the 10.8 SDK or later. */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
#error "The darwinssl back-end requires Leopard or later."
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
#define CURL_BUILD_IOS 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
(You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
environmental variable.) */
#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
#define CURL_BUILD_IOS 1
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
#define CURL_BUILD_MAC_10_7 0
#define CURL_BUILD_MAC_10_8 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
#define CURL_SUPPORT_MAC_10_8 0
#else
#error "The darwinssl back-end requires iOS or OS X."
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#if CURL_BUILD_MAC
#include <sys/sysctl.h>
#endif
#endif /* CURL_BUILD_MAC */
#include "urldata.h"
#include "sendf.h"
@@ -61,16 +106,6 @@
#define ioErr -36
#define paramErr -50
/* In Mountain Lion and iOS 5, Apple made some changes to the API. They
added TLS 1.1 and 1.2 support, and deprecated and replaced some
functions. You need to build against the Mountain Lion or iOS 5 SDK
or later to get TLS 1.1 or 1.2 support working in cURL. We'll weak-link
to the newer functions and use them if present in the user's OS.
Builders: If you want TLS 1.1 and 1.2 but still want to retain support
for older cats, don't forget to set the MACOSX_DEPLOYMENT_TARGET
environmental variable prior to building cURL. */
/* The following two functions were ripped from Apple sample code,
* with some modifications: */
static OSStatus SocketRead(SSLConnectionRef connection,
@@ -361,7 +396,7 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
break;
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* TLS 1.0 with ECDSA (RFC 4492) */
case TLS_ECDH_ECDSA_WITH_NULL_SHA:
return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
@@ -438,8 +473,8 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
break;
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
/* TLS 1.2 (RFC 5246) */
case TLS_RSA_WITH_NULL_MD5:
return "TLS_RSA_WITH_NULL_MD5";
@@ -624,12 +659,12 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
break;
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
}
return "TLS_NULL_WITH_NULL_NULL";
}
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
{
int mib[2];
@@ -658,7 +693,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
*minor = atoi(os_version_minor);
free(os_version);
}
#endif
#endif /* CURL_BUILD_MAC */
/* Apple provides a myriad of ways of getting information about a certificate
into a string. Some aren't available under iOS or newer cats. So here's
@@ -668,29 +703,122 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
{
CFStringRef server_cert_summary = CFSTR("(null)");
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_IOS
/* iOS: There's only one way to do this. */
server_cert_summary = SecCertificateCopySubjectSummary(cert);
#else
#if defined(__MAC_10_7)
#if CURL_BUILD_MAC_10_7
/* Lion & later: Get the long description if we can. */
if(SecCertificateCopyLongDescription != NULL)
server_cert_summary =
SecCertificateCopyLongDescription(NULL, cert, NULL);
else
#endif /* defined(__MAC_10_7) */
#if defined(__MAC_10_6)
#endif /* CURL_BUILD_MAC_10_7 */
#if CURL_BUILD_MAC_10_6
/* Snow Leopard: Get the certificate summary. */
if(SecCertificateCopySubjectSummary != NULL)
server_cert_summary = SecCertificateCopySubjectSummary(cert);
else
#endif /* defined(__MAC_10_6) */
#endif /* CURL_BUILD_MAC_10_6 */
/* Leopard is as far back as we go... */
(void)SecCertificateCopyCommonName(cert, &server_cert_summary);
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
return server_cert_summary;
}
#if CURL_SUPPORT_MAC_10_7
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
deprecation warnings, so let's not compile this unless it's necessary: */
static OSStatus CopyIdentityWithLabelOldSchool(char *label,
SecIdentityRef *out_c_a_k)
{
OSStatus status = errSecItemNotFound;
SecKeychainAttributeList attr_list;
SecKeychainAttribute attr;
SecKeychainSearchRef search = NULL;
SecCertificateRef cert = NULL;
/* Set up the attribute list: */
attr_list.count = 1L;
attr_list.attr = &attr;
/* Set up our lone search criterion: */
attr.tag = kSecLabelItemAttr;
attr.data = label;
attr.length = (UInt32)strlen(label);
/* Start searching: */
status = SecKeychainSearchCreateFromAttributes(NULL,
kSecCertificateItemClass,
&attr_list,
&search);
if(status == noErr) {
status = SecKeychainSearchCopyNext(search,
(SecKeychainItemRef *)&cert);
if(status == noErr && cert) {
/* If we found a certificate, does it have a private key? */
status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
CFRelease(cert);
}
}
if(search)
CFRelease(search);
return status;
}
#endif /* CURL_SUPPORT_MAC_10_7 */
static OSStatus CopyIdentityWithLabel(char *label,
SecIdentityRef *out_cert_and_key)
{
OSStatus status = errSecItemNotFound;
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
kSecClassIdentity was introduced in Lion. If both exist, let's use them
to find the certificate. */
if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
CFTypeRef keys[4];
CFTypeRef values[4];
CFDictionaryRef query_dict;
CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
kCFStringEncodingUTF8);
/* Set up our search criteria and expected results: */
values[0] = kSecClassIdentity; /* we want a certificate and a key */
keys[0] = kSecClass;
values[1] = kCFBooleanTrue; /* we want a reference */
keys[1] = kSecReturnRef;
values[2] = kSecMatchLimitOne; /* one is enough, thanks */
keys[2] = kSecMatchLimit;
/* identity searches need a SecPolicyRef in order to work */
values[3] = SecPolicyCreateSSL(false, label_cf);
keys[3] = kSecMatchPolicy;
query_dict = CFDictionaryCreate(NULL, (const void **)keys,
(const void **)values, 4L,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFRelease(values[3]);
CFRelease(label_cf);
/* Do we have a match? */
status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
CFRelease(query_dict);
}
else {
#if CURL_SUPPORT_MAC_10_7
/* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* CURL_SUPPORT_MAC_10_7 */
}
#elif CURL_SUPPORT_MAC_10_7
/* For developers building on older cats, we have no choice but to fall back
to SecKeychainSearch. */
status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
return status;
}
static CURLcode darwinssl_connect_step1(struct connectdata *conn,
int sockindex)
{
@@ -701,17 +829,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
struct in6_addr addr;
#else
struct in_addr addr;
#endif
#endif /* ENABLE_IPV6 */
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
char *ssl_sessionid;
size_t ssl_sessionid_len;
OSStatus err = noErr;
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
int darwinver_maj = 0, darwinver_min = 0;
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
#endif
#endif /* CURL_BUILD_MAC */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
if(connssl->ssl_ctx)
CFRelease(connssl->ssl_ctx);
@@ -723,7 +853,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
/* The old ST API does not exist under iOS, so don't compile it: */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
if(connssl->ssl_ctx)
(void)SSLDisposeContext(connssl->ssl_ctx);
err = SSLNewContext(false, &(connssl->ssl_ctx));
@@ -731,7 +861,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
if(connssl->ssl_ctx)
@@ -741,11 +871,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
/* check to see if we've been told to use an explicit SSL/TLS version */
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLSetProtocolVersionMax != NULL) {
switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT: default:
@@ -761,12 +891,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
(void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocolAll,
false);
@@ -802,12 +936,16 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
@@ -827,9 +965,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
case CURL_SSLVERSION_SSLv2:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
break;
case CURL_SSLVERSION_SSLv3:
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
@@ -837,16 +979,65 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
}
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
/* No need to load certificates here. SecureTransport uses the Keychain
* (which is also part of the Security framework) to evaluate trust. */
if(data->set.str[STRING_KEY]) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.\n");
}
if(data->set.str[STRING_CERT]) {
SecIdentityRef cert_and_key = NULL;
/* User wants to authenticate with a client cert. Look for it: */
err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key);
if(err == noErr) {
SecCertificateRef cert = NULL;
CFTypeRef certs_c[1];
CFArrayRef certs;
/* If we found one, print it out: */
err = SecIdentityCopyCertificate(cert_and_key, &cert);
if(err == noErr) {
CFStringRef cert_summary = CopyCertSubject(cert);
char cert_summary_c[128];
if(cert_summary) {
memset(cert_summary_c, 0, 128);
if(CFStringGetCString(cert_summary,
cert_summary_c,
128,
kCFStringEncodingUTF8)) {
infof(data, "Client certificate: %s\n", cert_summary_c);
}
CFRelease(cert_summary);
CFRelease(cert);
}
}
certs_c[0] = cert_and_key;
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
&kCFTypeArrayCallBacks);
err = SSLSetCertificate(connssl->ssl_ctx, certs);
if(certs)
CFRelease(certs);
if(err != noErr) {
failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
return CURLE_SSL_CERTPROBLEM;
}
CFRelease(cert_and_key);
}
else {
failf(data, "SSL: Can't find the certificate \"%s\" and its private key "
"in the Keychain.", data->set.str[STRING_CERT]);
return CURLE_SSL_CERTPROBLEM;
}
}
/* SSL always tries to verify the peer, this only says whether it should
* fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */
#if defined(__MAC_10_6) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
/* Snow Leopard introduced the SSLSetSessionOption() function, but due to
a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
works, it doesn't work as expected under Snow Leopard or Lion.
@@ -855,11 +1046,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
(SecureTransport will always validate the certificate chain by
default.) */
/* (Note: Darwin 12.x.x is Mountain Lion.) */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
#else
if(SSLSetSessionOption != NULL) {
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_BUILD_MAC */
err = SSLSetSessionOption(connssl->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
data->set.ssl.verifypeer?false:true);
@@ -869,14 +1060,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
else {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
data->set.ssl.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
@@ -885,7 +1076,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
/* If this is a domain name and not an IP address, then configure SNI.
* Also: the verifyhost setting influences SNI usage */
@@ -898,7 +1089,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
strlen(conn->host.name));
if(err != noErr) {
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
err);
}
}
@@ -915,7 +1106,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
&all_ciphers_count) == noErr) {
for(i = 0UL ; i < all_ciphers_count ; i++) {
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_BUILD_MAC
/* There's a known bug in early versions of Mountain Lion where ST's ECC
ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
Work around the problem here by disabling those ciphers if we are
@@ -924,7 +1115,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
continue;
}
#endif
#endif /* CURL_BUILD_MAC */
switch(all_ciphers[i]) {
/* Disable NULL ciphersuites: */
case SSL_NULL_WITH_NULL_NULL:
@@ -990,6 +1181,38 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
Curl_safefree(all_ciphers);
Curl_safefree(allowed_ciphers);
/* Check if there's a cached ID we can/should use here! */
if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
&ssl_sessionid_len)) {
/* we got a session id, use it! */
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
if(err != noErr) {
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
/* Informational message */
infof(data, "SSL re-using session ID\n");
}
/* If there isn't one, then let's make one up! This has to be done prior
to starting the handshake. */
else {
CURLcode retcode;
ssl_sessionid = malloc(256*sizeof(char));
ssl_sessionid_len = snprintf(ssl_sessionid, 256, "curl:%s:%hu",
conn->host.name, conn->remote_port);
err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
if(err != noErr) {
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
retcode = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len);
if(retcode!= CURLE_OK) {
failf(data, "failed to store ssl session");
return retcode;
}
}
err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
if(err != noErr) {
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
@@ -1059,6 +1282,20 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
"certificate format");
return CURLE_SSL_CONNECT_ERROR;
/* These are all certificate problems with the client: */
case errSecAuthFailed:
failf(data, "SSL authentication failed");
return CURLE_SSL_CONNECT_ERROR;
case errSSLPeerHandshakeFail:
failf(data, "SSL peer handshake failed, the server most likely "
"requires a client certificate to connect");
return CURLE_SSL_CONNECT_ERROR;
case errSSLPeerUnknownCA:
failf(data, "SSL server rejected the client certificate due to "
"the certificate being signed by an unknown certificate "
"authority");
return CURLE_SSL_CONNECT_ERROR;
/* This error is raised if the server's cert didn't match the server's
host name: */
case errSSLHostNameMismatch:
@@ -1111,7 +1348,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "TLS 1.0 connection using %s\n",
TLSCipherNameForNumber(cipher));
break;
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
case kTLSProtocol11:
infof(data, "TLS 1.1 connection using %s\n",
TLSCipherNameForNumber(cipher));
@@ -1138,20 +1375,22 @@ darwinssl_connect_step3(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CFStringRef server_cert_summary;
char server_cert_summary_c[128];
CFArrayRef server_certs;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
CFIndex i, count;
SecTrustRef trust;
SecTrustRef trust = NULL;
/* There is no step 3!
* Well, okay, if verbose mode is on, let's print the details of the
* server certificates. */
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
#if CURL_BUILD_IOS
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1177,7 +1416,9 @@ darwinssl_connect_step3(struct connectdata *conn,
if(SecTrustEvaluateAsync != NULL) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) {
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1195,8 +1436,10 @@ darwinssl_connect_step3(struct connectdata *conn,
}
}
else {
#if CURL_SUPPORT_MAC_10_8
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
if(err == noErr) {
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
@@ -1214,8 +1457,9 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#endif /* CURL_BUILD_IOS */
#else
#pragma unused(trust)
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
@@ -1235,7 +1479,7 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
#endif /* defined(__MAC_10_7) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
@@ -1387,16 +1631,16 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
if(connssl->ssl_ctx) {
(void)SSLClose(connssl->ssl_ctx);
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL)
CFRelease(connssl->ssl_ctx);
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if CURL_SUPPORT_MAC_10_8
else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#endif /* CURL_SUPPORT_MAC_10_8 */
#else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
connssl->ssl_ctx = NULL;
}
connssl->ssl_sockfd = 0;
@@ -1462,6 +1706,17 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
return rc;
}
void Curl_darwinssl_session_free(void *ptr)
{
/* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
cached session ID inside the Security framework. There is a private
function that does this, but I don't want to have to explain to you why I
got your application rejected from the App Store due to the use of a
private API, so the best we can do is free up our own char array that we
created way back in darwinssl_connect_step1... */
Curl_safefree(ptr);
}
size_t Curl_darwinssl_version(char *buffer, size_t size)
{
return snprintf(buffer, size, "SecureTransport");

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2013, Nick Zitzmann, <nickzman@gmail.com>.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -37,6 +37,7 @@ void Curl_darwinssl_close_all(struct SessionHandle *data);
/* close a SSL connection */
void Curl_darwinssl_close(struct connectdata *conn, int sockindex);
void Curl_darwinssl_session_free(void *ptr);
size_t Curl_darwinssl_version(char *buffer, size_t size);
int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex);
int Curl_darwinssl_check_cxn(struct connectdata *conn);
@@ -51,12 +52,16 @@ void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for SecureTransport */
#define curlssl_init() (1)
#define curlssl_cleanup() Curl_nop_stmt
#define curlssl_connect Curl_darwinssl_connect
#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking
#define curlssl_session_free(x) Curl_nop_stmt
#define curlssl_session_free(x) Curl_darwinssl_session_free(x)
#define curlssl_close_all Curl_darwinssl_close_all
#define curlssl_close Curl_darwinssl_close
#define curlssl_shutdown(x,y) 0

View File

@@ -87,7 +87,7 @@ extern curl_free_callback Curl_cfree;
extern curl_realloc_callback Curl_crealloc;
extern curl_strdup_callback Curl_cstrdup;
extern curl_calloc_callback Curl_ccalloc;
#ifdef WIN32
#if defined(WIN32) && defined(UNICODE)
extern curl_wcsdup_callback Curl_cwcsdup;
#endif
@@ -114,14 +114,15 @@ extern curl_wcsdup_callback Curl_cwcsdup;
#define free(ptr) Curl_cfree(ptr)
#ifdef WIN32
# undef wcsdup
# define wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _wcsdup
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _tcsdup
# ifdef UNICODE
# undef wcsdup
# define wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _wcsdup
# define _wcsdup(ptr) Curl_cwcsdup(ptr)
# undef _tcsdup
# define _tcsdup(ptr) Curl_cwcsdup(ptr)
# else
# undef _tcsdup
# define _tcsdup(ptr) Curl_cstrdup(ptr)
# endif
#endif

View File

@@ -1,61 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#include <curl/curl.h>
#include "curl_rand.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Private pseudo-random number seed. Unsigned integer >= 32bit. Threads
mutual exclusion is not implemented to acess it since we do not require
high quality random numbers (only used in form boudary generation). */
static unsigned int randseed;
/* Pseudo-random number support. */
unsigned int Curl_rand(void)
{
unsigned int r;
/* Return an unsigned 32-bit pseudo-random number. */
r = randseed = randseed * 1103515245 + 12345;
return (r << 16) | ((r >> 16) & 0xFFFF);
}
void Curl_srand(void)
{
/* Randomize pseudo-random number sequence. */
randseed = (unsigned int) time(NULL);
Curl_rand();
Curl_rand();
Curl_rand();
}

View File

@@ -32,7 +32,7 @@
#include "curl_base64.h"
#include "curl_md5.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "curl_hmac.h"
#include "curl_ntlm_msgs.h"
#include "curl_sasl.h"
@@ -314,7 +314,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
/* Generate 64 bits of random data */
for(i = 0; i < 8; i++)
cnonce[i] = table16[Curl_rand()%16];
cnonce[i] = table16[Curl_rand(data)%16];
/* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);

View File

@@ -25,13 +25,17 @@
#include "pingpong.h"
/* Authentication mechanism flags */
#define SASL_MECH_LOGIN 0x0001
#define SASL_MECH_PLAIN 0x0002
#define SASL_MECH_CRAM_MD5 0x0004
#define SASL_MECH_DIGEST_MD5 0x0008
#define SASL_MECH_GSSAPI 0x0010
#define SASL_MECH_EXTERNAL 0x0020
#define SASL_MECH_NTLM 0x0040
#define SASL_MECH_LOGIN (1 << 0)
#define SASL_MECH_PLAIN (1 << 1)
#define SASL_MECH_CRAM_MD5 (1 << 2)
#define SASL_MECH_DIGEST_MD5 (1 << 3)
#define SASL_MECH_GSSAPI (1 << 4)
#define SASL_MECH_EXTERNAL (1 << 5)
#define SASL_MECH_NTLM (1 << 6)
/* Authentication mechanism values */
#define SASL_AUTH_NONE 0
#define SASL_AUTH_ANY ~0
/* This is used to generate a base64 encoded PLAIN authentication message */
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,

View File

@@ -534,6 +534,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
return retcode;
}
else {
connssl->cred->cached = TRUE;
infof(data, "schannel: stored credential handle in session cache\n");
}
}
@@ -1063,7 +1064,6 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
*/
struct SessionHandle *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct curl_schannel_cred *cached_cred = NULL;
infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
conn->host.name, conn->remote_port);
@@ -1141,17 +1141,11 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
connssl->cred->refcount);
}
/* if the handle refcount is zero, check if we have not cached it */
if(connssl->cred->refcount == 0) {
if(Curl_ssl_getsessionid(conn, (void**)&cached_cred, NULL)) {
cached_cred = NULL;
}
/* if the handle was not cached, it is stale to be freed */
if(connssl->cred != cached_cred) {
infof(data, "schannel: clear credential handle\n");
s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
Curl_safefree(connssl->cred);
}
/* if the handle was not cached and the refcount is zero */
if(!connssl->cred->cached && connssl->cred->refcount == 0) {
infof(data, "schannel: clear credential handle\n");
s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
Curl_safefree(connssl->cred);
}
}
}
@@ -1177,7 +1171,7 @@ void Curl_schannel_session_free(void *ptr)
{
struct curl_schannel_cred *cred = ptr;
if(cred && cred->refcount == 0) {
if(cred && cred->cached && cred->refcount == 0) {
s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
Curl_safefree(cred);
}

View File

@@ -270,7 +270,9 @@
# endif
# endif
# include <tchar.h>
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
# ifdef UNICODE
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
# endif
#endif
/*
@@ -369,7 +371,9 @@
# include <sys/stat.h>
# undef lseek
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
# undef fstat
# define fstat(fdes,stp) _fstati64(fdes, stp)
# undef stat
# define stat(fname,stp) _stati64(fname, stp)
# define struct_stat struct _stati64
# define LSEEK_ERROR (__int64)-1
@@ -616,7 +620,7 @@ int netware_init(void);
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
defined(USE_DARWINSSL)
defined(USE_DARWINSSL) || defined(USE_GSKIT)
#define USE_SSL /* SSL support has been enabled */
#endif

170
lib/dotdot.c Normal file
View File

@@ -0,0 +1,170 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#include "dotdot.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/*
* "Remove Dot Segments"
* http://tools.ietf.org/html/rfc3986#section-5.2.4
*/
/*
* Curl_dedotdotify()
*
* This function gets a zero-terminated path with dot and dotdot sequences
* passed in and strips them off according to the rules in RFC 3986 section
* 5.2.4.
*
* The function handles a query part ('?' + stuff) appended but it expects
* that fragments ('#' + stuff) have already been cut off.
*
* RETURNS
*
* an allocated dedotdotified output string
*/
char *Curl_dedotdotify(char *input)
{
size_t inlen = strlen(input);
char *clone;
size_t clen = inlen; /* the length of the cloned input */
char *out = malloc(inlen+1);
char *outptr;
char *orgclone;
char *queryp;
if(!out)
return NULL; /* out of memory */
/* get a cloned copy of the input */
clone = strdup(input);
if(!clone) {
free(out);
return NULL;
}
orgclone = clone;
outptr = out;
/*
* To handle query-parts properly, we must find it and remove it during the
* dotdot-operation and then append it again at the end to the output
* string.
*/
queryp = strchr(clone, '?');
if(queryp)
*queryp = 0;
do {
/* A. If the input buffer begins with a prefix of "../" or "./", then
remove that prefix from the input buffer; otherwise, */
if(!strncmp("./", clone, 2)) {
clone+=2;
clen-=2;
}
else if(!strncmp("../", clone, 3)) {
clone+=3;
clen-=3;
}
/* B. if the input buffer begins with a prefix of "/./" or "/.", where
"." is a complete path segment, then replace that prefix with "/" in
the input buffer; otherwise, */
else if(!strncmp("/./", clone, 3)) {
clone+=2;
clen-=2;
}
else if(!strcmp("/.", clone)) {
clone[1]='/';
clone++;
clen-=1;
}
/* C. if the input buffer begins with a prefix of "/../" or "/..", where
".." is a complete path segment, then replace that prefix with "/" in
the input buffer and remove the last segment and its preceding "/" (if
any) from the output buffer; otherwise, */
else if(!strncmp("/../", clone, 4)) {
clone+=3;
clen-=3;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
else if(!strcmp("/..", clone)) {
clone[2]='/';
clone+=2;
clen-=2;
/* remove the last segment from the output buffer */
while(outptr > out) {
outptr--;
if(*outptr == '/')
break;
}
*outptr = 0; /* zero-terminate where it stops */
}
/* D. if the input buffer consists only of "." or "..", then remove
that from the input buffer; otherwise, */
else if(!strcmp(".", clone) || !strcmp("..", clone)) {
*clone=0;
}
else {
/* E. move the first path segment in the input buffer to the end of
the output buffer, including the initial "/" character (if any) and
any subsequent characters up to, but not including, the next "/"
character or the end of the input buffer. */
do {
*outptr++ = *clone++;
clen--;
} while(*clone && (*clone != '/'));
*outptr = 0;
}
} while(*clone);
if(queryp) {
size_t qlen;
/* There was a query part, append that to the output. The 'clone' string
may now have been altered so we copy from the original input string
from the correct index. */
size_t oindex = queryp - orgclone;
qlen = strlen(&input[oindex]);
memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */
}
free(orgclone);
return out;
}

View File

@@ -1,5 +1,5 @@
#ifndef HEADER_CURL_RAND_H
#define HEADER_CURL_RAND_H
#ifndef HEADER_CURL_DOTDOT_H
#define HEADER_CURL_DOTDOT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, 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
@@ -21,9 +21,5 @@
* KIND, either express or implied.
*
***************************************************************************/
void Curl_srand(void);
unsigned int Curl_rand(void);
#endif /* HEADER_CURL_RAND_H */
char *Curl_dedotdotify(char *input);
#endif

View File

@@ -50,6 +50,11 @@
#include <sys/param.h>
#endif
#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
#define SIGPIPE_IGNORE 1
#include <signal.h>
#endif
#include "strequal.h"
#include "urldata.h"
#include <curl/curl.h>
@@ -69,10 +74,10 @@
#include "connect.h" /* for Curl_getconnectinfo */
#include "slist.h"
#include "amigaos.h"
#include "curl_rand.h"
#include "non-ascii.h"
#include "warnless.h"
#include "conncache.h"
#include "multiif.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -80,6 +85,56 @@
/* The last #include file should be: */
#include "memdebug.h"
#ifdef SIGPIPE_IGNORE
struct sigpipe_ignore {
struct sigaction old_pipe_act;
bool no_signal;
};
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
/*
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
* internals, and then sigpipe_restore() will restore the situation when we
* return from libcurl again.
*/
static void sigpipe_ignore(struct SessionHandle *data,
struct sigpipe_ignore *ig)
{
/* get a local copy of no_signal because the SessionHandle might not be
around when we restore */
ig->no_signal = data->set.no_signal;
if(!data->set.no_signal) {
struct sigaction action;
/* first, extract the existing situation */
memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
action = ig->old_pipe_act;
/* ignore this signal */
action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &action, NULL);
}
}
/*
* sigpipe_restore() puts back the outside world's opinion of signal handler
* and SIGPIPE handling. It MUST only be called after a corresponding
* sigpipe_ignore() was used.
*/
static void sigpipe_restore(struct sigpipe_ignore *ig)
{
if(!ig->no_signal)
/* restore the outside state */
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
}
#else
/* for systems without sigaction */
#define sigpipe_ignore(x,y) Curl_nop_stmt
#define sigpipe_restore(x) Curl_nop_stmt
#define SIGPIPE_VARIABLE(x)
#endif
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
of win32_init() */
static void win32_cleanup(void)
@@ -197,8 +252,8 @@ curl_free_callback Curl_cfree = (curl_free_callback)free;
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
#ifdef WIN32
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
#if defined(WIN32) && defined(UNICODE)
curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
#else
/*
@@ -231,8 +286,8 @@ CURLcode curl_global_init(long flags)
Curl_crealloc = (curl_realloc_callback)realloc;
Curl_cstrdup = (curl_strdup_callback)system_strdup;
Curl_ccalloc = (curl_calloc_callback)calloc;
#ifdef WIN32
Curl_cwcsdup = (curl_wcsdup_callback)wcsdup;
#if defined(WIN32) && defined(UNICODE)
Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
#endif
if(flags & CURL_GLOBAL_SSL)
@@ -281,10 +336,6 @@ CURLcode curl_global_init(long flags)
init_flags = flags;
/* Preset pseudo-random number sequence. */
Curl_srand();
return CURLE_OK;
}
@@ -425,6 +476,10 @@ CURLcode curl_easy_perform(CURL *easy)
bool done = FALSE;
int rc;
struct SessionHandle *data = easy;
int without_fds = 0; /* count number of consecutive returns from
curl_multi_wait() without any filedescriptors */
struct timeval before;
SIGPIPE_VARIABLE(pipe_st);
if(!easy)
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -437,7 +492,9 @@ CURLcode curl_easy_perform(CURL *easy)
if(data->multi_easy)
multi = data->multi_easy;
else {
multi = curl_multi_init();
/* this multi handle will only ever have a single easy handled attached
to it, so make it use minimal hashes */
multi = Curl_multi_handle(1, 3);
if(!multi)
return CURLE_OUT_OF_MEMORY;
data->multi_easy = multi;
@@ -455,6 +512,8 @@ CURLcode curl_easy_perform(CURL *easy)
return CURLE_FAILED_INIT;
}
sigpipe_ignore(data, &pipe_st);
/* assign this after curl_multi_add_handle() since that function checks for
it and rejects this handle otherwise */
data->multi = multi;
@@ -463,6 +522,7 @@ CURLcode curl_easy_perform(CURL *easy)
int still_running;
int ret;
before = curlx_tvnow();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
if(mcode == CURLM_OK) {
@@ -471,6 +531,25 @@ CURLcode curl_easy_perform(CURL *easy)
code = CURLE_RECV_ERROR;
break;
}
else if(ret == 0) {
struct timeval after = curlx_tvnow();
/* If it returns without any filedescriptor instantly, we need to
avoid busy-looping during periods where it has nothing particular
to wait for */
if(curlx_tvdiff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
Curl_wait_ms(sleep_ms);
}
}
else
/* it wasn't "instant", restart counter */
without_fds = 0;
}
else
/* got file descriptor, restart counter */
without_fds = 0;
mcode = curl_multi_perform(multi, &still_running);
}
@@ -489,6 +568,8 @@ CURLcode curl_easy_perform(CURL *easy)
a failure here, room for future improvement! */
(void)curl_multi_remove_handle(multi, easy);
sigpipe_restore(&pipe_st);
/* The multi handle is kept alive, owned by the easy handle */
return code;
}
@@ -500,11 +581,14 @@ CURLcode curl_easy_perform(CURL *easy)
void curl_easy_cleanup(CURL *curl)
{
struct SessionHandle *data = (struct SessionHandle *)curl;
SIGPIPE_VARIABLE(pipe_st);
if(!data)
return;
sigpipe_ignore(data, &pipe_st);
Curl_close(data);
sigpipe_restore(&pipe_st);
}
/*
@@ -532,12 +616,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
{
va_list arg;
void *paramp;
CURLcode ret;
struct SessionHandle *data = (struct SessionHandle *)curl;
va_start(arg, info);
paramp = va_arg(arg, void *);
return Curl_getinfo(data, info, paramp);
ret = Curl_getinfo(data, info, paramp);
va_end(arg);
return ret;
}
/*
@@ -724,7 +812,7 @@ CURLcode curl_easy_pause(CURL *curl, int action)
do {
chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
result = Curl_client_write(data->state.current_conn,
result = Curl_client_write(data->easy_conn,
temptype, tempwrite, chunklen);
if(result)
/* failures abort the loop at once */
@@ -766,6 +854,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
free(freewrite); /* this is unconditionally no longer used */
}
/* if there's no error and we're not pausing both directions, we want
to have this handle checked soon */
if(!result &&
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
Curl_expire(data, 1); /* get this handle going again */
return result;
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, 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
@@ -159,7 +159,8 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
while(--alloc > 0) {
in = *string;
if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
if(('%' == in) && (alloc > 2) &&
ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
char hexstr[3];
char *ptr;

View File

@@ -24,9 +24,6 @@
#include <curl/curl.h>
/* Length of the random boundary string. */
#define BOUNDARY_LENGTH 40
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
@@ -35,7 +32,7 @@
#include "urldata.h" /* for struct SessionHandle */
#include "formdata.h"
#include "curl_rand.h"
#include "sslgen.h"
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
@@ -56,7 +53,7 @@ static char *Curl_basename(char *path);
#endif
static size_t readfromfile(struct Form *form, char *buffer, size_t size);
static char *formboundary(void);
static char *formboundary(struct SessionHandle *data);
/* What kind of Content-Type to use on un-specified files with unrecognized
extensions. */
@@ -171,8 +168,8 @@ static FormInfo * AddFormInfo(char *value,
* Returns some valid contenttype for filename.
*
***************************************************************************/
static const char * ContentTypeForFilename (const char *filename,
const char *prevtype)
static const char *ContentTypeForFilename(const char *filename,
const char *prevtype)
{
const char *contenttype = NULL;
unsigned int i;
@@ -181,7 +178,7 @@ static const char * ContentTypeForFilename (const char *filename,
* extensions and pick the first we match!
*/
struct ContentType {
char extension[6];
const char *extension;
const char *type;
};
static const struct ContentType ctts[]={
@@ -429,7 +426,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
/* Get contents from a given file name */
case CURLFORM_FILECONTENT:
if(current_form->flags != 0)
if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
return_value = CURL_FORMADD_OPTION_TWICE;
else {
const char *filename = array_state?
@@ -670,9 +667,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
if(((form->flags & HTTPPOST_FILENAME) ||
(form->flags & HTTPPOST_BUFFER)) &&
!form->contenttype ) {
char *f = form->flags & HTTPPOST_BUFFER?
form->showfilename : form->value;
/* our contenttype is missing */
form->contenttype
= strdup(ContentTypeForFilename(form->value, prevtype));
form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
if(!form->contenttype) {
return_value = CURL_FORMADD_MEMORY;
break;
@@ -777,6 +776,70 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
return result;
}
#ifdef __VMS
#include <fabdef.h>
/*
* get_vms_file_size does what it takes to get the real size of the file
*
* For fixed files, find out the size of the EOF block and adjust.
*
* For all others, have to read the entire file in, discarding the contents.
* Most posted text files will be small, and binary files like zlib archives
* and CD/DVD images should be either a STREAM_LF format or a fixed format.
*
*/
curl_off_t VmsRealFileSize(const char * name,
const struct_stat * stat_buf)
{
char buffer[8192];
curl_off_t count;
int ret_stat;
FILE * file;
file = fopen(name, "r");
if(file == NULL)
return 0;
count = 0;
ret_stat = 1;
while(ret_stat > 0) {
ret_stat = fread(buffer, 1, sizeof(buffer), file);
if(ret_stat != 0)
count += ret_stat;
}
fclose(file);
return count;
}
/*
*
* VmsSpecialSize checks to see if the stat st_size can be trusted and
* if not to call a routine to get the correct size.
*
*/
static curl_off_t VmsSpecialSize(const char * name,
const struct_stat * stat_buf)
{
switch(stat_buf->st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
return VmsRealFileSize(name, stat_buf);
break;
default:
return stat_buf->st_size;
}
}
#endif
#ifndef __VMS
#define filesize(name, stat_data) (stat_data.st_size)
#else
/* Getting the expected file size needs help on VMS */
#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
#endif
/*
* AddFormData() adds a chunk of data to the FormData linked list.
*
@@ -832,7 +895,7 @@ static CURLcode AddFormData(struct FormData **formp,
if(!strequal("-", newform->line)) {
struct_stat file;
if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode))
*size += file.st_size;
*size += filesize(newform->line, file);
else
return CURLE_BAD_FUNCTION_ARGUMENT;
}
@@ -1101,7 +1164,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
if(!post)
return result; /* no input => no output! */
boundary = formboundary();
boundary = formboundary(data);
if(!boundary)
return CURLE_OUT_OF_MEMORY;
@@ -1157,7 +1220,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
the magic to include several files with the same field name */
Curl_safefree(fileboundary);
fileboundary = formboundary();
fileboundary = formboundary(data);
if(!fileboundary) {
result = CURLE_OUT_OF_MEMORY;
break;
@@ -1343,6 +1406,36 @@ int Curl_FormInit(struct Form *form, struct FormData *formdata )
return 0;
}
#ifndef __VMS
# define fopen_read fopen
#else
/*
* vmsfopenread
*
* For upload to work as expected on VMS, different optional
* parameters must be added to the fopen command based on
* record format of the file.
*
*/
# define fopen_read vmsfopenread
static FILE * vmsfopenread(const char *file, const char *mode) {
struct_stat statbuf;
int result;
result = stat(file, &statbuf);
switch (statbuf.st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
return fopen(file, "r");
break;
default:
return fopen(file, "r", "rfm=stmlf", "ctx=stm");
}
}
#endif
/*
* readfromfile()
*
@@ -1365,7 +1458,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
else {
if(!form->fp) {
/* this file hasn't yet been opened */
form->fp = fopen(form->data->line, "rb"); /* b is for binary */
form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */
if(!form->fp)
return (size_t)-1; /* failure */
}
@@ -1464,28 +1557,12 @@ char *Curl_formpostheader(void *formp, size_t *len)
* formboundary() creates a suitable boundary string and returns an allocated
* one.
*/
static char *formboundary(void)
static char *formboundary(struct SessionHandle *data)
{
char *retstring;
size_t i;
static const char table16[]="0123456789abcdef";
retstring = malloc(BOUNDARY_LENGTH+1);
if(!retstring)
return NULL; /* failed */
strcpy(retstring, "----------------------------");
for(i=strlen(retstring); i<BOUNDARY_LENGTH; i++)
retstring[i] = table16[Curl_rand()%16];
/* 28 dashes and 12 hexadecimal digits makes 12^16 (184884258895036416)
/* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615)
combinations */
retstring[BOUNDARY_LENGTH]=0; /* zero terminate */
return retstring;
return aprintf("------------------------%08x%08x",
Curl_rand(data), Curl_rand(data));
}
#else /* CURL_DISABLE_HTTP */

183
lib/ftp.c
View File

@@ -123,8 +123,8 @@ static void ftp_pasv_verbose(struct connectdata *conn,
char *newhost, /* ascii version */
int port);
#endif
static CURLcode ftp_state_post_rest(struct connectdata *conn);
static CURLcode ftp_state_post_cwd(struct connectdata *conn);
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
static CURLcode ftp_state_mdtm(struct connectdata *conn);
static CURLcode ftp_state_quote(struct connectdata *conn,
bool init, ftpstate instate);
static CURLcode ftp_nb_type(struct connectdata *conn,
@@ -136,7 +136,7 @@ static CURLcode ftp_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode ftp_connect(struct connectdata *conn, bool *done);
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
static CURLcode ftp_do_more(struct connectdata *conn, bool *completed);
static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
@@ -151,8 +151,7 @@ static CURLcode wc_statemach(struct connectdata *conn);
static void wc_data_dtor(void *ptr);
static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
curl_off_t filesize);
static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
static CURLcode ftp_readresp(curl_socket_t sockfd,
struct pingpong *pp,
@@ -828,7 +827,7 @@ static void _state(struct connectdata *conn,
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
if(ftpc->state != newstate)
infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
ftpc, lineno, names[ftpc->state], names[newstate]);
(void *)ftpc, lineno, names[ftpc->state], names[newstate]);
#endif
ftpc->state = newstate;
}
@@ -851,7 +850,7 @@ static CURLcode ftp_state_pwd(struct connectdata *conn)
CURLcode result;
/* send PWD to discover our entry point */
PPSENDF(&conn->proto.ftpc.pp, "PWD", NULL);
PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
state(conn, FTP_PWD);
return CURLE_OK;
@@ -915,7 +914,7 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
if(ftpc->cwddone)
/* already done and fine */
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
else {
ftpc->count2 = 0; /* count2 counts failed CWDs */
@@ -943,7 +942,7 @@ static CURLcode ftp_state_cwd(struct connectdata *conn)
}
else {
/* No CWD necessary */
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
}
}
}
@@ -1373,10 +1372,14 @@ static CURLcode ftp_state_use_pasv(struct connectdata *conn)
return result;
}
/* REST is the last command in the chain of commands when a "head"-like
request is made. Thus, if an actual transfer is to be made this is where
we take off for real. */
static CURLcode ftp_state_post_rest(struct connectdata *conn)
/*
* ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
*
* REST is the last command in the chain of commands when a "head"-like
* request is made. Thus, if an actual transfer is to be made this is where we
* take off for real.
*/
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1419,7 +1422,7 @@ static CURLcode ftp_state_post_rest(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_size(struct connectdata *conn)
static CURLcode ftp_state_rest(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1435,12 +1438,12 @@ static CURLcode ftp_state_post_size(struct connectdata *conn)
state(conn, FTP_REST);
}
else
result = ftp_state_post_rest(conn);
result = ftp_state_prepare_transfer(conn);
return result;
}
static CURLcode ftp_state_post_type(struct connectdata *conn)
static CURLcode ftp_state_size(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1455,12 +1458,12 @@ static CURLcode ftp_state_post_type(struct connectdata *conn)
state(conn, FTP_SIZE);
}
else
result = ftp_state_post_size(conn);
result = ftp_state_rest(conn);
return result;
}
static CURLcode ftp_state_post_listtype(struct connectdata *conn)
static CURLcode ftp_state_list(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
@@ -1529,7 +1532,7 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_retrtype(struct connectdata *conn)
static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -1540,7 +1543,7 @@ static CURLcode ftp_state_post_retrtype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_stortype(struct connectdata *conn)
static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -1551,7 +1554,7 @@ static CURLcode ftp_state_post_stortype(struct connectdata *conn)
return result;
}
static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
static CURLcode ftp_state_type(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct FTP *ftp = conn->data->state.proto.ftp;
@@ -1577,14 +1580,14 @@ static CURLcode ftp_state_post_mdtm(struct connectdata *conn)
return result;
}
else
result = ftp_state_post_type(conn);
result = ftp_state_size(conn);
return result;
}
/* This is called after the CWD commands have been done in the beginning of
the DO phase */
static CURLcode ftp_state_post_cwd(struct connectdata *conn)
static CURLcode ftp_state_mdtm(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
@@ -1600,7 +1603,7 @@ static CURLcode ftp_state_post_cwd(struct connectdata *conn)
state(conn, FTP_MDTM);
}
else
result = ftp_state_post_mdtm(conn);
result = ftp_state_type(conn);
return result;
}
@@ -1775,7 +1778,7 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
else {
if(ftpc->known_filesize != -1) {
Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
result = ftp_state_post_retr_size(conn, ftpc->known_filesize);
result = ftp_state_retr(conn, ftpc->known_filesize);
}
else {
PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
@@ -1799,15 +1802,15 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
static CURLcode ftp_epsv_disable(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
infof(conn->data, "got positive EPSV response, but can't connect. "
"Disabling EPSV\n");
infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
conn->data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
PPSENDF(&conn->proto.ftpc.pp, "PASV", NULL);
PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
conn->proto.ftpc.count1++;
/* remain in the FTP_PASV state */
/* remain in/go to the FTP_PASV state */
state(conn, FTP_PASV);
return result;
}
@@ -1936,28 +1939,18 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
else if(ftpc->count1 == 0) {
/* EPSV failed, move on to PASV */
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
infof(data, "disabling EPSV usage\n");
PPSENDF(&ftpc->pp, "PASV", NULL);
ftpc->count1++;
/* remain in the FTP_PASV state */
return result;
return ftp_epsv_disable(conn);
}
else {
failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
return CURLE_FTP_WEIRD_PASV_REPLY;
}
if(data->set.str[STRING_PROXY] && *data->set.str[STRING_PROXY]) {
if(conn->bits.proxy) {
/*
* This is a tunnel through a http proxy and we need to connect to the
* proxy again 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!
* This connection uses a proxy and we need to connect to the proxy again
* 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!
*/
rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr);
if(rc == CURLRESOLV_PENDING)
@@ -2023,14 +2016,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
case CURLPROXY_SOCKS5_HOSTNAME:
result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost, newport,
SECONDARYSOCKET, conn);
connected = TRUE;
break;
case CURLPROXY_SOCKS4:
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
SECONDARYSOCKET, conn, FALSE);
connected = TRUE;
break;
case CURLPROXY_SOCKS4A:
result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
SECONDARYSOCKET, conn, TRUE);
connected = TRUE;
break;
case CURLPROXY_HTTP:
case CURLPROXY_HTTP_1_0:
@@ -2082,8 +2078,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
}
conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
conn->bits.do_more = TRUE;
state(conn, FTP_STOP); /* this phase is completed */
@@ -2223,7 +2218,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
}
if(!result)
result = ftp_state_post_mdtm(conn);
result = ftp_state_type(conn);
return result;
}
@@ -2247,18 +2242,18 @@ static CURLcode ftp_state_type_resp(struct connectdata *conn,
ftpcode);
if(instate == FTP_TYPE)
result = ftp_state_post_type(conn);
result = ftp_state_size(conn);
else if(instate == FTP_LIST_TYPE)
result = ftp_state_post_listtype(conn);
result = ftp_state_list(conn);
else if(instate == FTP_RETR_TYPE)
result = ftp_state_post_retrtype(conn);
result = ftp_state_retr_prequote(conn);
else if(instate == FTP_STOR_TYPE)
result = ftp_state_post_stortype(conn);
result = ftp_state_stor_prequote(conn);
return result;
}
static CURLcode ftp_state_post_retr_size(struct connectdata *conn,
static CURLcode ftp_state_retr(struct connectdata *conn,
curl_off_t filesize)
{
CURLcode result = CURLE_OK;
@@ -2363,11 +2358,11 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
}
#endif
Curl_pgrsSetDownloadSize(data, filesize);
result = ftp_state_post_size(conn);
result = ftp_state_rest(conn);
}
else if(instate == FTP_RETR_SIZE) {
Curl_pgrsSetDownloadSize(data, filesize);
result = ftp_state_post_retr_size(conn, filesize);
result = ftp_state_retr(conn, filesize);
}
else if(instate == FTP_STOR_SIZE) {
data->state.resume_from = filesize;
@@ -2395,7 +2390,7 @@ static CURLcode ftp_state_rest_resp(struct connectdata *conn,
return result;
}
#endif
result = ftp_state_post_rest(conn);
result = ftp_state_prepare_transfer(conn);
break;
case FTP_RETR_REST:
@@ -2711,7 +2706,10 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
/* we have now received a full FTP server response */
switch(ftpc->state) {
case FTP_WAIT220:
if(ftpcode != 220) {
if(ftpcode == 230)
/* 230 User logged in - already! */
return ftp_state_user_resp(conn, ftpcode, ftpc->state);
else if(ftpcode != 220) {
failf(data, "Got a %03d ftp-server response when 220 was expected",
ftpcode);
return CURLE_FTP_WEIRD_SERVER_REPLY;
@@ -2833,7 +2831,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(data->set.ftp_ccc) {
/* CCC - Clear Command Channel
*/
PPSENDF(&ftpc->pp, "CCC", NULL);
PPSENDF(&ftpc->pp, "%s", "CCC");
state(conn, FTP_CCC);
}
else {
@@ -2920,7 +2918,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(!ftpc->server_os && dir[0] != '/') {
result = Curl_pp_sendf(&ftpc->pp, "SYST", NULL);
result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
if(result != CURLE_OK) {
free(dir);
return result;
@@ -2973,7 +2971,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
if(strequal(os, "OS/400")) {
/* Force OS400 name format 1. */
result = Curl_pp_sendf(&ftpc->pp, "SITE NAMEFMT 1", NULL);
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
if(result != CURLE_OK) {
free(os);
return result;
@@ -3051,7 +3049,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]);
}
else {
result = ftp_state_post_cwd(conn);
result = ftp_state_mdtm(conn);
if(result)
return result;
}
@@ -3215,8 +3213,8 @@ static CURLcode ftp_init(struct connectdata *conn)
* the connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*
*/
static CURLcode ftp_connect(struct connectdata *conn,
bool *done) /* see description above */
@@ -3382,7 +3380,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
/* partial download completed */
result = Curl_pp_sendf(pp, "ABOR");
result = Curl_pp_sendf(pp, "%s", "ABOR");
if(result) {
failf(data, "Failure sending ABOR command: %s",
curl_easy_strerror(result));
@@ -3676,20 +3674,23 @@ static CURLcode ftp_range(struct connectdata *conn)
*
* This function shall be called when the second FTP (data) connection is
* connected.
*
* 'complete' can return 0 for incomplete, 1 for done and -1 for go back
* (which basically is only for when PASV is being sent to retry a failed
* EPSV).
*/
static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
{
struct SessionHandle *data=conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
bool connected = FALSE;
bool complete = FALSE;
/* the ftp struct is inited in ftp_connect() */
struct FTP *ftp = data->state.proto.ftp;
*complete = FALSE;
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
@@ -3706,14 +3707,22 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(connected) {
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
}
else
else {
if(result && (ftpc->count1 == 0)) {
*completep = -1; /* go back to DOING please */
/* this is a EPSV connect failing, try PASV instead */
return ftp_epsv_disable(conn);
}
return result;
}
}
if(ftpc->state) {
/* already in a state so skip the intial commands.
They are only done to kickstart the do_more state */
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
/* if we got an error or if we don't wait for a data connection return
immediately */
@@ -3724,7 +3733,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
/* if we reach the end of the FTP state machine here, *complete will be
TRUE but so is ftpc->wait_data_conn, which says we need to wait for
the data connection and therefore we're not actually complete */
*complete = FALSE;
*completep = 0;
}
if(ftp->transfer <= FTPTRANSFER_INFO) {
@@ -3747,6 +3756,9 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
*completep = 1; /* this state is now complete when the server has
connected back to us */
}
}
else if(data->set.upload) {
@@ -3754,7 +3766,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
}
else {
/* download */
@@ -3782,7 +3795,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
return result;
}
result = ftp_multi_statemach(conn, complete);
result = ftp_multi_statemach(conn, &complete);
*completep = (int)complete;
}
return result;
}
@@ -3794,7 +3808,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(!ftpc->wait_data_conn) {
/* no waiting for the data connection so this is now complete */
*complete = TRUE;
*completep = 1;
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
}
@@ -3837,7 +3851,9 @@ CURLcode ftp_perform(struct connectdata *conn,
/* run the state-machine */
result = ftp_multi_statemach(conn, dophase_done);
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
*connected = conn->bits.tcpconnect[SECONDARYSOCKET];
infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
if(*dophase_done)
DEBUGF(infof(conn->data, "DO phase is complete1\n"));
@@ -4188,7 +4204,7 @@ static CURLcode ftp_quit(struct connectdata *conn)
CURLcode result = CURLE_OK;
if(conn->proto.ftpc.ctl_valid) {
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "QUIT", NULL);
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
if(result) {
failf(conn->data, "Failure sending QUIT command: %s",
curl_easy_strerror(result));
@@ -4316,13 +4332,17 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
}
slash_pos=strrchr(cur_pos, '/');
if(slash_pos || !*cur_pos) {
size_t dirlen = slash_pos-cur_pos;
ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
if(!ftpc->dirs)
return CURLE_OUT_OF_MEMORY;
if(!dirlen)
dirlen++;
ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
slash_pos ?
curlx_sztosi(slash_pos-cur_pos) : 1,
slash_pos ? curlx_sztosi(dirlen) : 1,
NULL);
if(!ftpc->dirs[0]) {
freedirs(ftpc);
@@ -4377,6 +4397,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
}
else {
cur_pos = slash_pos + 1; /* jump to the rest of the string */
if(!ftpc->dirdepth) {
/* path starts with a slash, add that as a directory */
ftpc->dirs[ftpc->dirdepth] = strdup("/");
if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
failf(data, "no memory");
freedirs(ftpc);
return CURLE_OUT_OF_MEMORY;
}
}
continue;
}
@@ -4452,7 +4481,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
bool completed;
int completed;
CURLcode result = ftp_do_more(conn, &completed);
if(result) {

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -53,8 +53,9 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
pro->t_redirect = 0;
info->httpcode = 0;
info->httpversion=0;
info->filetime=-1; /* -1 is an illegal time and thus means unknown */
info->httpversion = 0;
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
info->timecond = FALSE;
if(info->contenttype)
free(info->contenttype);
@@ -185,7 +186,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
break;
case CURLINFO_CONDITION_UNMET:
/* return if the condition prevented the document to get transferred */
*param_longp = data->info.timecond;
*param_longp = data->info.timecond ? 1L : 0L;
break;
case CURLINFO_RTSP_CLIENT_CSEQ:
*param_longp = data->state.rtsp_next_client_CSeq;

906
lib/gskit.c Normal file
View File

@@ -0,0 +1,906 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_GSKIT
#include <gskssl.h>
#include <qsoasync.h>
/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"
#include "gskit.h"
#include "sslgen.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "strequal.h"
#include "x509asn1.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* Supported ciphers. */
typedef struct {
const char * name; /* Cipher name. */
const char * gsktoken; /* Corresponding token for GSKit String. */
int sslver; /* SSL version. */
} gskit_cipher;
static const gskit_cipher ciphertable[] = {
{ "null-md5", "01", CURL_SSLVERSION_SSLv3 },
{ "null-sha", "02", CURL_SSLVERSION_SSLv3 },
{ "exp-rc4-md5", "03", CURL_SSLVERSION_SSLv3 },
{ "rc4-md5", "04", CURL_SSLVERSION_SSLv3 },
{ "rc4-sha", "05", CURL_SSLVERSION_SSLv3 },
{ "exp-rc2-cbc-md5", "06", CURL_SSLVERSION_SSLv3 },
{ "exp-des-cbc-sha", "09", CURL_SSLVERSION_SSLv3 },
{ "des-cbc3-sha", "0A", CURL_SSLVERSION_SSLv3 },
{ "aes128-sha", "2F", CURL_SSLVERSION_TLSv1 },
{ "aes256-sha", "35", CURL_SSLVERSION_TLSv1 },
{ "rc4-md5", "1", CURL_SSLVERSION_SSLv2 },
{ "exp-rc4-md5", "2", CURL_SSLVERSION_SSLv2 },
{ "rc2-md5", "3", CURL_SSLVERSION_SSLv2 },
{ "exp-rc2-md5", "4", CURL_SSLVERSION_SSLv2 },
{ "des-cbc-md5", "6", CURL_SSLVERSION_SSLv2 },
{ "des-cbc3-md5", "7", CURL_SSLVERSION_SSLv2 },
{ (const char *) NULL, (const char *) NULL, 0 }
};
static bool is_separator(char c)
{
/* Return whether character is a cipher list separator. */
switch (c) {
case ' ':
case '\t':
case ':':
case ',':
case ';':
return true;
}
return false;
}
static CURLcode gskit_status(struct SessionHandle * data, int rc,
const char * procname, CURLcode defcode)
{
CURLcode cc;
/* Process GSKit status and map it to a CURLcode. */
switch (rc) {
case GSK_OK:
case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
return CURLE_OK;
case GSK_KEYRING_OPEN_ERROR:
case GSK_OS400_ERROR_NO_ACCESS:
return CURLE_SSL_CACERT_BADFILE;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
case GSK_ERROR_BAD_V2_CIPHER:
case GSK_ERROR_BAD_V3_CIPHER:
case GSK_ERROR_NO_CIPHERS:
return CURLE_SSL_CIPHER;
case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
case GSK_ERROR_CERT_VALIDATION:
return CURLE_PEER_FAILED_VERIFICATION;
case GSK_OS400_ERROR_TIMED_OUT:
return CURLE_OPERATION_TIMEDOUT;
case GSK_WOULD_BLOCK:
return CURLE_AGAIN;
case GSK_OS400_ERROR_NOT_REGISTERED:
break;
case GSK_ERROR_IO:
switch (errno) {
case ENOMEM:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "%s I/O error: %s", procname, strerror(errno));
break;
}
break;
default:
failf(data, "%s: %s", procname, gsk_strerror(rc));
break;
}
return defcode;
}
static CURLcode set_enum(struct SessionHandle * data,
gsk_handle h, GSK_ENUM_ID id, GSK_ENUM_VALUE value)
{
int rc = gsk_attribute_set_enum(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_buffer(struct SessionHandle * data,
gsk_handle h, GSK_BUF_ID id, const char * buffer)
{
int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_numeric(struct SessionHandle * data,
gsk_handle h, GSK_NUM_ID id, int value)
{
int rc = gsk_attribute_set_numeric_value(h, id, value);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_callback(struct SessionHandle * data,
gsk_handle h, GSK_CALLBACK_ID id, void * info)
{
int rc = gsk_attribute_set_callback(h, id, info);
switch (rc) {
case GSK_OK:
return CURLE_OK;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
break;
default:
failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode set_ciphers(struct SessionHandle * data, gsk_handle h)
{
const char * cipherlist = data->set.str[STRING_SSL_CIPHER_LIST];
char * sslv2ciphers;
char * sslv3ciphers;
const char * clp;
const gskit_cipher * ctp;
char * v2p;
char * v3p;
int i;
CURLcode cc;
/* Compile cipher list into GSKit-compatible cipher lists. */
if(!cipherlist)
return CURLE_OK;
while(is_separator(*cipherlist)) /* Skip initial separators. */
cipherlist++;
if(!*cipherlist)
return CURLE_OK;
/* We allocate GSKit buffers of the same size as the input string: since
GSKit tokens are always shorter than their cipher names, allocated buffers
will always be large enough to accomodate the result. */
i = strlen(cipherlist) + 1;
v2p = malloc(i);
if(!v2p)
return CURLE_OUT_OF_MEMORY;
v3p = malloc(i);
if(!v3p) {
free(v2p);
return CURLE_OUT_OF_MEMORY;
}
sslv2ciphers = v2p;
sslv3ciphers = v3p;
/* Process each cipher in input string. */
for(;;) {
for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
cipherlist++;
i = cipherlist - clp;
if(!i)
break;
/* Search the cipher in our table. */
for(ctp = ciphertable; ctp->name; ctp++)
if(strnequal(ctp->name, clp, i) && !ctp->name[i])
break;
if(!ctp->name)
failf(data, "Unknown cipher %.*s: ignored", i, clp);
else {
switch (ctp->sslver) {
case CURL_SSLVERSION_SSLv2:
strcpy(v2p, ctp->gsktoken);
v2p += strlen(v2p);
break;
default:
/* GSKit wants TLSv1 ciphers with SSLv3 ciphers. */
strcpy(v3p, ctp->gsktoken);
v3p += strlen(v3p);
break;
}
}
/* Advance to next cipher name or end of string. */
while(is_separator(*cipherlist))
cipherlist++;
}
*v2p = '\0';
*v3p = '\0';
cc = set_buffer(data, h, GSK_V2_CIPHER_SPECS, sslv2ciphers);
if(cc == CURLE_OK)
cc = set_buffer(data, h, GSK_V3_CIPHER_SPECS, sslv3ciphers);
free(sslv2ciphers);
free(sslv3ciphers);
return cc;
}
int Curl_gskit_init(void)
{
/* No initialisation needed. */
return 1;
}
void Curl_gskit_cleanup(void)
{
/* Nothing to do. */
}
static CURLcode init_environment(struct SessionHandle * data,
gsk_handle * envir, const char * appid,
const char * file, const char * label,
const char * password)
{
int rc;
CURLcode c;
gsk_handle h;
/* Creates the GSKit environment. */
rc = gsk_environment_open(&h);
switch (rc) {
case GSK_OK:
break;
case GSK_INSUFFICIENT_STORAGE:
return CURLE_OUT_OF_MEMORY;
default:
failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
}
c = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION);
if(c == CURLE_OK && appid)
c = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid);
if(c == CURLE_OK && file)
c = set_buffer(data, h, GSK_KEYRING_FILE, file);
if(c == CURLE_OK && label)
c = set_buffer(data, h, GSK_KEYRING_LABEL, label);
if(c == CURLE_OK && password)
c = set_buffer(data, h, GSK_KEYRING_PW, password);
if(c == CURLE_OK) {
/* Locate CAs, Client certificate and key according to our settings.
Note: this call may be blocking for some tenths of seconds. */
c = gskit_status(data, gsk_environment_init(h),
"gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
if(c == CURLE_OK) {
*envir = h;
return c;
}
}
/* Error: rollback. */
gsk_environment_close(&h);
return c;
}
static void cancel_async_handshake(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL);
}
static void close_async_handshake(struct ssl_connect_data * connssl)
{
QsoDestroyIOCompletionPort(connssl->iocport);
connssl->iocport = -1;
}
static void close_one(struct ssl_connect_data * conn,
struct SessionHandle * data)
{
if(conn->handle) {
gskit_status(data, gsk_secure_soc_close(&conn->handle),
"gsk_secure_soc_close()", 0);
conn->handle = (gsk_handle) NULL;
}
if(conn->iocport >= 0)
close_async_handshake(conn);
}
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;
int written;
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;
}
return (ssize_t) written; /* number of bytes */
}
static ssize_t gskit_recv(struct connectdata * conn, int num, char * buf,
size_t buffersize, CURLcode * curlcode)
{
struct SessionHandle * data = conn->data;
int buffsize;
int nread;
CURLcode cc;
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;
}
return (ssize_t) nread;
}
static CURLcode gskit_connect_step1(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
gsk_handle envir;
CURLcode cc;
int rc;
char * keyringfile;
char * keyringpwd;
char * keyringlabel;
char * v2ciphers;
char * v3ciphers;
char * sni;
bool sslv2enable, sslv3enable, tlsv1enable;
long timeout;
Qso_OverlappedIO_t commarea;
/* Create SSL environment, start (preferably asynchronous) handshake. */
connssl->handle = (gsk_handle) NULL;
connssl->iocport = -1;
/* GSKit supports two ways of specifying an SSL context: either by
* application identifier (that should have been defined at the system
* level) or by keyring file, password and certificate label.
* Local certificate name (CURLOPT_SSLCERT) is used to hold either the
* application identifier of the certificate label.
* Key password (CURLOPT_KEYPASSWD) holds the keyring password.
* It is not possible to have different keyrings for the CAs and the
* local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
* the keyring file.
* If no key password is given and the keyring is the system keyring,
* 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 &&
!strcmp(keyringfile, CURL_CA_BUNDLE)) {
/* Try application identifier mode. */
init_environment(data, &envir, keyringlabel, (const char *) NULL,
(const char *) NULL, (const char *) NULL);
}
if(!envir) {
/* Use keyring mode. */
cc = init_environment(data, &envir, (const char *) NULL,
keyringfile, keyringlabel, keyringpwd);
if(cc != CURLE_OK)
return cc;
}
/* Create secure session. */
cc = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle),
"gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
gsk_environment_close(&envir);
if(cc != CURLE_OK)
return cc;
/* Determine which SSL/TLS version should be enabled. */
sslv2enable = sslv3enable = tlsv1enable = false;
sni = conn->host.name;
switch (data->set.ssl.version) {
case CURL_SSLVERSION_SSLv2:
sslv2enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_SSLv3:
sslv3enable = true;
sni = (char *) NULL;
break;
case CURL_SSLVERSION_TLSv1:
tlsv1enable = true;
break;
default: /* CURL_SSLVERSION_DEFAULT. */
sslv3enable = true;
tlsv1enable = true;
break;
}
/* Process SNI. Ignore if not supported (on OS400 < V7R1). */
if(sni) {
rc = gsk_attribute_set_buffer(connssl->handle,
GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, 0);
switch (rc) {
case GSK_OK:
case GSK_ATTRIBUTE_INVALID_ID:
break;
case GSK_ERROR_IO:
failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
cc = CURLE_SSL_CONNECT_ERROR;
break;
default:
failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
cc = CURLE_SSL_CONNECT_ERROR;
break;
}
}
/* Set session parameters. */
if(cc == CURLE_OK) {
/* Compute the handshake timeout. Since GSKit granularity is 1 second,
we round up the required value. */
timeout = Curl_timeleft(data, NULL, TRUE);
if(timeout < 0)
cc = CURLE_OPERATION_TIMEDOUT;
else
cc = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT,
(timeout + 999) / 1000);
}
if(cc == CURLE_OK)
cc = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]);
if(cc == CURLE_OK)
cc = set_ciphers(data, connssl->handle);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2,
sslv2enable? GSK_PROTOCOL_SSLV2_ON:
GSK_PROTOCOL_SSLV2_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3,
sslv3enable? GSK_PROTOCOL_SSLV3_ON:
GSK_PROTOCOL_SSLV3_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1,
sslv3enable? GSK_PROTOCOL_TLSV1_ON:
GSK_PROTOCOL_TLSV1_OFF);
if(cc == CURLE_OK)
cc = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE,
data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL:
GSK_SERVER_AUTH_PASSTHRU);
if(cc == CURLE_OK) {
/* Start handshake. Try asynchronous first. */
memset(&commarea, 0, sizeof commarea);
connssl->iocport = QsoCreateIOCompletionPort();
if(connssl->iocport != -1) {
cc = gskit_status(data, gsk_secure_soc_startInit(connssl->handle,
connssl->iocport, &commarea),
"gsk_secure_soc_startInit()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
else
close_async_handshake(connssl);
}
else if(errno != ENOBUFS)
cc = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0);
else {
/* No more completion port available. Use synchronous IO. */
cc = gskit_status(data, gsk_secure_soc_init(connssl->handle),
"gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK) {
connssl->connecting_state = ssl_connect_3;
return CURLE_OK;
}
}
}
/* Error: rollback. */
close_one(connssl, data);
return cc;
}
static CURLcode gskit_connect_step2(struct connectdata * conn, int sockindex,
bool nonblocking)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
Qso_OverlappedIO_t cstat;
long timeout_ms;
struct timeval stmv;
CURLcode cc;
/* Poll or wait for end of SSL asynchronous handshake. */
for(;;) {
timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0)
timeout_ms = 0;
stmv.tv_sec = timeout_ms / 1000;
stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) {
case 1: /* Operation complete. */
break;
case -1: /* An error occurred: handshake still in progress. */
if(errno == EINTR) {
if(nonblocking)
return CURLE_OK;
continue; /* Retry. */
}
if(errno != ETIME) {
failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_SSL_CONNECT_ERROR;
}
/* FALL INTO... */
case 0: /* Handshake in progress, timeout occurred. */
if(nonblocking)
return CURLE_OK;
cancel_async_handshake(conn, sockindex);
close_async_handshake(connssl);
return CURLE_OPERATION_TIMEDOUT;
}
break;
}
cc = gskit_status(data, cstat.returnValue, "SSL handshake",
CURLE_SSL_CONNECT_ERROR);
if(cc == CURLE_OK)
connssl->connecting_state = ssl_connect_3;
close_async_handshake(connssl);
return cc;
}
static CURLcode gskit_connect_step3(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
const gsk_cert_data_elem * cdev;
int cdec;
const gsk_cert_data_elem * p;
const char * cert = (const char *) NULL;
const char * certend;
int i;
CURLcode cc;
/* SSL handshake done: gather certificate info and verify host. */
if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle,
GSK_PARTNER_CERT_INFO,
&cdev, &cdec),
"gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
CURLE_OK) {
infof(data, "Server certificate:\n");
p = cdev;
for(i = 0; i++ < cdec; p++)
switch (p->cert_data_id) {
case CERT_BODY_DER:
cert = p->cert_data_p;
certend = cert + cdev->cert_data_l;
break;
case CERT_DN_PRINTABLE:
infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_ISSUER_DN_PRINTABLE:
infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_FROM:
infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
case CERT_VALID_TO:
infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
break;
}
}
/* Verify host. */
cc = Curl_verifyhost(conn, cert, certend);
if(cc != CURLE_OK)
return cc;
/* The only place GSKit can get the whole CA chain is a validation
callback where no user data pointer is available. Therefore it's not
possible to copy this chain into our structures for CAINFO.
However the server certificate may be available, thus we can return
info about it. */
if(data->set.ssl.certinfo) {
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(cert) {
cc = Curl_extract_certinfo(conn, 0, cert, certend);
if(cc != CURLE_OK)
return cc;
}
}
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
static CURLcode gskit_connect_common(struct connectdata * conn, int sockindex,
bool nonblocking, bool * done)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
long timeout_ms;
Qso_OverlappedIO_t cstat;
CURLcode cc = CURLE_OK;
*done = connssl->state == ssl_connection_complete;
if(*done)
return CURLE_OK;
/* Step 1: create session, start handshake. */
if(connssl->connecting_state == ssl_connect_1) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step1(conn, sockindex);
}
/* Step 2: check if handshake is over. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_2) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
cc = CURLE_OPERATION_TIMEDOUT;
}
else
cc = gskit_connect_step2(conn, sockindex, nonblocking);
}
/* Step 3: gather certificate info, verify host. */
if(cc == CURLE_OK && connssl->connecting_state == ssl_connect_3)
cc = gskit_connect_step3(conn, sockindex);
if(cc != CURLE_OK)
close_one(connssl, data);
else if(connssl->connecting_state == ssl_connect_done) {
connssl->state = ssl_connection_complete;
connssl->connecting_state = ssl_connect_1;
conn->recv[sockindex] = gskit_recv;
conn->send[sockindex] = gskit_send;
*done = TRUE;
}
return cc;
}
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex,
bool * done)
{
CURLcode cc;
cc = gskit_connect_common(conn, sockindex, TRUE, done);
if(*done || cc != CURLE_OK)
conn->ssl[sockindex].connecting_state = ssl_connect_1;
return cc;
}
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex)
{
CURLcode retcode;
bool done;
conn->ssl[sockindex].connecting_state = ssl_connect_1;
retcode = gskit_connect_common(conn, sockindex, FALSE, &done);
if(retcode)
return retcode;
DEBUGASSERT(done);
return CURLE_OK;
}
void Curl_gskit_close(struct connectdata * conn, int sockindex)
{
struct SessionHandle * data = conn->data;
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
if(connssl->use)
close_one(connssl, data);
}
int Curl_gskit_close_all(struct SessionHandle * data)
{
/* Unimplemented. */
(void) data;
return 0;
}
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex)
{
struct ssl_connect_data * connssl = &conn->ssl[sockindex];
struct SessionHandle * data = conn->data;
ssize_t nread;
int what;
int rc;
char buf[120];
if(!connssl->handle)
return 0;
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
return 0;
close_one(connssl, data);
rc = 0;
what = Curl_socket_ready(conn->sock[sockindex],
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
for(;;) {
if(what < 0) {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
rc = -1;
break;
}
if(!what) { /* timeout */
failf(data, "SSL shutdown timeout");
break;
}
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to gsk_secure_soc_read() now, so
use read(). */
nread = read(conn->sock[sockindex], buf, sizeof(buf));
if(nread < 0) {
failf(data, "read: %s", strerror(errno));
rc = -1;
}
if(nread <= 0)
break;
what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0);
}
return rc;
}
size_t Curl_gskit_version(char * buffer, size_t size)
{
strncpy(buffer, "GSKit", size);
return strlen(buffer);
}
int Curl_gskit_check_cxn(struct connectdata * cxn)
{
int err;
int errlen;
/* The only thing that can be tested here is at the socket level. */
if(!cxn->ssl[FIRSTSOCKET].handle)
return 0; /* connection has been closed */
err = 0;
errlen = sizeof err;
if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
(unsigned char *) &err, &errlen) ||
errlen != sizeof err || err)
return 0; /* connection has been closed */
return -1; /* connection status unknown */
}
#endif /* USE_GSKIT */

64
lib/gskit.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef HEADER_CURL_GSKIT_H
#define HEADER_CURL_GSKIT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
/*
* This header should only be needed to get included by sslgen.c and gskit.c
*/
#include "urldata.h"
#ifdef USE_GSKIT
int Curl_gskit_init(void);
void Curl_gskit_cleanup(void);
CURLcode Curl_gskit_connect(struct connectdata * conn, int sockindex);
CURLcode Curl_gskit_connect_nonblocking(struct connectdata * conn,
int sockindex, bool * done);
void Curl_gskit_close(struct connectdata *conn, int sockindex);
int Curl_gskit_close_all(struct SessionHandle * data);
int Curl_gskit_shutdown(struct connectdata * conn, int sockindex);
size_t Curl_gskit_version(char * buffer, size_t size);
int Curl_gskit_check_cxn(struct connectdata * cxn);
/* API setup for GSKit */
#define curlssl_init Curl_gskit_init
#define curlssl_cleanup Curl_gskit_cleanup
#define curlssl_connect Curl_gskit_connect
#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking
/* No session handling for GSKit */
#define curlssl_session_free(x) Curl_nop_stmt
#define curlssl_close_all Curl_gskit_close_all
#define curlssl_close Curl_gskit_close
#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y)
#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN
#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN
#define curlssl_engines_list(x) NULL
#define curlssl_version Curl_gskit_version
#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x)
#define curlssl_data_pending(x,y) 0
#endif /* USE_GSKIT */
#endif /* HEADER_CURL_GSKIT_H */

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -55,6 +55,10 @@ void Curl_gtls_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for GnuTLS */
#define curlssl_init Curl_gtls_init
#define curlssl_cleanup Curl_gtls_cleanup

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -391,7 +391,7 @@ void Curl_hash_print(struct curl_hash *h,
if(func)
func(he->ptr);
else
fprintf(stderr, " [%p]", he->ptr);
fprintf(stderr, " [%p]", (void *)he->ptr);
he = Curl_hash_next_element(&iter);
}

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -22,8 +22,9 @@
#include "curl_setup.h"
#if defined(USE_SSLEAY) || defined(USE_AXTLS)
/* these two backends use functions from this file */
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
defined(USE_GSKIT)
/* these backends use functions from this file */
#include "hostcheck.h"
#include "rawstr.h"
@@ -93,4 +94,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
return 0;
}
#endif /* SSLEAY or AXTLS */
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -140,6 +140,10 @@ struct curl_hash *Curl_global_host_cache_init(void)
void Curl_global_host_cache_dtor(void)
{
if(host_cache_initialized) {
/* first make sure that any custom "CURLOPT_RESOLVE" names are
cleared off */
Curl_hostcache_clean(NULL, &hostname_cache);
/* then free the remaining hash completely */
Curl_hash_clean(&hostname_cache);
host_cache_initialized = 0;
}
@@ -681,12 +685,14 @@ clean_up:
* Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
* made, the struct may be destroyed due to pruning. It is important that only
* one unlock is made for each Curl_resolv() call.
*
* May be called with 'data' == NULL for global cache.
*/
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
{
DEBUGASSERT(dns && (dns->inuse>0));
if(data->share)
if(data && data->share)
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
dns->inuse--;
@@ -697,7 +703,7 @@ void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
free(dns);
}
if(data->share)
if(data && data->share)
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
}
@@ -734,22 +740,23 @@ static int hostcache_inuse(void *data, void *hc)
return 1; /* free all entries */
}
void Curl_hostcache_clean(struct SessionHandle *data)
/*
* Curl_hostcache_clean()
*
* This _can_ be called with 'data' == NULL but then of course no locking
* can be done!
*/
void Curl_hostcache_clean(struct SessionHandle *data,
struct curl_hash *hash)
{
/* Entries added to the hostcache with the CURLOPT_RESOLVE function are
* still present in the cache with the inuse counter set to 1. Detect them
* and cleanup!
*/
Curl_hash_clean_with_criterium(data->dns.hostcache, data, hostcache_inuse);
Curl_hash_clean_with_criterium(hash, data, hostcache_inuse);
}
void Curl_hostcache_destroy(struct SessionHandle *data)
{
Curl_hostcache_clean(data);
Curl_hash_destroy(data->dns.hostcache);
data->dns.hostcachetype = HCACHE_NONE;
data->dns.hostcache = NULL;
}
CURLcode Curl_loadhostpairs(struct SessionHandle *data)
{

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -203,7 +203,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers);
/*
* Clean off entries from the cache
*/
void Curl_hostcache_clean(struct SessionHandle *data);
void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash);
/*
* Destroy the hostcache of this handle.

View File

@@ -25,14 +25,13 @@
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
#include "urldata.h"
#include "sendf.h"
#include "rawstr.h"
#include "curl_base64.h"
#include "curl_md5.h"
#include "http_digest.h"
#include "strtok.h"
#include "url.h" /* for Curl_safefree() */
#include "curl_memory.h"
#include "sslgen.h" /* for Curl_rand() */
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
#include "warnless.h"
@@ -267,6 +266,38 @@ static void md5_to_ascii(unsigned char *source, /* 16 bytes */
snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
}
/* Perform quoted-string escaping as described in RFC2616 and its errata */
static char *string_quoted(const char *source)
{
char *dest, *d;
const char *s = source;
size_t n = 1; /* null terminator */
/* Calculate size needed */
while(*s) {
++n;
if(*s == '"' || *s == '\\') {
++n;
}
++s;
}
dest = malloc(n);
if(dest) {
s = source;
d = dest;
while(*s) {
if(*s == '"' || *s == '\\') {
*d++ = '\\';
}
*d++ = *s++;
}
*d = 0;
}
return dest;
}
CURLcode Curl_output_digest(struct connectdata *conn,
bool proxy,
const unsigned char *request,
@@ -278,17 +309,16 @@ CURLcode Curl_output_digest(struct connectdata *conn,
unsigned char md5buf[16]; /* 16 bytes/128 bits */
unsigned char request_digest[33];
unsigned char *md5this;
unsigned char *ha1;
unsigned char ha1[33];/* 32 digits and 1 zero byte */
unsigned char ha2[33];/* 32 digits and 1 zero byte */
char cnoncebuf[33];
char *cnonce = NULL;
size_t cnonce_sz = 0;
char *tmp = NULL;
struct timeval now;
char **allocuserpwd;
size_t userlen;
const char *userp;
char *userp_quoted;
const char *passwdp;
struct auth *authp;
@@ -321,10 +351,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
authp = &data->state.authhost;
}
if(*allocuserpwd) {
Curl_safefree(*allocuserpwd);
*allocuserpwd = NULL;
}
Curl_safefree(*allocuserpwd);
/* not set means empty */
if(!userp)
@@ -343,10 +370,11 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nc = 1;
if(!d->cnonce) {
/* Generate a cnonce */
now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%32ld",
(long)now.tv_sec + now.tv_usec);
struct timeval now = Curl_tvnow();
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
Curl_rand(data), Curl_rand(data),
(unsigned int)now.tv_sec,
(unsigned int)now.tv_usec);
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
&cnonce, &cnonce_sz);
@@ -373,12 +401,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
ha1 = malloc(33); /* 32 digits and 1 zero byte */
if(!ha1)
return CURLE_OUT_OF_MEMORY;
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha1);
if(d->algo == CURLDIGESTALGO_MD5SESS) {
@@ -388,7 +411,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
Curl_md5it(md5buf, (unsigned char *)tmp);
free(tmp); /* free this again */
Curl_safefree(tmp);
md5_to_ascii(md5buf, ha1);
}
@@ -425,19 +448,21 @@ CURLcode Curl_output_digest(struct connectdata *conn,
else
md5this = (unsigned char *)aprintf("%s:%s", request, uripath);
if(!md5this) {
free(ha1);
return CURLE_OUT_OF_MEMORY;
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
/* We don't support auth-int for PUT or POST at the moment.
TODO: replace md5 of empty string with entity-body for PUT/POST */
unsigned char *md5this2 = (unsigned char *)
aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
Curl_safefree(md5this);
md5this = md5this2;
}
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
/* We don't support auth-int at the moment. I can't see a easy way to get
entity-body here */
/* TODO: Append H(entity-body)*/
}
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, ha2);
if(d->qop) {
@@ -455,20 +480,30 @@ CURLcode Curl_output_digest(struct connectdata *conn,
d->nonce,
ha2);
}
free(ha1);
if(!md5this)
return CURLE_OUT_OF_MEMORY;
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
Curl_md5it(md5buf, md5this);
free(md5this); /* free this again */
Curl_safefree(md5this);
md5_to_ascii(md5buf, request_digest);
/* for test case 64 (snooped from a Mozilla 1.3a request)
Authorization: Digest username="testuser", realm="testrealm", \
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
Digest parameters are all quoted strings. Username which is provided by
the user will need double quotes and backslashes within it escaped. For
the other fields, this shouldn't be an issue. realm, nonce, and opaque
are copied as is from the server, escapes and all. cnonce is generated
with web-safe characters. uri is already percent encoded. nc is 8 hex
characters. algorithm and qop with standard values only contain web-safe
chracters.
*/
userp_quoted = string_quoted(userp);
if(!userp_quoted)
return CURLE_OUT_OF_MEMORY;
if(d->qop) {
*allocuserpwd =
@@ -482,7 +517,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"qop=%s, "
"response=\"%s\"",
proxy?"Proxy-":"",
userp,
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
@@ -505,12 +540,13 @@ CURLcode Curl_output_digest(struct connectdata *conn,
"uri=\"%s\", "
"response=\"%s\"",
proxy?"Proxy-":"",
userp,
userp_quoted,
d->realm,
d->nonce,
uripath, /* this is the PATH part of the URL */
request_digest);
}
Curl_safefree(userp_quoted);
if(!*allocuserpwd)
return CURLE_OUT_OF_MEMORY;
@@ -546,29 +582,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
static void digest_cleanup_one(struct digestdata *d)
{
if(d->nonce)
free(d->nonce);
d->nonce = NULL;
if(d->cnonce)
free(d->cnonce);
d->cnonce = NULL;
if(d->realm)
free(d->realm);
d->realm = NULL;
if(d->opaque)
free(d->opaque);
d->opaque = NULL;
if(d->qop)
free(d->qop);
d->qop = NULL;
if(d->algorithm)
free(d->algorithm);
d->algorithm = NULL;
Curl_safefree(d->nonce);
Curl_safefree(d->cnonce);
Curl_safefree(d->realm);
Curl_safefree(d->opaque);
Curl_safefree(d->qop);
Curl_safefree(d->algorithm);
d->nc = 0;
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */

View File

@@ -77,6 +77,7 @@
#include "url.h"
#include "rawstr.h"
#include "curl_sasl.h"
#include "warnless.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -86,8 +87,6 @@
#include "memdebug.h"
/* Local API functions */
static CURLcode imap_parse_url_path(struct connectdata *conn);
static CURLcode imap_parse_custom_request(struct connectdata *conn);
static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done);
static CURLcode imap_do(struct connectdata *conn, bool *done);
static CURLcode imap_done(struct connectdata *conn, CURLcode status,
@@ -99,6 +98,11 @@ static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
static CURLcode imap_setup_connection(struct connectdata *conn);
static char *imap_atom(const char *str);
static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
static CURLcode imap_parse_url_options(struct connectdata *conn);
static CURLcode imap_parse_url_path(struct connectdata *conn);
static CURLcode imap_parse_custom_request(struct connectdata *conn);
/*
* IMAP protocol handler.
@@ -213,119 +217,6 @@ static void imap_to_imaps(struct connectdata *conn)
#define imap_to_imaps(x) Curl_nop_stmt
#endif
/***********************************************************************
*
* imap_sendf()
*
* Sends the formated string as an IMAP command to the server.
*
* Designed to never block.
*/
static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
char *taggedfmt;
va_list ap;
va_start(ap, fmt);
/* Calculate the next command ID wrapping at 3 digits */
imapc->cmdid = (imapc->cmdid + 1) % 1000;
/* Calculate the tag based on the connection ID and command ID */
snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
'A' + (conn->connection_id % 26), imapc->cmdid);
/* Prefix the format with the tag */
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
if(!taggedfmt)
return CURLE_OUT_OF_MEMORY;
/* Send the data with the tag */
result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
Curl_safefree(taggedfmt);
va_end(ap);
return result;
}
/***********************************************************************
*
* imap_atom()
*
* Checks the input string for characters that need escaping and returns an
* atom ready for sending to the server.
*
* The returned string needs to be freed.
*
*/
static char *imap_atom(const char *str)
{
const char *p1;
char *p2;
size_t backsp_count = 0;
size_t quote_count = 0;
bool space_exists = FALSE;
size_t newlen = 0;
char *newstr = NULL;
if(!str)
return NULL;
/* Count any unescapped characters */
p1 = str;
while(*p1) {
if(*p1 == '\\')
backsp_count++;
else if(*p1 == '"')
quote_count++;
else if(*p1 == ' ')
space_exists = TRUE;
p1++;
}
/* Does the input contain any unescapped characters? */
if(!backsp_count && !quote_count && !space_exists)
return strdup(str);
/* Calculate the new string length */
newlen = strlen(str) + backsp_count + quote_count + (space_exists ? 2 : 0);
/* Allocate the new string */
newstr = (char *) malloc((newlen + 1) * sizeof(char));
if(!newstr)
return NULL;
/* Surround the string in quotes if necessary */
p2 = newstr;
if(space_exists) {
newstr[0] = '"';
newstr[newlen - 1] = '"';
p2++;
}
/* Copy the string, escaping backslash and quote characters along the way */
p1 = str;
while(*p1) {
if(*p1 == '\\' || *p1 == '"') {
*p2 = '\\';
p2++;
}
*p2 = *p1;
p1++;
p2++;
}
/* Terminate the string */
newstr[newlen] = '\0';
return newstr;
}
/***********************************************************************
*
* imap_matchresp()
@@ -508,7 +399,7 @@ static void state(struct connectdata *conn, imapstate newstate)
if(imapc->state != newstate)
infof(conn->data, "IMAP %p state change from %s to %s\n",
imapc, names[imapc->state], names[newstate]);
(void *)imapc, names[imapc->state], names[newstate]);
#endif
imapc->state = newstate;
@@ -635,6 +526,7 @@ static CURLcode imap_perform_login(struct connectdata *conn)
static CURLcode imap_perform_authenticate(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
const char *mech = NULL;
char *initresp = NULL;
@@ -653,12 +545,14 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
/* Calculate the supported authentication mechanism by decreasing order of
security */
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(imapc->authmechs & SASL_MECH_DIGEST_MD5) {
if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
(imapc->prefmech & SASL_MECH_DIGEST_MD5)) {
mech = "DIGEST-MD5";
state1 = IMAP_AUTHENTICATE_DIGESTMD5;
imapc->authused = SASL_MECH_DIGEST_MD5;
}
else if(imapc->authmechs & SASL_MECH_CRAM_MD5) {
else if((imapc->authmechs & SASL_MECH_CRAM_MD5) &&
(imapc->prefmech & SASL_MECH_CRAM_MD5)) {
mech = "CRAM-MD5";
state1 = IMAP_AUTHENTICATE_CRAMMD5;
imapc->authused = SASL_MECH_CRAM_MD5;
@@ -666,67 +560,69 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
else
#endif
#ifdef USE_NTLM
if(imapc->authmechs & SASL_MECH_NTLM) {
if((imapc->authmechs & SASL_MECH_NTLM) &&
(imapc->prefmech & SASL_MECH_NTLM)) {
mech = "NTLM";
state1 = IMAP_AUTHENTICATE_NTLM;
state2 = IMAP_AUTHENTICATE_NTLM_TYPE2MSG;
imapc->authused = SASL_MECH_NTLM;
if(imapc->ir_supported)
if(imapc->ir_supported || data->set.sasl_ir)
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
&conn->ntlm,
&initresp, &len);
}
else
#endif
if(imapc->authmechs & SASL_MECH_LOGIN) {
if((imapc->authmechs & SASL_MECH_LOGIN) &&
(imapc->prefmech & SASL_MECH_LOGIN)) {
mech = "LOGIN";
state1 = IMAP_AUTHENTICATE_LOGIN;
state2 = IMAP_AUTHENTICATE_LOGIN_PASSWD;
imapc->authused = SASL_MECH_LOGIN;
if(imapc->ir_supported)
if(imapc->ir_supported || data->set.sasl_ir)
result = Curl_sasl_create_login_message(conn->data, conn->user,
&initresp, &len);
}
else if(imapc->authmechs & SASL_MECH_PLAIN) {
else if((imapc->authmechs & SASL_MECH_PLAIN) &&
(imapc->prefmech & SASL_MECH_PLAIN)) {
mech = "PLAIN";
state1 = IMAP_AUTHENTICATE_PLAIN;
state2 = IMAP_AUTHENTICATE_FINAL;
imapc->authused = SASL_MECH_PLAIN;
if(imapc->ir_supported)
if(imapc->ir_supported || data->set.sasl_ir)
result = Curl_sasl_create_plain_message(conn->data, conn->user,
conn->passwd, &initresp, &len);
}
if(result)
return result;
if(!result) {
if(mech) {
/* Perform SASL based authentication */
if(initresp) {
result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
if(mech) {
/* Perform SASL based authentication */
if(initresp) {
result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
if(!result)
state(conn, state2);
}
else {
result = imap_sendf(conn, "AUTHENTICATE %s", mech);
if(!result)
state(conn, state2);
if(!result)
state(conn, state1);
}
Curl_safefree(initresp);
}
else if(!imapc->login_disabled)
/* Perform clear text authentication */
result = imap_perform_login(conn);
else {
result = imap_sendf(conn, "AUTHENTICATE %s", mech);
if(!result)
state(conn, state1);
/* Other mechanisms not supported */
infof(conn->data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
Curl_safefree(initresp);
}
else if(!imapc->login_disabled)
/* Perform clear text authentication */
result = imap_perform_login(conn);
else {
/* Other mechanisms not supported */
infof(conn->data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
return result;
@@ -1257,7 +1153,7 @@ static CURLcode imap_state_auth_digest_resp_resp(struct connectdata *conn,
}
else {
/* Send an empty response */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "");
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
if(!result)
state(conn, IMAP_AUTHENTICATE_FINAL);
@@ -1793,12 +1689,13 @@ static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
/***********************************************************************
*
* imap_connect() should do everything that is to be considered a part of
* the connection phase.
* imap_connect()
*
* This function should do everything that is to be considered a part of the
* connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*/
static CURLcode imap_connect(struct connectdata *conn, bool *done)
{
@@ -1826,9 +1723,17 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
pp->endofresp = imap_endofresp;
pp->conn = conn;
/* Set the default preferred authentication mechanism */
imapc->prefmech = SASL_AUTH_ANY;
/* Initialise the pingpong layer */
Curl_pp_init(pp);
/* Parse the URL options */
result = imap_parse_url_options(conn);
if(result)
return result;
/* Start off waiting for the server greeting response */
state(conn, IMAP_SERVERGREET);
@@ -1876,7 +1781,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status,
state(conn, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
result = Curl_pp_sendf(&conn->proto.imapc.pp, "");
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
if(!result)
state(conn, IMAP_APPEND_FINAL);
}
@@ -2044,6 +1949,220 @@ static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
return CURLE_OK;
}
/* Call this when the DO phase has completed */
static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
{
struct IMAP *imap = conn->data->state.proto.imap;
(void)connected;
if(imap->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
return CURLE_OK;
}
/* Called from multi.c while DOing */
static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
{
CURLcode result = imap_multi_statemach(conn, dophase_done);
if(result)
DEBUGF(infof(conn->data, "DO phase failed\n"));
else if(*dophase_done) {
result = imap_dophase_done(conn, FALSE /* not connected */);
DEBUGF(infof(conn->data, "DO phase is complete\n"));
}
return result;
}
/***********************************************************************
*
* imap_regular_transfer()
*
* The input argument is already checked for validity.
*
* Performs all commands done before a regular transfer between a local and a
* remote host.
*/
static CURLcode imap_regular_transfer(struct connectdata *conn,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
struct SessionHandle *data = conn->data;
/* Make sure size is unknown at this point */
data->req.size = -1;
/* Set the progress data */
Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0);
Curl_pgrsSetUploadSize(data, 0);
Curl_pgrsSetDownloadSize(data, 0);
/* Carry out the perform */
result = imap_perform(conn, &connected, dophase_done);
/* Perform post DO phase operations if necessary */
if(!result && *dophase_done)
result = imap_dophase_done(conn, connected);
return result;
}
static CURLcode imap_setup_connection(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel IMAP operations through the proxy, we
switch and use HTTP operations only */
#ifndef CURL_DISABLE_HTTP
if(conn->handler == &Curl_handler_imap)
conn->handler = &Curl_handler_imap_proxy;
else {
#ifdef USE_SSL
conn->handler = &Curl_handler_imaps_proxy;
#else
failf(data, "IMAPS not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
/* We explicitly mark this connection as persistent here as we're doing
IMAP over HTTP and thus we accidentally avoid setting this value
otherwise */
conn->bits.close = FALSE;
#else
failf(data, "IMAP over http proxy requires HTTP support built-in!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
data->state.path++; /* don't include the initial slash */
return CURLE_OK;
}
/***********************************************************************
*
* imap_sendf()
*
* Sends the formated string as an IMAP command to the server.
*
* Designed to never block.
*/
static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
char *taggedfmt;
va_list ap;
DEBUGASSERT(fmt);
/* Calculate the next command ID wrapping at 3 digits */
imapc->cmdid = (imapc->cmdid + 1) % 1000;
/* Calculate the tag based on the connection ID and command ID */
snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
/* Prefix the format with the tag */
taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
if(!taggedfmt)
return CURLE_OUT_OF_MEMORY;
/* Send the data with the tag */
va_start(ap, fmt);
result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
va_end(ap);
Curl_safefree(taggedfmt);
return result;
}
/***********************************************************************
*
* imap_atom()
*
* Checks the input string for characters that need escaping and returns an
* atom ready for sending to the server.
*
* The returned string needs to be freed.
*
*/
static char *imap_atom(const char *str)
{
const char *p1;
char *p2;
size_t backsp_count = 0;
size_t quote_count = 0;
bool space_exists = FALSE;
size_t newlen = 0;
char *newstr = NULL;
if(!str)
return NULL;
/* Count any unescapped characters */
p1 = str;
while(*p1) {
if(*p1 == '\\')
backsp_count++;
else if(*p1 == '"')
quote_count++;
else if(*p1 == ' ')
space_exists = TRUE;
p1++;
}
/* Does the input contain any unescapped characters? */
if(!backsp_count && !quote_count && !space_exists)
return strdup(str);
/* Calculate the new string length */
newlen = strlen(str) + backsp_count + quote_count + (space_exists ? 2 : 0);
/* Allocate the new string */
newstr = (char *) malloc((newlen + 1) * sizeof(char));
if(!newstr)
return NULL;
/* Surround the string in quotes if necessary */
p2 = newstr;
if(space_exists) {
newstr[0] = '"';
newstr[newlen - 1] = '"';
p2++;
}
/* Copy the string, escaping backslash and quote characters along the way */
p1 = str;
while(*p1) {
if(*p1 == '\\' || *p1 == '"') {
*p2 = '\\';
p2++;
}
*p2 = *p1;
p1++;
p2++;
}
/* Terminate the string */
newstr[newlen] = '\0';
return newstr;
}
/***********************************************************************
*
* imap_is_bchar()
@@ -2082,6 +2201,52 @@ static bool imap_is_bchar(char ch)
}
}
/***********************************************************************
*
* imap_parse_url_options()
*
* Parse the URL login options.
*/
static CURLcode imap_parse_url_options(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
const char *options = conn->options;
const char *ptr = options;
if(options) {
const char *key = ptr;
while(*ptr && *ptr != '=')
ptr++;
if(strnequal(key, "AUTH", 4)) {
const char *value = ptr + 1;
if(strequal(value, "*"))
imapc->prefmech = SASL_AUTH_ANY;
else if(strequal(value, "LOGIN"))
imapc->prefmech = SASL_MECH_LOGIN;
else if(strequal(value, "PLAIN"))
imapc->prefmech = SASL_MECH_PLAIN;
else if(strequal(value, "CRAM-MD5"))
imapc->prefmech = SASL_MECH_CRAM_MD5;
else if(strequal(value, "DIGEST-MD5"))
imapc->prefmech = SASL_MECH_DIGEST_MD5;
else if(strequal(value, "GSSAPI"))
imapc->prefmech = SASL_MECH_GSSAPI;
else if(strequal(value, "NTLM"))
imapc->prefmech = SASL_MECH_NTLM;
else
imapc->prefmech = SASL_AUTH_NONE;
}
else
result = CURLE_URL_MALFORMAT;
}
return result;
}
/***********************************************************************
*
* imap_parse_url_path()
@@ -2192,6 +2357,12 @@ static CURLcode imap_parse_url_path(struct connectdata *conn)
return CURLE_OK;
}
/***********************************************************************
*
* imap_parse_custom_request()
*
* Parse the custom request.
*/
static CURLcode imap_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -2223,103 +2394,4 @@ static CURLcode imap_parse_custom_request(struct connectdata *conn)
return result;
}
/* Call this when the DO phase has completed */
static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
{
struct IMAP *imap = conn->data->state.proto.imap;
(void)connected;
if(imap->transfer != FTPTRANSFER_BODY)
/* no data to transfer */
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
return CURLE_OK;
}
/* Called from multi.c while DOing */
static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
{
CURLcode result = imap_multi_statemach(conn, dophase_done);
if(result)
DEBUGF(infof(conn->data, "DO phase failed\n"));
else if(*dophase_done) {
result = imap_dophase_done(conn, FALSE /* not connected */);
DEBUGF(infof(conn->data, "DO phase is complete\n"));
}
return result;
}
/***********************************************************************
*
* imap_regular_transfer()
*
* The input argument is already checked for validity.
*
* Performs all commands done before a regular transfer between a local and a
* remote host.
*/
static CURLcode imap_regular_transfer(struct connectdata *conn,
bool *dophase_done)
{
CURLcode result = CURLE_OK;
bool connected = FALSE;
struct SessionHandle *data = conn->data;
/* Make sure size is unknown at this point */
data->req.size = -1;
/* Set the progress data */
Curl_pgrsSetUploadCounter(data, 0);
Curl_pgrsSetDownloadCounter(data, 0);
Curl_pgrsSetUploadSize(data, 0);
Curl_pgrsSetDownloadSize(data, 0);
/* Carry out the perform */
result = imap_perform(conn, &connected, dophase_done);
/* Perform post DO phase operations if necessary */
if(!result && *dophase_done)
result = imap_dophase_done(conn, connected);
return result;
}
static CURLcode imap_setup_connection(struct connectdata *conn)
{
struct SessionHandle *data = conn->data;
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel IMAP operations through the proxy, we
switch and use HTTP operations only */
#ifndef CURL_DISABLE_HTTP
if(conn->handler == &Curl_handler_imap)
conn->handler = &Curl_handler_imap_proxy;
else {
#ifdef USE_SSL
conn->handler = &Curl_handler_imaps_proxy;
#else
failf(data, "IMAPS not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
/* We explicitly mark this connection as persistent here as we're doing
IMAP over HTTP and thus we accidentally avoid setting this value
otherwise */
conn->bits.close = FALSE;
#else
failf(data, "IMAP over http proxy requires HTTP support built-in!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
data->state.path++; /* don't include the initial slash */
return CURLE_OK;
}
#endif /* CURL_DISABLE_IMAP */

View File

@@ -76,6 +76,7 @@ struct imap_conn {
imapstate state; /* Always use imap.c:state() to change state! */
bool ssldone; /* Is connect() over SSL done? */
unsigned int authmechs; /* Accepted authentication mechanisms */
unsigned int prefmech; /* Preferred authentication mechanism */
unsigned int authused; /* Auth mechanism used for the connection */
int cmdid; /* Last used command ID */
char resptag[5]; /* Response tag to wait for */

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -260,7 +260,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
server = ldapssl_init(conn->host.name, (int)conn->port, 1);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;
@@ -301,7 +301,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
}
server = ldap_init(conn->host.name, (int)conn->port);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;
@@ -337,7 +337,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
else {
server = ldap_init(conn->host.name, (int)conn->port);
if(server == NULL) {
failf(data, "LDAP local: Cannot connect to %s:%hu",
failf(data, "LDAP local: Cannot connect to %s:%ld",
conn->host.name, conn->port);
status = CURLE_COULDNT_CONNECT;
goto quit;

View File

@@ -90,16 +90,36 @@ static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
# include <md5.h>
# endif
#elif defined(__MAC_10_4) || defined(__IPHONE_5_0)
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
/* For Apple operating systems: CommonCrypto has the functions we need.
The library's headers are even backward-compatible with OpenSSL's
headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
These functions are available on Tiger and later, as well as iOS 2.0
and later. If you're building for an older cat, well, sorry.
These functions are available on Tiger and later, as well as iOS 5.0
and later. If you're building for an older cat, well, sorry. */
# define COMMON_DIGEST_FOR_OPENSSL
Declaring the functions as static like this seems to be a bit more
reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
# include <CommonCrypto/CommonDigest.h>
# define MD5_CTX CC_MD5_CTX
static void MD5_Init(MD5_CTX *ctx)
{
CC_MD5_Init(ctx);
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CC_MD5_Update(ctx, input, inputLen);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
CC_MD5_Final(digest, ctx);
}
#elif defined(_WIN32)

View File

@@ -185,8 +185,10 @@ void *curl_domalloc(size_t wantedsize, int line, const char *source)
}
if(source)
curl_memlog("MEM %s:%d malloc(%zd) = %p\n",
source, line, wantedsize, mem ? mem->mem : 0);
curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
source, line, wantedsize,
mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
@@ -212,7 +214,9 @@ void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
if(source)
curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
source, line, wanted_elements, wanted_size, mem?mem->mem:0);
source, line, wanted_elements, wanted_size,
mem ? (void *)mem->mem : (void *)0);
return (mem ? mem->mem : NULL);
}
@@ -234,12 +238,12 @@ char *curl_dostrdup(const char *str, int line, const char *source)
if(source)
curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
source, line, str, len, mem);
source, line, (void *)str, len, (void *)mem);
return mem;
}
#ifdef WIN32
#if defined(WIN32) && defined(UNICODE)
wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
{
wchar_t *mem;
@@ -259,7 +263,7 @@ wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
if(source)
curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
source, line, str, bsiz, mem);
source, line, (void *)str, bsiz, (void *)mem);
return mem;
}
@@ -295,7 +299,8 @@ void *curl_dorealloc(void *ptr, size_t wantedsize,
mem = (Curl_crealloc)(mem, size);
if(source)
curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
source, line, ptr, wantedsize, mem?mem->mem:NULL);
source, line, (void *)ptr, wantedsize,
mem ? (void *)mem->mem : (void *)0);
if(mem) {
mem->size = wantedsize;
@@ -330,7 +335,7 @@ void curl_dofree(void *ptr, int line, const char *source)
(Curl_cfree)(mem);
if(source)
curl_memlog("MEM %s:%d free(%p)\n", source, line, ptr);
curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
}
curl_socket_t curl_socket(int domain, int type, int protocol,
@@ -343,8 +348,10 @@ curl_socket_t curl_socket(int domain, int type, int protocol,
"FD %s:%d socket() = %zd\n" ;
curl_socket_t sockfd = socket(domain, type, protocol);
if(source && (sockfd != CURL_SOCKET_BAD))
curl_memlog(fmt, source, line, sockfd);
return sockfd;
}
@@ -360,8 +367,10 @@ int curl_socketpair(int domain, int type, int protocol,
"FD %s:%d socketpair() = %zd %zd\n" ;
int res = socketpair(domain, type, protocol, socket_vector);
if(source && (0 == res))
curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
return res;
}
#endif
@@ -377,9 +386,12 @@ curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
struct sockaddr *addr = (struct sockaddr *)saddr;
curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
curl_socket_t sockfd = accept(s, addr, addrlen);
if(source && (sockfd != CURL_SOCKET_BAD))
curl_memlog(fmt, source, line, sockfd);
return sockfd;
}
@@ -408,9 +420,11 @@ FILE *curl_fopen(const char *file, const char *mode,
int line, const char *source)
{
FILE *res=fopen(file, mode);
if(source)
curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
source, line, file, mode, res);
source, line, file, mode, (void *)res);
return res;
}
@@ -419,9 +433,11 @@ FILE *curl_fdopen(int filedes, const char *mode,
int line, const char *source)
{
FILE *res=fdopen(filedes, mode);
if(source)
curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
source, line, filedes, mode, res);
source, line, filedes, mode, (void *)res);
return res;
}
#endif
@@ -433,9 +449,11 @@ int curl_fclose(FILE *file, int line, const char *source)
assert(file != NULL);
res=fclose(file);
if(source)
curl_memlog("FILE %s:%d fclose(%p)\n",
source, line, file);
source, line, (void *)file);
return res;
}

View File

@@ -46,7 +46,7 @@ CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
const char *source);
CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
#ifdef WIN32
#if defined(WIN32) && defined(UNICODE)
CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
const char *source);
#endif
@@ -90,14 +90,15 @@ CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
#ifdef WIN32
# undef wcsdup
# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
# undef _wcsdup
# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
# undef _tcsdup
# ifdef UNICODE
# undef wcsdup
# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
# undef _wcsdup
# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
# undef _tcsdup
# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
# else
# undef _tcsdup
# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
# endif
#endif

View File

@@ -40,7 +40,7 @@ my $url = 'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/
# If the OpenSSL commandline is not in search path you can configure it here!
my $openssl = 'openssl';
my $version = '1.18';
my $version = '1.19';
$opt_w = 76; # default base64 encoded lines length
@@ -164,7 +164,7 @@ while (<TXT>) {
if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) {
$caname = $1;
}
my $untrusted = 0;
my $untrusted = 1;
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
my $data;
while (<TXT>) {
@@ -184,9 +184,8 @@ while (<TXT>) {
# now scan the trust part for untrusted certs
while (<TXT>) {
last if (/^#/);
if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_NOT_TRUSTED$/
or /^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUST_UNKNOWN$/) {
$untrusted = 1;
if (/^CKA_TRUST_SERVER_AUTH\s+CK_TRUST\s+CKT_NSS_TRUSTED_DELEGATOR$/) {
$untrusted = 0;
}
}
if ($untrusted) {

View File

@@ -26,7 +26,7 @@
'* Hacked by Guenter Knauf
'***************************************************************************
Option Explicit
Const myVersion = "0.3.7"
Const myVersion = "0.3.8"
Const myUrl = "http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1"
@@ -130,9 +130,8 @@ For i = 0 To UBound(myLines)
myInsideCert = FALSE
While (i < UBound(myLines)) And Not (myLines(i) = "#")
i = i + 1
If (InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED") Or _
InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUST_UNKNOWN")) Then
myUntrusted = TRUE
If InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR") Then
myUntrusted = FALSE
End If
Wend
If (myUntrusted = TRUE) Then
@@ -182,7 +181,7 @@ For i = 0 To UBound(myLines)
End If
If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then
myInsideCert = TRUE
myUntrusted = FALSE
myUntrusted = TRUE
myData = ""
End If
If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then

View File

@@ -380,11 +380,11 @@ static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
break;
case 'x':
vto[i].type = FORMAT_INT;
flags |= FLAGS_HEX;
flags |= FLAGS_HEX|FLAGS_UNSIGNED;
break;
case 'X':
vto[i].type = FORMAT_INT;
flags |= FLAGS_HEX|FLAGS_UPPER;
flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
break;
case 'c':
vto[i].type = FORMAT_INT;
@@ -633,23 +633,23 @@ static int dprintf_formatf(
OUTCHAR(' ');
break;
}
if(p->flags & FLAGS_UNSIGNED) {
/* Decimal unsigned integer. */
base = 10;
goto unsigned_number;
}
if(p->flags & FLAGS_OCTAL) {
/* Octal unsigned integer. */
base = 8;
goto unsigned_number;
}
if(p->flags & FLAGS_HEX) {
else if(p->flags & FLAGS_HEX) {
/* Hexadecimal unsigned integer. */
digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
base = 16;
goto unsigned_number;
}
else if(p->flags & FLAGS_UNSIGNED) {
/* Decimal unsigned integer. */
base = 10;
goto unsigned_number;
}
/* Decimal integer. */
base = 10;

File diff suppressed because it is too large Load Diff

View File

@@ -59,27 +59,6 @@ typedef enum {
#define GETSOCK_READABLE (0x00ff)
#define GETSOCK_WRITABLE (0xff00)
struct Curl_one_easy {
/* first, two fields for the linked list of these */
struct Curl_one_easy *next;
struct Curl_one_easy *prev;
struct SessionHandle *easy_handle; /* the easy handle for this unit */
struct connectdata *easy_conn; /* the "unit's" connection */
CURLMstate state; /* the handle's state */
CURLcode result; /* previous result */
struct Curl_message msg; /* A single posted message. */
/* Array with the plain socket numbers this handle takes care of, in no
particular order. Note that all sockets are added to the sockhash, where
the state etc are also kept. This array is mostly used to detect when a
socket is to be removed from the hash. See singlesocket(). */
curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
int numsocks;
};
/* This is the struct known as CURLM on the outside */
struct Curl_multi {
/* First a simple identifier to easier detect if a user mix up
@@ -87,7 +66,8 @@ struct Curl_multi {
long type;
/* We have a doubly-linked circular list with easy handles */
struct Curl_one_easy easy;
struct SessionHandle *easyp;
struct SessionHandle *easylp; /* last node */
int num_easy; /* amount of entries in the linked list above. */
int num_alive; /* amount of easy handles that are added but have not yet

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2010, 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
@@ -22,6 +22,8 @@
*
***************************************************************************/
/*
* Prototypes for library-wide functions provided by multi.c
*/
@@ -30,6 +32,10 @@ void Curl_expire(struct SessionHandle *data, long milli);
bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi);
void Curl_multi_handlePipeBreak(struct SessionHandle *data);
/* Internal version of curl_multi_init() accepts size parameters for the
socket and connection hashes */
struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
/* the write bits start at bit 16 for the *getsock() bitmap */
#define GETSOCK_WRITEBITSTART 16
@@ -77,4 +83,16 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
/*
* Curl_multi_closed()
*
* Used by the connect code to tell the multi_socket code that one of the
* sockets we were using have just been closed. This function will then
* remove it from the sockethash for this handle to make the multi_socket API
* behave properly, especially for the case when libcurl will create another
* socket again and it gets the same file descriptor number.
*/
void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
#endif /* HEADER_CURL_MULTIIF_H */

View File

@@ -1482,10 +1482,8 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
size_t len, /* amount to write */
CURLcode *curlcode)
{
int rc;
rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1);
ssize_t rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0,
PR_INTERVAL_NO_WAIT);
if(rc < 0) {
PRInt32 err = PR_GetError();
if(err == PR_WOULD_BLOCK_ERROR)
@@ -1513,9 +1511,8 @@ static ssize_t nss_recv(struct connectdata * conn, /* connection data */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
ssize_t nread;
nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1);
ssize_t nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0,
PR_INTERVAL_NO_WAIT);
if(nread < 0) {
/* failed SSL read */
PRInt32 err = PR_GetError();

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -60,6 +60,10 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
unsigned char *md5sum, /* output */
size_t md5len);
/* this backend provides these functions: */
#define have_curlssl_random 1
#define have_curlssl_md5sum 1
/* API setup for NSS */
#define curlssl_init Curl_nss_init
#define curlssl_cleanup Curl_nss_cleanup

View File

@@ -6,6 +6,7 @@
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
* Copyright (C) 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
@@ -84,9 +85,10 @@ bool Curl_pipeline_penalized(struct SessionHandle *data,
(curl_off_t)conn->chunk.datasize > chunk_penalty_size)
penalized = TRUE;
infof(data, "Conn: %d (%p) Receive pipe weight: (%d/%d), penalized: %d\n",
conn->connection_id, conn, recv_size,
conn->chunk.datasize, penalized);
infof(data, "Conn: %ld (%p) Receive pipe weight: (%" FORMAT_OFF_T
"/%zu), penalized: %s\n",
conn->connection_id, (void *)conn, recv_size,
conn->chunk.datasize, penalized?"TRUE":"FALSE");
return penalized;
}
return FALSE;
@@ -101,7 +103,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
pipeline = conn->send_pipe;
infof(conn->data, "Adding handle: conn: %p\n", conn);
infof(conn->data, "Adding handle: conn: %p\n", (void *)conn);
infof(conn->data, "Adding handle: send: %d\n", conn->send_pipe->size);
infof(conn->data, "Adding handle: recv: %d\n", conn->recv_pipe->size);
rc = Curl_addHandleToPipeline(handle, pipeline);
@@ -111,7 +113,7 @@ CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle,
conn->writechannel_inuse = FALSE; /* not in use yet */
#ifdef DEBUGBUILD
infof(conn->data, "%p is at send pipe head!\n",
conn->send_pipe->head->ptr);
(void *)conn->send_pipe->head->ptr);
#endif
Curl_expire(conn->send_pipe->head->ptr, 1);
}
@@ -144,7 +146,7 @@ void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle,
conn->writechannel_inuse = FALSE; /* not used now */
#ifdef DEBUGBUILD
infof(conn->data, "%p is at send pipe head B!\n",
conn->send_pipe->head->ptr);
(void *)conn->send_pipe->head->ptr);
#endif
Curl_expire(conn->send_pipe->head->ptr, 1);
}
@@ -320,9 +322,9 @@ void print_pipeline(struct connectdata *conn)
curr = cb_ptr->conn_list->head;
while(curr) {
conn = curr->ptr;
infof(data, "- Conn %d (%p) send_pipe: %d, recv_pipe: %d\n",
infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
conn->connection_id,
conn,
(void *)conn,
conn->send_pipe->size,
conn->recv_pipe->size);
curr = curr->next;

View File

@@ -90,8 +90,6 @@
#include "memdebug.h"
/* Local API functions */
static CURLcode pop3_parse_url_path(struct connectdata *conn);
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
static CURLcode pop3_do(struct connectdata *conn, bool *done);
static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
@@ -103,6 +101,9 @@ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
static CURLcode pop3_setup_connection(struct connectdata *conn);
static CURLcode pop3_parse_url_options(struct connectdata *conn);
static CURLcode pop3_parse_url_path(struct connectdata *conn);
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
/*
* POP3 protocol handler.
@@ -216,10 +217,15 @@ static void pop3_to_pop3s(struct connectdata *conn)
#define pop3_to_pop3s(x) Curl_nop_stmt
#endif
/* Function that checks for an ending POP3 status code at the start of the
given string, but also detects the APOP timestamp from the server greeting
and various capabilities from the CAPA response including the supported
authentication types and allowed SASL mechanisms. */
/***********************************************************************
*
* pop3_endofresp()
*
* Checks for an ending POP3 status code at the start of the given string, but
* also detects the APOP timestamp from the server greeting and various
* capabilities from the CAPA response including the supported authentication
* types and allowed SASL mechanisms.
*/
static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
int *resp)
{
@@ -340,7 +346,12 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
return FALSE; /* Nothing for us */
}
/* This is the ONLY way to change POP3 state! */
/***********************************************************************
*
* state()
*
* This is the ONLY way to change POP3 state!
*/
static void state(struct connectdata *conn, pop3state newstate)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
@@ -371,13 +382,20 @@ static void state(struct connectdata *conn, pop3state newstate)
if(pop3c->state != newstate)
infof(conn->data, "POP3 %p state change from %s to %s\n",
pop3c, names[pop3c->state], names[newstate]);
(void *)pop3c, names[pop3c->state], names[newstate]);
#endif
pop3c->state = newstate;
}
static CURLcode pop3_state_capa(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_capa()
*
* Sends the CAPA command in order to obtain a list of server side supported
* capabilities.
*/
static CURLcode pop3_perform_capa(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
@@ -387,7 +405,7 @@ static CURLcode pop3_state_capa(struct connectdata *conn)
pop3c->tls_supported = FALSE; /* Clear the TLS capability */
/* Send the CAPA command */
result = Curl_pp_sendf(&pop3c->pp, "CAPA");
result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
if(!result)
state(conn, POP3_CAPA);
@@ -395,12 +413,18 @@ static CURLcode pop3_state_capa(struct connectdata *conn)
return result;
}
static CURLcode pop3_state_starttls(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_starttls()
*
* Sends the STLS command to start the upgrade to TLS.
*/
static CURLcode pop3_perform_starttls(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
/* Send the STLS command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "STLS");
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
if(!result)
state(conn, POP3_STARTTLS);
@@ -408,7 +432,13 @@ static CURLcode pop3_state_starttls(struct connectdata *conn)
return result;
}
static CURLcode pop3_state_upgrade_tls(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_upgrade_tls()
*
* Performs the upgrade to TLS.
*/
static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
@@ -422,14 +452,20 @@ static CURLcode pop3_state_upgrade_tls(struct connectdata *conn)
if(pop3c->ssldone) {
pop3_to_pop3s(conn);
result = pop3_state_capa(conn);
result = pop3_perform_capa(conn);
}
}
return result;
}
static CURLcode pop3_state_user(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_user()
*
* Sends a clear text USER command to authenticate with.
*/
static CURLcode pop3_perform_user(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
@@ -451,7 +487,13 @@ static CURLcode pop3_state_user(struct connectdata *conn)
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
static CURLcode pop3_state_apop(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_apop()
*
* Sends an APOP command to authenticate with.
*/
static CURLcode pop3_perform_apop(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
@@ -495,12 +537,26 @@ static CURLcode pop3_state_apop(struct connectdata *conn)
}
#endif
static CURLcode pop3_authenticate(struct connectdata *conn)
/***********************************************************************
*
* pop3_perform_authenticate()
*
* Sends an AUTH command allowing the client to login with the appropriate
* SASL authentication mechanism.
*
* Additionally, the function will perform fallback to APOP and USER commands
* should a common mechanism not be available between the client and server.
*/
static CURLcode pop3_perform_authenticate(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *mech = NULL;
pop3state authstate = POP3_STOP;
char *initresp = NULL;
size_t len = 0;
pop3state state1 = POP3_STOP;
pop3state state2 = POP3_STOP;
/* Check we have a username and password to authenticate with and end the
connect phase if we don't */
@@ -514,62 +570,158 @@ static CURLcode pop3_authenticate(struct connectdata *conn)
security */
if(pop3c->authtypes & POP3_TYPE_SASL) {
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(pop3c->authmechs & SASL_MECH_DIGEST_MD5) {
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
(pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
mech = "DIGEST-MD5";
authstate = POP3_AUTH_DIGESTMD5;
state1 = POP3_AUTH_DIGESTMD5;
pop3c->authused = SASL_MECH_DIGEST_MD5;
}
else if(pop3c->authmechs & SASL_MECH_CRAM_MD5) {
else if((pop3c->authmechs & SASL_MECH_CRAM_MD5) &&
(pop3c->prefmech & SASL_MECH_CRAM_MD5)) {
mech = "CRAM-MD5";
authstate = POP3_AUTH_CRAMMD5;
state1 = POP3_AUTH_CRAMMD5;
pop3c->authused = SASL_MECH_CRAM_MD5;
}
else
#endif
#ifdef USE_NTLM
if(pop3c->authmechs & SASL_MECH_NTLM) {
if((pop3c->authmechs & SASL_MECH_NTLM) &&
(pop3c->prefmech & SASL_MECH_NTLM)) {
mech = "NTLM";
authstate = POP3_AUTH_NTLM;
state1 = POP3_AUTH_NTLM;
state2 = POP3_AUTH_NTLM_TYPE2MSG;
pop3c->authused = SASL_MECH_NTLM;
if(data->set.sasl_ir)
result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd,
&conn->ntlm,
&initresp, &len);
}
else
#endif
if(pop3c->authmechs & SASL_MECH_LOGIN) {
if((pop3c->authmechs & SASL_MECH_LOGIN) &&
(pop3c->prefmech & SASL_MECH_LOGIN)) {
mech = "LOGIN";
authstate = POP3_AUTH_LOGIN;
state1 = POP3_AUTH_LOGIN;
state2 = POP3_AUTH_LOGIN_PASSWD;
pop3c->authused = SASL_MECH_LOGIN;
if(data->set.sasl_ir)
result = Curl_sasl_create_login_message(conn->data, conn->user,
&initresp, &len);
}
else if(pop3c->authmechs & SASL_MECH_PLAIN) {
else if((pop3c->authmechs & SASL_MECH_PLAIN) &&
(pop3c->prefmech & SASL_MECH_PLAIN)) {
mech = "PLAIN";
authstate = POP3_AUTH_PLAIN;
state1 = POP3_AUTH_PLAIN;
state2 = POP3_AUTH_FINAL;
pop3c->authused = SASL_MECH_PLAIN;
if(data->set.sasl_ir)
result = Curl_sasl_create_plain_message(conn->data, conn->user,
conn->passwd, &initresp,
&len);
}
}
if(mech) {
/* Perform SASL based authentication */
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
if(!result) {
if(mech && (pop3c->preftype & POP3_TYPE_SASL)) {
/* Perform SASL based authentication */
if(initresp &&
8 + strlen(mech) + len <= 255) { /* AUTH <mech> ...<crlf> */
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
if(!result)
state(conn, authstate);
}
if(!result)
state(conn, state2);
}
else {
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
if(!result)
state(conn, state1);
}
Curl_safefree(initresp);
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
else if(pop3c->authtypes & POP3_TYPE_APOP)
/* Perform APOP authentication */
result = pop3_state_apop(conn);
else if((pop3c->authtypes & POP3_TYPE_APOP) &&
(pop3c->preftype & POP3_TYPE_APOP))
/* Perform APOP authentication */
result = pop3_perform_apop(conn);
#endif
else if(pop3c->authtypes & POP3_TYPE_CLEARTEXT)
/* Perform clear text authentication */
result = pop3_state_user(conn);
else {
/* Other mechanisms not supported */
infof(conn->data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
else if((pop3c->authtypes & POP3_TYPE_CLEARTEXT) &&
(pop3c->preftype & POP3_TYPE_CLEARTEXT))
/* Perform clear text authentication */
result = pop3_perform_user(conn);
else {
/* Other mechanisms not supported */
infof(conn->data, "No known authentication mechanisms supported!\n");
result = CURLE_LOGIN_DENIED;
}
}
return result;
}
/***********************************************************************
*
* pop3_perform_command()
*
* Sends a POP3 based command.
*/
static CURLcode pop3_perform_command(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *command = NULL;
/* Calculate the default command */
if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
command = "LIST";
if(pop3->id[0] != '\0')
/* Message specific LIST so skip the BODY transfer */
pop3->transfer = FTPTRANSFER_INFO;
}
else
command = "RETR";
/* Send the command */
if(pop3->id[0] != '\0')
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command), pop3->id);
else
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command));
if(!result)
state(conn, POP3_COMMAND);
return result;
}
/***********************************************************************
*
* pop3_perform_quit()
*
* Performs the quit action prior to sclose() be called.
*/
static CURLcode pop3_perform_quit(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
/* Send the QUIT command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
if(!result)
state(conn, POP3_QUIT);
return result;
}
/* For the initial server greeting */
static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
int pop3code,
@@ -582,10 +734,10 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
if(pop3code != '+') {
failf(data, "Got unexpected pop3-server response");
return CURLE_FTP_WEIRD_SERVER_REPLY;
result = CURLE_FTP_WEIRD_SERVER_REPLY;
}
result = pop3_state_capa(conn);
else
result = pop3_perform_capa(conn);
return result;
}
@@ -601,22 +753,22 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
(void)instate; /* no use for this yet */
if(pop3code != '+')
result = pop3_state_user(conn);
result = pop3_perform_user(conn);
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
/* We don't have a SSL/TLS connection yet, but SSL is requested */
if(pop3c->tls_supported)
/* Switch to TLS connection now */
result = pop3_state_starttls(conn);
result = pop3_perform_starttls(conn);
else if(data->set.use_ssl == CURLUSESSL_TRY)
/* Fallback and carry on with authentication */
result = pop3_authenticate(conn);
result = pop3_perform_authenticate(conn);
else {
failf(data, "STLS not supported.");
result = CURLE_USE_SSL_FAILED;
}
}
else
result = pop3_authenticate(conn);
result = pop3_perform_authenticate(conn);
return result;
}
@@ -637,15 +789,15 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
result = CURLE_USE_SSL_FAILED;
}
else
result = pop3_authenticate(conn);
result = pop3_perform_authenticate(conn);
}
else
result = pop3_state_upgrade_tls(conn);
result = pop3_perform_upgrade_tls(conn);
return result;
}
/* For AUTH PLAIN responses */
/* For AUTH PLAIN (without initial response) responses */
static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
@@ -682,7 +834,7 @@ static CURLcode pop3_state_auth_plain_resp(struct connectdata *conn,
return result;
}
/* For AUTH LOGIN responses */
/* For AUTH LOGIN (without initial response) responses */
static CURLcode pop3_state_auth_login_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
@@ -868,7 +1020,7 @@ static CURLcode pop3_state_auth_digest_resp_resp(struct connectdata *conn,
}
else {
/* Send an empty response */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "");
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "");
if(!result)
state(conn, POP3_AUTH_FINAL);
@@ -879,7 +1031,7 @@ static CURLcode pop3_state_auth_digest_resp_resp(struct connectdata *conn,
#endif
#ifdef USE_NTLM
/* For AUTH NTLM responses */
/* For AUTH NTLM (without initial response) responses */
static CURLcode pop3_state_auth_ntlm_resp(struct connectdata *conn,
int pop3code,
pop3state instate)
@@ -980,6 +1132,7 @@ static CURLcode pop3_state_auth_final_resp(struct connectdata *conn,
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
/* For APOP responses */
static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
pop3state instate)
{
@@ -1043,41 +1196,6 @@ static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
return result;
}
/* Start the DO phase for the command */
static CURLcode pop3_command(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *command = NULL;
/* Calculate the default command */
if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
command = "LIST";
if(pop3->id[0] != '\0')
/* Message specific LIST so skip the BODY transfer */
pop3->transfer = FTPTRANSFER_INFO;
}
else
command = "RETR";
/* Send the command */
if(pop3->id[0] != '\0')
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command), pop3->id);
else
result = Curl_pp_sendf(&conn->proto.pop3c.pp,
(pop3->custom && pop3->custom[0] != '\0' ?
pop3->custom : command));
if(!result)
state(conn, POP3_COMMAND);
return result;
}
/* For command responses */
static CURLcode pop3_state_command_resp(struct connectdata *conn,
int pop3code,
@@ -1146,7 +1264,7 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
/* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
if(pop3c->state == POP3_UPGRADETLS)
return pop3_state_upgrade_tls(conn);
return pop3_perform_upgrade_tls(conn);
/* Flush any data that needs to be sent */
if(pp->sendleft)
@@ -1303,8 +1421,7 @@ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
* connection phase.
*
* The variable 'done' points to will be TRUE if the protocol-layer connect
* phase is done when this function returns, or FALSE is not. When called as
* a part of the easy interface, it will always be TRUE.
* phase is done when this function returns, or FALSE if not.
*/
static CURLcode pop3_connect(struct connectdata *conn, bool *done)
{
@@ -1332,9 +1449,18 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
pp->endofresp = pop3_endofresp;
pp->conn = conn;
/* Set the default preferred authentication type and mechanism */
pop3c->preftype = POP3_TYPE_ANY;
pop3c->prefmech = SASL_AUTH_ANY;
/* Initialise the pingpong layer */
Curl_pp_init(pp);
/* Parse the URL options */
result = pop3_parse_url_options(conn);
if(result)
return result;
/* Start off waiting for the server greeting response */
state(conn, POP3_SERVERGREET);
@@ -1407,7 +1533,7 @@ static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
*dophase_done = FALSE; /* not done yet */
/* Start the first command in the DO phase */
result = pop3_command(conn);
result = pop3_perform_command(conn);
if(result)
return result;
@@ -1461,25 +1587,6 @@ static CURLcode pop3_do(struct connectdata *conn, bool *done)
return result;
}
/***********************************************************************
*
* pop3_quit()
*
* Performs the quit action prior to sclose() be called.
*/
static CURLcode pop3_quit(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
/* Send the QUIT command */
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "QUIT");
if(!result)
state(conn, POP3_QUIT);
return result;
}
/***********************************************************************
*
* pop3_disconnect()
@@ -1499,7 +1606,7 @@ static CURLcode pop3_disconnect(struct connectdata *conn,
/* The POP3 session may or may not have been allocated/setup at this
point! */
if(!dead_connection && pop3c->pp.conn)
if(!pop3_quit(conn))
if(!pop3_perform_quit(conn))
(void)pop3_block_statemach(conn); /* ignore errors on QUIT */
/* Disconnect from the server */
@@ -1514,37 +1621,6 @@ static CURLcode pop3_disconnect(struct connectdata *conn,
return CURLE_OK;
}
/***********************************************************************
*
* pop3_parse_url_path()
*
* Parse the URL path into separate path components.
*/
static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
/* The POP3 struct is already initialised in pop3_connect() */
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *path = data->state.path;
/* URL decode the path for the message ID */
return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
}
static CURLcode pop3_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
/* URL decode the custom request */
if(custom)
result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
return result;
}
/* Call this when the DO phase has completed */
static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
{
@@ -1639,8 +1715,116 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)
return CURLE_OK;
}
/* This function scans the body after the end-of-body and writes everything
until the end is found */
/***********************************************************************
*
* pop3_parse_url_options()
*
* Parse the URL login options.
*/
static CURLcode pop3_parse_url_options(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *options = conn->options;
const char *ptr = options;
if(options) {
const char *key = ptr;
while(*ptr && *ptr != '=')
ptr++;
if(strnequal(key, "AUTH", 4)) {
const char *value = ptr + 1;
if(strequal(value, "*")) {
pop3c->preftype = POP3_TYPE_ANY;
pop3c->prefmech = SASL_AUTH_ANY;
}
else if(strequal(value, "+APOP")) {
pop3c->preftype = POP3_TYPE_APOP;
pop3c->prefmech = SASL_AUTH_NONE;
}
else if(strequal(value, "LOGIN")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_LOGIN;
}
else if(strequal(value, "PLAIN")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_PLAIN;
}
else if(strequal(value, "CRAM-MD5")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_CRAM_MD5;
}
else if(strequal(value, "DIGEST-MD5")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_DIGEST_MD5;
}
else if(strequal(value, "GSSAPI")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_GSSAPI;
}
else if(strequal(value, "NTLM")) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->prefmech = SASL_MECH_NTLM;
}
else {
pop3c->preftype = POP3_TYPE_NONE;
pop3c->prefmech = SASL_AUTH_NONE;
}
}
else
result = CURLE_URL_MALFORMAT;
}
return result;
}
/***********************************************************************
*
* pop3_parse_url_path()
*
* Parse the URL path into separate path components.
*/
static CURLcode pop3_parse_url_path(struct connectdata *conn)
{
/* The POP3 struct is already initialised in pop3_connect() */
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *path = data->state.path;
/* URL decode the path for the message ID */
return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
}
/***********************************************************************
*
* pop3_parse_custom_request()
*
* Parse the custom request.
*/
static CURLcode pop3_parse_custom_request(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct POP3 *pop3 = data->state.proto.pop3;
const char *custom = data->set.str[STRING_CUSTOMREQUEST];
/* URL decode the custom request */
if(custom)
result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
return result;
}
/***********************************************************************
*
* Curl_pop3_write()
*
* This function scans the body after the end-of-body and writes everything
* until the end is found.
*/
CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
{
/* This code could be made into a special function in the handler struct */

View File

@@ -72,8 +72,10 @@ struct pop3_conn {
have been received so far */
size_t strip; /* Number of bytes from the start to ignore as
non-body */
unsigned int authtypes; /* Supported authentication types */
unsigned int authtypes; /* Accepted authentication types */
unsigned int authmechs; /* Accepted SASL authentication mechanisms */
unsigned int preftype; /* Preferred authentication type */
unsigned int prefmech; /* Preferred SASL authentication mechanism */
unsigned int authused; /* SASL auth mechanism used for the connection */
char *apoptimestamp; /* APOP timestamp from the server greeting */
bool tls_supported; /* StartTLS capability supported by server */
@@ -83,9 +85,13 @@ extern const struct Curl_handler Curl_handler_pop3;
extern const struct Curl_handler Curl_handler_pop3s;
/* Authentication type flags */
#define POP3_TYPE_CLEARTEXT 0x0001
#define POP3_TYPE_APOP 0x0002
#define POP3_TYPE_SASL 0x0004
#define POP3_TYPE_CLEARTEXT (1 << 0)
#define POP3_TYPE_APOP (1 << 1)
#define POP3_TYPE_SASL (1 << 2)
/* Authentication type values */
#define POP3_TYPE_NONE 0
#define POP3_TYPE_ANY ~0
/* This is the 5-bytes End-Of-Body marker for POP3 */
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2012, 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
@@ -357,12 +357,21 @@ int Curl_pgrsUpdate(struct connectdata *conn)
} /* Calculations end */
if(!(data->progress.flags & PGRS_HIDE)) {
/* progress meter has not been shut off */
if(data->set.fprogress) {
/* There's a callback set, so we call that instead of writing
anything ourselves. This really is the way to go. */
if(data->set.fxferinfo) {
/* There's a callback set, call that */
result= data->set.fxferinfo(data->set.progress_client,
data->progress.size_dl,
data->progress.downloaded,
data->progress.size_ul,
data->progress.uploaded);
if(result)
failf(data, "Callback aborted");
return result;
}
else if(data->set.fprogress) {
/* The older deprecated callback is set, call that */
result= data->set.fprogress(data->set.progress_client,
(double)data->progress.size_dl,
(double)data->progress.downloaded,

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, 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
@@ -37,6 +37,7 @@
#include "sslgen.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "x509asn1.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
@@ -169,10 +170,7 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
SSLHandle * h = connssl->handle;
long timeout_ms;
h->exitPgm = NULL;
if(!data->set.ssl.verifyhost)
h->exitPgm = Curl_qsossl_trap_cert;
h->exitPgm = data->set.ssl.verifypeer? NULL: Curl_qsossl_trap_cert;
/* figure out how long time we should wait at maximum */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
@@ -208,6 +206,8 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
break;
}
h->peerCert = NULL;
h->peerCertLen = 0;
rc = SSL_Handshake(h, SSL_HANDSHAKE_AS_CLIENT);
switch (rc) {
@@ -238,6 +238,23 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
return CURLE_SSL_CONNECT_ERROR;
}
/* Verify host. */
rc = Curl_verifyhost(conn, h->peerCert, h->peerCert + h->peerCertLen);
if(rc != CURLE_OK)
return rc;
/* Gather certificate info. */
if(data->set.ssl.certinfo) {
if(Curl_ssl_init_certinfo(data, 1))
return CURLE_OUT_OF_MEMORY;
if(h->peerCert) {
rc = Curl_extract_certinfo(conn, 0, h->peerCert,
h->peerCert + h->peerCertLen);
if(rc != CURLE_OK)
return rc;
}
}
return CURLE_OK;
}
@@ -257,19 +274,22 @@ CURLcode Curl_qsossl_connect(struct connectdata * conn, int sockindex)
if(rc == CURLE_OK) {
rc = Curl_qsossl_create(conn, sockindex);
if(rc == CURLE_OK)
if(rc == CURLE_OK) {
rc = Curl_qsossl_handshake(conn, sockindex);
else {
SSL_Destroy(connssl->handle);
connssl->handle = NULL;
connssl->use = FALSE;
connssl->state = ssl_connection_none;
if(rc != CURLE_OK)
SSL_Destroy(connssl->handle);
}
}
if(rc == CURLE_OK) {
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = qsossl_recv;
conn->send[sockindex] = qsossl_send;
connssl->state = ssl_connection_complete;
}
else {
connssl->handle = NULL;
connssl->use = FALSE;
connssl->state = ssl_connection_none;
}
return rc;

View File

@@ -668,7 +668,7 @@ static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data,
}
if(rtp_dataleft != 0 && rtp[0] == '$') {
DEBUGF(infof(data, "RTP Rewinding %zu %s\n", rtp_dataleft,
DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
*readmore ? "(READMORE)" : ""));
/* Store the incomplete RTP packet for a "rewind" */

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