Compare commits
252 Commits
curl-7_21_
...
curl-7_22_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
64c613c27a | ||
![]() |
73b18a9d24 | ||
![]() |
1bac153ea3 | ||
![]() |
432044b774 | ||
![]() |
9dfd7a3d13 | ||
![]() |
deb3321092 | ||
![]() |
68253ca52e | ||
![]() |
50c3c20416 | ||
![]() |
4e9a1c5bba | ||
![]() |
587ed3234b | ||
![]() |
94d64f8d4c | ||
![]() |
0d3584c482 | ||
![]() |
2a9fec16cc | ||
![]() |
777f9aea13 | ||
![]() |
72c14bd6f0 | ||
![]() |
0413e24891 | ||
![]() |
be8e68494c | ||
![]() |
a7d8894291 | ||
![]() |
08a5a9b68d | ||
![]() |
303c90074d | ||
![]() |
443ab77e1f | ||
![]() |
7b7c45879e | ||
![]() |
81ead2c4e7 | ||
![]() |
28d09cb0f5 | ||
![]() |
2147492050 | ||
![]() |
58a7c51362 | ||
![]() |
450975b0c3 | ||
![]() |
5658aa9574 | ||
![]() |
6539047694 | ||
![]() |
774ad4e31d | ||
![]() |
f764da8afb | ||
![]() |
c8ba8740b9 | ||
![]() |
46df51a391 | ||
![]() |
e9e894905c | ||
![]() |
a50210710a | ||
![]() |
eb44ac0138 | ||
![]() |
d52f3eb598 | ||
![]() |
8e154225b5 | ||
![]() |
196e0d699f | ||
![]() |
809cde5416 | ||
![]() |
476f194d7f | ||
![]() |
bdc311cf98 | ||
![]() |
a405a8976d | ||
![]() |
6b75d2c2df | ||
![]() |
2be65bb0c5 | ||
![]() |
f02325ea65 | ||
![]() |
b98594c8bf | ||
![]() |
ded3638d97 | ||
![]() |
9194e17003 | ||
![]() |
749dbfbc87 | ||
![]() |
6b59bc1805 | ||
![]() |
0a5bbb2ac1 | ||
![]() |
f2285a6d39 | ||
![]() |
fdf157abdf | ||
![]() |
437848d754 | ||
![]() |
38fff918f9 | ||
![]() |
5ea65fbc79 | ||
![]() |
0b018a0a05 | ||
![]() |
d20408e816 | ||
![]() |
c06de20025 | ||
![]() |
e495f82f86 | ||
![]() |
3445fa2e3f | ||
![]() |
5a45dc4a29 | ||
![]() |
78199b6030 | ||
![]() |
05ef245170 | ||
![]() |
662c1d87f3 | ||
![]() |
135f694058 | ||
![]() |
260ee6b7bf | ||
![]() |
b976d108f1 | ||
![]() |
b4f6319cf7 | ||
![]() |
e18c3f447e | ||
![]() |
0fd2bf3726 | ||
![]() |
407e08baad | ||
![]() |
186463e7fa | ||
![]() |
d535cff775 | ||
![]() |
f5ad192d23 | ||
![]() |
e83421baf4 | ||
![]() |
aa5c72af15 | ||
![]() |
b9c63b9a73 | ||
![]() |
cb5e72bf62 | ||
![]() |
e882416e75 | ||
![]() |
fd00b382b2 | ||
![]() |
cce6508242 | ||
![]() |
af809923e4 | ||
![]() |
006b011cdf | ||
![]() |
a659cc4794 | ||
![]() |
1c400b4e5e | ||
![]() |
61ae7e9ce7 | ||
![]() |
838dd8f594 | ||
![]() |
aaab5fa299 | ||
![]() |
2d7c79af76 | ||
![]() |
38c5e81a67 | ||
![]() |
3af9ba166c | ||
![]() |
7b054a42aa | ||
![]() |
b998d95b4d | ||
![]() |
d44896508c | ||
![]() |
9afb343368 | ||
![]() |
1833984664 | ||
![]() |
31a1af5ebb | ||
![]() |
9710f387c4 | ||
![]() |
4ed7abb537 | ||
![]() |
ef2059a44c | ||
![]() |
93ba8b9560 | ||
![]() |
ade87b32c7 | ||
![]() |
d6f319fb64 | ||
![]() |
b9d5e72adc | ||
![]() |
6a7ce5cc76 | ||
![]() |
7d738baeb5 | ||
![]() |
44b44a751d | ||
![]() |
2828b8ef9e | ||
![]() |
e575cbc815 | ||
![]() |
f0c59c6c2c | ||
![]() |
dfb18da5dc | ||
![]() |
0c4ec8033b | ||
![]() |
dc4f9d185d | ||
![]() |
98fb0ef73e | ||
![]() |
08b05efd20 | ||
![]() |
b4d6db83de | ||
![]() |
e209f3f176 | ||
![]() |
a30ede868a | ||
![]() |
40afeea2fb | ||
![]() |
e40c663d36 | ||
![]() |
c8766ed3fb | ||
![]() |
1e4187f8bf | ||
![]() |
8bd877d179 | ||
![]() |
5538904d77 | ||
![]() |
a472ceb174 | ||
![]() |
092189c664 | ||
![]() |
301e907aed | ||
![]() |
3293150da2 | ||
![]() |
784971743d | ||
![]() |
448f982d54 | ||
![]() |
f396d94736 | ||
![]() |
657d02fbac | ||
![]() |
8e2de86723 | ||
![]() |
4b48adb876 | ||
![]() |
c7fb556f26 | ||
![]() |
5ed17de326 | ||
![]() |
209cf2df37 | ||
![]() |
7c21c1c4f9 | ||
![]() |
f8831d55e0 | ||
![]() |
43d2c66454 | ||
![]() |
27dbc3f526 | ||
![]() |
9f10dabc43 | ||
![]() |
45d883d88d | ||
![]() |
3ef6418b61 | ||
![]() |
56ef3e295f | ||
![]() |
3dcc0df5cc | ||
![]() |
da3ae20da5 | ||
![]() |
73548e1d22 | ||
![]() |
56a0635216 | ||
![]() |
967deb43f8 | ||
![]() |
3d919440c8 | ||
![]() |
339fef4440 | ||
![]() |
15379f0614 | ||
![]() |
f2a6373629 | ||
![]() |
2ccffbb37e | ||
![]() |
1db023d3cb | ||
![]() |
91ad42412f | ||
![]() |
7d69e31023 | ||
![]() |
704dc18440 | ||
![]() |
b0f18c4beb | ||
![]() |
40e1d03c5d | ||
![]() |
c95fec5e5b | ||
![]() |
817b863466 | ||
![]() |
f6272dd9b8 | ||
![]() |
40597fd942 | ||
![]() |
f0fae85acd | ||
![]() |
e1f3536bac | ||
![]() |
afe88d85f4 | ||
![]() |
17f343290c | ||
![]() |
75fa3d2d6e | ||
![]() |
9812446c65 | ||
![]() |
5eb2396cd1 | ||
![]() |
86b50a1fe5 | ||
![]() |
8f890470f1 | ||
![]() |
a6ed2b8426 | ||
![]() |
b56bbabee0 | ||
![]() |
a04912bb65 | ||
![]() |
519d0c0dd2 | ||
![]() |
d2c22411af | ||
![]() |
c4142034ff | ||
![]() |
efc8ef7cc4 | ||
![]() |
b698f90051 | ||
![]() |
ddf0b30ffd | ||
![]() |
a7864c41db | ||
![]() |
ebf42c4be7 | ||
![]() |
7688a99bef | ||
![]() |
10a0bed485 | ||
![]() |
cc3e01cfae | ||
![]() |
65cc163195 | ||
![]() |
9417e71f4a | ||
![]() |
bc6e6a465a | ||
![]() |
ad8193fbb9 | ||
![]() |
bcbac913d6 | ||
![]() |
5cdbfa1837 | ||
![]() |
c01c000b16 | ||
![]() |
35051d274f | ||
![]() |
9779553221 | ||
![]() |
435e2bc757 | ||
![]() |
99848d3dab | ||
![]() |
02e59579ef | ||
![]() |
dddf9aa610 | ||
![]() |
4eb08ac1c0 | ||
![]() |
6ac4eeab2f | ||
![]() |
8350fb8f2f | ||
![]() |
cfcca89b76 | ||
![]() |
41c6c78a08 | ||
![]() |
78bbd0eecf | ||
![]() |
f1586cb477 | ||
![]() |
983f3d70f9 | ||
![]() |
0337b87197 | ||
![]() |
0a26b0e3e7 | ||
![]() |
ef2176109f | ||
![]() |
27b8814017 | ||
![]() |
dcc8481a13 | ||
![]() |
3f9b4afdfd | ||
![]() |
d007c3ca76 | ||
![]() |
0ae15092d4 | ||
![]() |
b9313af838 | ||
![]() |
d0d36f312f | ||
![]() |
d95f45cd40 | ||
![]() |
177fd0a14c | ||
![]() |
aa26c2751a | ||
![]() |
a6d4807d02 | ||
![]() |
650a504b2f | ||
![]() |
e3a9804d3a | ||
![]() |
9c1f50c583 | ||
![]() |
6e3285d5b1 | ||
![]() |
44b5847237 | ||
![]() |
ee4ed46128 | ||
![]() |
2af0287856 | ||
![]() |
20485a4885 | ||
![]() |
6488e03f44 | ||
![]() |
b680fd180b | ||
![]() |
dc97475ded | ||
![]() |
c6e3081090 | ||
![]() |
902d3dc33d | ||
![]() |
c7a4df16e0 | ||
![]() |
bcf50283fc | ||
![]() |
3e16c3e73e | ||
![]() |
3e71ebe4eb | ||
![]() |
bfca0e2f50 | ||
![]() |
2e2e5f247a | ||
![]() |
ac28971aa6 | ||
![]() |
fb48e2050b | ||
![]() |
78480892cd | ||
![]() |
17a2d70dc4 | ||
![]() |
43ce5580a8 | ||
![]() |
0215f7cb4d | ||
![]() |
67f28662e1 | ||
![]() |
57d51be60c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@ Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
|
@@ -148,7 +148,9 @@ option(ENABLE_IPV6 "Define if you want to enable IPv6 support" OFF)
|
||||
mark_as_advanced(ENABLE_IPV6)
|
||||
|
||||
if(WIN32)
|
||||
list_spaces_append_once(CMAKE_C_STANDARD_LIBRARIES wsock32.lib ws2_32.lib) # bufferoverflowu.lib
|
||||
find_library(WSOCK32_LIBRARY wsock32)
|
||||
find_library(WS2_32_LIBRARY ws2_32)
|
||||
list_spaces_append_once(CMAKE_C_STANDARD_LIBRARIES ${WSOCK32_LIBRARY} ${WS2_32_LIBRARY}) # bufferoverflowu.lib
|
||||
if(CURL_DISABLE_LDAP)
|
||||
# Remove wldap32.lib from space-separated list
|
||||
string(REPLACE " " ";" _LIST ${CMAKE_C_STANDARD_LIBRARIES})
|
||||
@@ -861,4 +863,3 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
|
||||
DESTINATION include
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN "curlbuild.h" EXCLUDE)
|
||||
|
@@ -1,38 +1,59 @@
|
||||
Curl and libcurl 7.21.7
|
||||
Curl and libcurl 7.22.0
|
||||
|
||||
Public curl releases: 123
|
||||
Command line options: 144
|
||||
curl_easy_setopt() options: 186
|
||||
Public curl releases: 124
|
||||
Command line options: 149
|
||||
curl_easy_setopt() options: 192
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 868
|
||||
Contributors: 873
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o recognize the [protocol]:// prefix in proxy hosts where the protocol is one
|
||||
of socks4, socks4a, socks5 or socks5h.
|
||||
o Added CURLOPT_CLOSESOCKETFUNCTION and CURLOPT_CLOSESOCKETDATA
|
||||
o Added CURLOPT_GSSAPI_DELEGATION
|
||||
o Added support for NTLM delegation to Samba's winbind daemon helper ntlm_auth
|
||||
o Display notes from setup file in testcurl.pl
|
||||
o BSD-style lwIP TCP/IP stack experimental support on Windows
|
||||
o OpenSSL: Use SSL_MODE_RELEASE_BUFFERS if available
|
||||
o --delegation was added to set CURLOPT_GSSAPI_DELEGATION
|
||||
o nss: start with no database if the selected database is broken
|
||||
o telnet: allow programatic use on Windows
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o SECURITY ADVISORY: inappropriate GSSAPI delegation. Full details at
|
||||
http://curl.haxx.se/docs/adv_20110623.html
|
||||
o NTLM: work with unicode
|
||||
o fix connect with SOCKS proxy when using the multi interface
|
||||
o anyauthput.c: stdint.h must not be included unconditionally
|
||||
o CMake: improved build
|
||||
o SCP/SFTP enable non-blocking earlier
|
||||
o GnuTLS handshake: fix timeout
|
||||
o cyassl: build without filesystem
|
||||
o HTTPS over HTTP proxy using the multi interface
|
||||
o speedcheck: invalid timeout event on a reused handle
|
||||
o Force connection close for HTTP 200 OK when time condition matched
|
||||
o curl_formget: fix FILE * leak
|
||||
o configure: improved OpenSSL detection
|
||||
o Android build: support gingerbread
|
||||
o CURLFORM_STREAM: acknowledge CURLFORM_FILENAME
|
||||
o windows build: use correct MS CRT
|
||||
o pop3: remove extra space in LIST command
|
||||
o curl_getdate: detect some illegal dates better
|
||||
o when sending a request and an error is received before the (entire) request
|
||||
body is sent, stop sending the request and close the connection after
|
||||
having received the entire response. This is equally true if an Expect:
|
||||
100-continue header was used.
|
||||
o When using both -J and a single -O with multiple URLs, a missing init
|
||||
could cause a segfault
|
||||
o -J fixed for escaped quotes
|
||||
o -J fixed for file names with semicolons
|
||||
o progress: reset flags at transfer start to avoid wrong
|
||||
CURLINFO_CONTENT_LENGTH_DOWNLOAD
|
||||
o curl_gssapi: Guard files with HAVE_GSSAPI and rename private header
|
||||
o silence picky compilers: mark unused parameters
|
||||
o help output: more gnu like output
|
||||
o libtests: stop checking for CURLM_CALL_MULTI_PERFORM
|
||||
o setting a non-HTTP proxy with an environment variable or with CURLOPT_PROXY
|
||||
/ --proxy (without specifying CURLOPT_PROXYTYPE) would still make it do
|
||||
proxy-like HTTP requests
|
||||
o CURLFORM_BUFFER: insert filename as documented (regression)
|
||||
o SOCKS: fix the connect timeout
|
||||
o ftp_doing: bail out on error properly while multi interfacing
|
||||
o improved Content-Encoded decoding error message
|
||||
o asyn-thread: check for dotted addresses before thread starts
|
||||
o cmake: find winsock when building on windows
|
||||
o Curl_retry_request: check return code
|
||||
o cookies: handle 'secure=' as if it was 'secure'
|
||||
o tests: break busy loops in tests 502, 555, and 573
|
||||
o FTP: fix proxy connect race condition with multi interface and SOCKS proxy
|
||||
o RTSP: GET_PARAMETER requests have a body
|
||||
o fixed several memory leaks in OOM situations
|
||||
o bad expire(0) caused multi_socket API to hang
|
||||
o Avoid ftruncate() static define with mingw64
|
||||
o mk-ca-bundle.pl: ignore untrusted certs
|
||||
o builds with PolarSSL 1.0.0
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -41,9 +62,11 @@ 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:
|
||||
|
||||
Dan Fandrich, Guenter Knauf, Vsevolod Novikov, Zmey Petroff,
|
||||
Dagobert Michelsen, Jeff Pohlmeyer, Dmitri Shubin, Matteo Rocco,
|
||||
Aaron Orenstein, Yang Tse, Kamil Dudka, Amr Shahin, Josue Andrade Gomes,
|
||||
Ori Avtalion, Richard Silverman, Julien Chaffraix
|
||||
Paolo Piacentini, Steven Parkes, Adam Tkac, Ben Winslow, Dan Fandrich,
|
||||
Julien Chaffraix, Kamil Dudka, Mandy Wu, Michael Mueller, Patrick Monnerat,
|
||||
Yang Tse, Paul Howarth, Garrett Holmstrom, Peter Hjalmarsson, Herve Amblard,
|
||||
Christian Hagele, Richard Silverman, Henry Ludemann, Cristian Rodriguez,
|
||||
Steve Holme, Jim Hollinger, Pau Garcia i Quiles, Fabian Keil, Wu Yongzheng,
|
||||
Adriano Meirelles, Jeff Pohlmeyer
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
16
TODO-RELEASE
16
TODO-RELEASE
@@ -1,15 +1,11 @@
|
||||
To be addressed in 7.21.6
|
||||
To be addressed in 7.22.1
|
||||
=========================
|
||||
|
||||
284 - bug 3172608 "No re-authentication when HTTP connecton is closed"
|
||||
http://curl.haxx.se/bug/view.cgi?id=3172608
|
||||
Would be nice if someone could verify the suggested patch
|
||||
295 - "RTSP Authentication (#22)" https://github.com/bagder/curl/pull/22
|
||||
|
||||
285 - bug 3163118 "Allow programatic use of telnet on Windows"
|
||||
http://curl.haxx.se/bug/view.cgi?id=3163118
|
||||
Would appreciate a Windows developer to give it a look before we apply
|
||||
the suggested patch
|
||||
296 - "OOM leak in multi code" (by Dan Fandrich)
|
||||
|
||||
287 - bug 3215314 Post quote operation to rename fails in Windows
|
||||
300 - "Polling on stray socket on sequential transfers." Andrew S
|
||||
http://curl.haxx.se/mail/lib-2011-07/0053.html
|
||||
|
||||
289 -
|
||||
308 -
|
||||
|
@@ -27,6 +27,11 @@ if not exist include\curl\curlbuild.h.dist goto end_curlbuild_h
|
||||
copy /Y include\curl\curlbuild.h.dist include\curl\curlbuild.h
|
||||
:end_curlbuild_h
|
||||
|
||||
REM create src\config-win32.h
|
||||
if not exist lib\config-win32.h goto end_config_win32_h
|
||||
copy /Y lib\config-win32.h src\config-win32.h
|
||||
:end_config_win32_h
|
||||
|
||||
REM setup c-ares git tree
|
||||
if not exist ares\buildconf.bat goto end_c_ares
|
||||
cd ares
|
||||
|
31
configure.ac
31
configure.ac
@@ -314,6 +314,26 @@ if test "x$cross_compiling" != "xno" &&
|
||||
supports_unittests=no
|
||||
fi
|
||||
|
||||
# IRIX 6.5.24 gcc 3.3 autobuilds fail unittests library compilation due to
|
||||
# a problem related with OpenSSL headers and library versions not matching.
|
||||
# Disable unit tests while time to further investigate this is found.
|
||||
case $host in
|
||||
mips-sgi-irix6.5)
|
||||
if test "$compiler_id" = "GNU_C"; then
|
||||
supports_unittests=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# All AIX autobuilds fails unit tests linking against unittests library
|
||||
# due to unittests library being built with no symbols or members. Libtool ?
|
||||
# Disable unit tests while time to further investigate this is found.
|
||||
case $host_os in
|
||||
aix*)
|
||||
supports_unittests=no
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Build unit tests when option --enable-debug is given.
|
||||
if test "x$want_debug" = "xyes" &&
|
||||
test "x$supports_unittests" = "xyes"; then
|
||||
@@ -1330,7 +1350,7 @@ if test X"$OPT_SSL" != Xno; then
|
||||
dnl the user told us to look
|
||||
OPENSSL_PCDIR="$OPT_SSL/lib/pkgconfig"
|
||||
AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$OPENSSL_PCDIR"])
|
||||
if test -e "$OPENSSL_PCDIR/openssl.pc"; then
|
||||
if test -f "$OPENSSL_PCDIR/openssl.pc"; then
|
||||
PKGTEST="yes"
|
||||
fi
|
||||
|
||||
@@ -2419,6 +2439,7 @@ AC_CHECK_HEADERS(
|
||||
stdbool.h \
|
||||
arpa/tftp.h \
|
||||
sys/filio.h \
|
||||
sys/wait.h \
|
||||
setjmp.h,
|
||||
dnl to do if not found
|
||||
[],
|
||||
@@ -2564,6 +2585,7 @@ CURL_CHECK_FUNC_SIGINTERRUPT
|
||||
CURL_CHECK_FUNC_SIGNAL
|
||||
CURL_CHECK_FUNC_SIGSETJMP
|
||||
CURL_CHECK_FUNC_SOCKET
|
||||
CURL_CHECK_FUNC_SOCKETPAIR
|
||||
CURL_CHECK_FUNC_STRCASECMP
|
||||
CURL_CHECK_FUNC_STRCASESTR
|
||||
CURL_CHECK_FUNC_STRCMPI
|
||||
@@ -2794,6 +2816,10 @@ AC_HELP_STRING([--disable-crypto-auth],[Disable cryptographic authentication]),
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
CURL_CHECK_OPTION_NTLM_WB
|
||||
|
||||
CURL_CHECK_NTLM_WB
|
||||
|
||||
dnl ************************************************************
|
||||
dnl disable TLS-SRP authentication
|
||||
dnl
|
||||
@@ -2969,6 +2995,9 @@ if test "x$CURL_DISABLE_HTTP" != "x1"; then
|
||||
if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
|
||||
-o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM"
|
||||
if test "x$NTLM_WB_ENABLED" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM_WB"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "x$USE_TLS_SRP" = "x1"; then
|
||||
|
83
docs/BUGS
83
docs/BUGS
@@ -6,21 +6,34 @@
|
||||
|
||||
BUGS
|
||||
|
||||
1. Bugs
|
||||
1.1 There are still bugs
|
||||
1.2 Where to report
|
||||
1.3 What to report
|
||||
1.4 libcurl problems
|
||||
1.5 Who will fix the problems
|
||||
1.6 How to get a stack trace
|
||||
1.7 Bugs in libcurl bindings
|
||||
|
||||
==============================================================================
|
||||
|
||||
1.1 There are still bugs
|
||||
|
||||
Curl and libcurl have grown substantially since the beginning. At the time
|
||||
of writing (July 2007), there are about 47000 lines of source code, and by
|
||||
the time you read this it has probably grown even more.
|
||||
of writing (September 2011), there are about 66000 lines of source code, and
|
||||
by the time you read this it has probably grown even more.
|
||||
|
||||
Of course there are lots of bugs left. And lots of misfeatures.
|
||||
|
||||
To help us make curl the stable and solid product we want it to be, we need
|
||||
bug reports and bug fixes.
|
||||
|
||||
WHERE TO REPORT
|
||||
1.2 Where to report
|
||||
|
||||
If you can't fix a bug yourself and submit a fix for it, try to report an as
|
||||
detailed report as possible to a curl mailing list to allow one of us to
|
||||
have a go at a solution. You should also post your bug/problem at curl's bug
|
||||
tracking system over at
|
||||
have a go at a solution. You can optionally also post your bug/problem at
|
||||
curl's bug tracking system over at
|
||||
|
||||
http://sourceforge.net/bugs/?group_id=976
|
||||
|
||||
@@ -29,16 +42,18 @@ WHERE TO REPORT
|
||||
If you feel you need to ask around first, find a suitable mailing list and
|
||||
post there. The lists are available on http://curl.haxx.se/mail/
|
||||
|
||||
WHAT TO REPORT
|
||||
1.3 What to report
|
||||
|
||||
When reporting a bug, you should include all information that will help us
|
||||
understand what's wrong, what you expected to happen and how to repeat the
|
||||
bad behavior. You therefore need to tell us:
|
||||
|
||||
- your operating system's name and version number (uname -a under a unix
|
||||
is fine)
|
||||
- your operating system's name and version number
|
||||
|
||||
- what version of curl you're using (curl -V is fine)
|
||||
|
||||
- versions of the used libraries that libcurl is built to use
|
||||
|
||||
- what URL you were working with (if possible), at least which protocol
|
||||
|
||||
and anything and everything else you think matters. Tell us what you
|
||||
@@ -59,7 +74,48 @@ WHAT TO REPORT
|
||||
The address and how to subscribe to the mailing lists are detailed in the
|
||||
MANUAL file.
|
||||
|
||||
HOW TO GET A STACK TRACE
|
||||
1.4 libcurl problems
|
||||
|
||||
First, post all libcurl problems on the curl-library mailing list.
|
||||
|
||||
When you've written your own application with libcurl to perform transfers,
|
||||
it is even more important to be specific and detailed when reporting bugs.
|
||||
|
||||
Tell us the libcurl version and your operating system. Tell us the name and
|
||||
version of all relevant sub-components like for example the SSL library
|
||||
you're using and what name resolving your libcurl uses. If you use SFTP or
|
||||
SCP, the libssh2 version is relevant etc.
|
||||
|
||||
Showing us a real source code example repeating your problem is the best way
|
||||
to get our attention and it will greatly increase our chances to understand
|
||||
your problem and to work on a fix (if we agree it truly is a problem).
|
||||
|
||||
Lots of problems that appear to be libcurl problems are actually just abuses
|
||||
of the libcurl API or other malfunctions in your applications. It is adviced
|
||||
that you run your problematic program using a memory debug tool like
|
||||
valgrind or similar before you post memory-related or "crashing" problems to
|
||||
us.
|
||||
|
||||
1.5 Who will fix the problems
|
||||
|
||||
If the problems or bugs you describe are considered to be bugs, we want to
|
||||
have the problems fixed.
|
||||
|
||||
There are no developers in the curl project that are paid to work on bugs.
|
||||
All developers that take on reported bugs do this on a voluntary basis. We
|
||||
do it out of an ambition to keep curl and libcurl excellent products and out
|
||||
of pride.
|
||||
|
||||
But please do not assume that you can just lump over something to us and it
|
||||
will then magically be fixed after some given time. Most often we need
|
||||
feedback and help to understand what you've experienced and how to repeat a
|
||||
problem. Then we may only be able to assist YOU to debug the problem and to
|
||||
track down the proper fix.
|
||||
|
||||
We get reports from many people every month and each report can take a
|
||||
considerable amount of time to really go to the bottom with.
|
||||
|
||||
1.6 How to get a stack trace
|
||||
|
||||
First, you must make sure that you compile all sources with -g and that you
|
||||
don't 'strip' the final executable. Try to avoid optimizing the code as
|
||||
@@ -79,3 +135,12 @@ HOW TO GET A STACK TRACE
|
||||
crashed. Include the stack trace with your detailed bug report. It'll help a
|
||||
lot.
|
||||
|
||||
1.7 Bugs in libcurl bindings
|
||||
|
||||
There will of course pop up bugs in libcurl bindings. You should then
|
||||
primarily approach the team that works on that particular binding and see
|
||||
what you can do to help them fix the problem.
|
||||
|
||||
If you suspect that the problem exists in the underlying libcurl, then
|
||||
please convert your program over to plain C and follow the steps outlined
|
||||
above.
|
||||
|
28
docs/INSTALL
28
docs/INSTALL
@@ -467,6 +467,34 @@ Win32
|
||||
in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project.
|
||||
|
||||
|
||||
Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds
|
||||
--------------------------------------------------------------------
|
||||
|
||||
In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack
|
||||
it is necessary to make definition of preprocessor symbol USE_LWIPSOCK
|
||||
visible to libcurl and curl compilation processes. To set this definition
|
||||
you have the following alternatives:
|
||||
|
||||
- Modify lib/config-win32.h and src/config-win32.h
|
||||
- Modify lib/Makefile.vc6
|
||||
- Add definition to Project/Settings/C/C++/General/Preprocessor Definitions
|
||||
in the vc6libcurl.dsw/vc6libcurl.dsp Visual C++ 6 IDE project.
|
||||
|
||||
Once that libcurl has been built with BSD-style lwIP TCP/IP stack support,
|
||||
in order to use it with your program it is mandatory that your program
|
||||
includes lwIP header file <lwip/opt.h> (or another lwIP header that includes
|
||||
this) before including any libcurl header. Your program does not need the
|
||||
USE_LWIPSOCK preprocessor definition which is for libcurl internals only.
|
||||
|
||||
Compilation has been verified with lwIP 1.4.0 and contrib-1.4.0 from:
|
||||
|
||||
http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip
|
||||
http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip
|
||||
|
||||
This BSD-style lwIP TCP/IP stack support must be considered experimental
|
||||
given that it has been verified that lwIP 1.4.0 still needs some polish,
|
||||
and libcurl might yet need some additional adjustment, caveat emptor.
|
||||
|
||||
Important static libcurl usage note
|
||||
-----------------------------------
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
If you have contributed but are missing here, please let us know!
|
||||
|
||||
Aaron Oneal
|
||||
Aaron Orenstein
|
||||
Adam D. Moss
|
||||
Adam Light
|
||||
Adam Piggott
|
||||
@@ -151,6 +152,7 @@ Craig Markwardt
|
||||
Cris Bailiff
|
||||
Curt Bogmine
|
||||
Cyrill Osterwalder
|
||||
Dagobert Michelsen
|
||||
Damien Adant
|
||||
Dan Becker
|
||||
Dan C
|
||||
@@ -544,6 +546,7 @@ Matt Kraai
|
||||
Matt Veenstra
|
||||
Matt Witherspoon
|
||||
Matt Wixson
|
||||
Matteo Rocco
|
||||
Matthew Blain
|
||||
Matthew Clarke
|
||||
Matthias Bolte
|
||||
@@ -615,6 +618,7 @@ Ofer
|
||||
Olaf Stueben
|
||||
Olaf St<53>ben
|
||||
Oren Tirosh
|
||||
Ori Avtalion
|
||||
P R Schaffner
|
||||
Pascal Terjan
|
||||
Pasha Kuznetsov
|
||||
@@ -700,6 +704,7 @@ Richard Clayton
|
||||
Richard Cooper
|
||||
Richard Gorton
|
||||
Richard Prescott
|
||||
Richard Silverman
|
||||
Rick Jones
|
||||
Rick Richardson
|
||||
Rob Crittenden
|
||||
|
66
docs/TODO
66
docs/TODO
@@ -12,16 +12,15 @@
|
||||
All bugs documented in the KNOWN_BUGS document are subject for fixing!
|
||||
|
||||
1. libcurl
|
||||
1.1 Zero-copy interface
|
||||
1.2 More data sharing
|
||||
1.3 struct lifreq
|
||||
1.4 signal-based resolver timeouts
|
||||
1.5 get rid of PATH_MAX
|
||||
1.6 progress callback without doubles
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
2.2 Remove easy interface internally
|
||||
2.3 Avoid having to remove/readd handles
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
3. Documentation
|
||||
@@ -54,12 +53,10 @@
|
||||
7.5 Export session ids
|
||||
7.6 Provide callback for cert verification
|
||||
7.7 Support other SSL libraries
|
||||
7.8 Support SRP on the TLS layer
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
8. GnuTLS
|
||||
8.1 SSL engine stuff
|
||||
8.2 SRP
|
||||
8.3 check connection
|
||||
8.4 non-gcrypt
|
||||
|
||||
@@ -77,6 +74,7 @@
|
||||
11.6 url-specific options
|
||||
11.7 metalink support
|
||||
11.8 warning when setting an option
|
||||
11.9 IPv6 addresses with globbing
|
||||
|
||||
12. Build
|
||||
12.1 roffit
|
||||
@@ -100,17 +98,12 @@
|
||||
15.5 remove CURLOPT_FAILONERROR
|
||||
15.6 remove CURLOPT_DNS_USE_GLOBAL_CACHE
|
||||
15.7 remove progress meter from libcurl
|
||||
15.8 remove 'curl_httppost' from public
|
||||
|
||||
==============================================================================
|
||||
|
||||
1. libcurl
|
||||
|
||||
1.1 Zero-copy interface
|
||||
|
||||
Introduce another callback interface for upload/download that makes one less
|
||||
copy of data and thus a faster operation.
|
||||
[http://curl.haxx.se/dev/no_copy_callbacks.txt]
|
||||
|
||||
1.2 More data sharing
|
||||
|
||||
curl_share_* functions already exist and work, and they can be extended to
|
||||
@@ -144,6 +137,15 @@
|
||||
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.
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
2.1 More non-blocking
|
||||
@@ -170,23 +172,6 @@
|
||||
internally use and assume the multi interface. The select()-loop should use
|
||||
curl_multi_socket().
|
||||
|
||||
2.3 Avoid having to remove/readd handles
|
||||
|
||||
curl_multi_handle_control() - this can control the easy handle (while) added
|
||||
to a multi handle in various ways:
|
||||
|
||||
o RESTART, unconditionally restart this easy handle's transfer from the
|
||||
start, re-init the state
|
||||
|
||||
o RESTART_COMPLETED, restart this easy handle's transfer but only if the
|
||||
existing transfer has already completed and it is in a "finished state".
|
||||
|
||||
o STOP, just stop this transfer and consider it completed
|
||||
|
||||
o PAUSE?
|
||||
|
||||
o RESUME?
|
||||
|
||||
2.4 Fix HTTP Pipelining for PUT
|
||||
|
||||
HTTP Pipelining can be a way to greatly enhance performance for multiple
|
||||
@@ -334,12 +319,6 @@ to provide the data to send.
|
||||
Make curl's SSL layer capable of using other free SSL libraries. Such as
|
||||
MatrixSSL (http://www.matrixssl.org/).
|
||||
|
||||
7.8 Support SRP on the TLS layer
|
||||
|
||||
Peter Sylvester's patch for SRP on the TLS layer. Awaits OpenSSL support for
|
||||
this, no need to support this in libcurl before there's an OpenSSL release
|
||||
that does it.
|
||||
|
||||
7.9 improve configure --with-ssl
|
||||
|
||||
make the configure --with-ssl option first check for OpenSSL, then GnuTLS,
|
||||
@@ -351,11 +330,6 @@ to provide the data to send.
|
||||
|
||||
Is this even possible?
|
||||
|
||||
8.2 SRP
|
||||
|
||||
Work out a common method with Peter Sylvester's OpenSSL-patch for SRP on the
|
||||
TLS to provide name and password. GnuTLS already supports it...
|
||||
|
||||
8.3 check connection
|
||||
|
||||
Add a way to check if the connection seems to be alive, to correspond to the
|
||||
@@ -451,6 +425,13 @@ to provide the data to send.
|
||||
This can be useful to tell when support for a particular feature hasn't been
|
||||
compiled into the library.
|
||||
|
||||
11.9 IPv6 addresses with globbing
|
||||
|
||||
Currently the command line client needs to get url globbing disabled (with
|
||||
-g) for it to support IPv6 numerical addresses. This is a rather silly flaw
|
||||
that should be corrected. It probably involves a smarter detection of the
|
||||
'[' and ']' letters.
|
||||
|
||||
12. Build
|
||||
|
||||
12.1 roffit
|
||||
@@ -569,3 +550,12 @@ to provide the data to send.
|
||||
The progress callback should then be bumped as well to get proper 64bit
|
||||
variable types passed to it instead of doubles so that big files work
|
||||
correctly.
|
||||
|
||||
15.8 remove 'curl_httppost' from public
|
||||
|
||||
curl_formadd() was made to fill in a public struct, but the fact that the
|
||||
struct is public is never really used by application for their own advantage
|
||||
but instead often restricts how the form functions can or can't be modified.
|
||||
|
||||
Changing them to return a private handle will benefit the implementation and
|
||||
allow us much greater freedoms while still maintining a solid API and ABI.
|
||||
|
@@ -11,32 +11,25 @@ Version Numbers and Releases
|
||||
|
||||
The version numbering is always built up using the same system:
|
||||
|
||||
X.Y[.Z][-preN]
|
||||
X.Y[.Z]
|
||||
|
||||
Where
|
||||
X is main version number
|
||||
Y is release number
|
||||
Z is patch number
|
||||
N is pre-release number
|
||||
|
||||
One of these numbers will get bumped in each new release. The numbers to the
|
||||
right of a bumped number will be reset to zero. If Z is zero, it may not be
|
||||
included in the version number. The pre release number is only included in
|
||||
pre releases (they're never used in public, official, releases).
|
||||
included in the version number.
|
||||
|
||||
The main version number will get bumped when *really* big, world colliding
|
||||
changes are made. The release number is bumped when big changes are
|
||||
performed. The patch number is bumped when the changes are mere bugfixes and
|
||||
only minor feature changes. The pre-release is a counter, to identify which
|
||||
pre-release a certain release is.
|
||||
|
||||
When reaching the end of a pre-release period, the version without the
|
||||
pre-release part will be released as a public release.
|
||||
changes are made. The release number is bumped when changes are performed or
|
||||
things/features are added. The patch number is bumped when the changes are
|
||||
mere bugfixes.
|
||||
|
||||
It means that after release 1.2.3, we can release 2.0 if something really big
|
||||
has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs
|
||||
were fixed. Before 1.2.4 is released, we might release a 1.2.4-pre1 release
|
||||
for the brave people to try before the actual release.
|
||||
were fixed.
|
||||
|
||||
Bumping, as in increasing the number with 1, is unconditionally only
|
||||
affecting one of the numbers (except the ones to the right of it, that may be
|
||||
@@ -56,12 +49,12 @@ Version Numbers and Releases
|
||||
#define LIBCURL_VERSION_NUM 0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal. All three numbers are always represented using two digits. 1.2
|
||||
would appear as "0x010200" while version 9.11.7 appears as "0x090b07".
|
||||
hexadecimal. All three number fields are always represented using two digits
|
||||
(eight bits each). 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit hexadecimal number does not show pre-release number, and it is
|
||||
always a greater number in a more recent release. It makes comparisons with
|
||||
greater than and less than work.
|
||||
This 6-digit hexadecimal number is always a greater number in a more recent
|
||||
release. It makes comparisons with greater than and less than work.
|
||||
|
||||
This number is also available as three separate defines:
|
||||
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR and LIBCURL_VERSION_PATCH.
|
||||
|
74
docs/curl.1
74
docs/curl.1
@@ -194,7 +194,10 @@ no file will be written. The file will be written using the Netscape cookie
|
||||
file format. If you set the file name to a single dash, "-", the cookies will
|
||||
be written to stdout.
|
||||
|
||||
.B NOTE
|
||||
This command line option will activate the cookie engine that makes curl
|
||||
record and use cookies. Another way to activate it is to use the \fI-b,
|
||||
--cookie\fP option.
|
||||
|
||||
If the cookie jar can't be created or written to, the whole curl operation
|
||||
won't fail or even report an error clearly. Using -v will get a warning
|
||||
displayed, but that is the only visible feedback you get about this possibly
|
||||
@@ -320,6 +323,18 @@ URL-encode that data and pass it on in the POST. The name part gets an equal
|
||||
sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the
|
||||
name is expected to be URL-encoded already.
|
||||
.RE
|
||||
.IP "--delegation LEVEL"
|
||||
Set \fILEVEL\fP to tell the server what it is allowed to delegate when it
|
||||
comes to user credentials. Used with GSS/kerberos.
|
||||
.RS
|
||||
.IP "none"
|
||||
Don't allow any delegation.
|
||||
.IP "policy"
|
||||
Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos
|
||||
service ticket, which is a matter of realm policy.
|
||||
.IP "always"
|
||||
Unconditionally allow the server to delegate.
|
||||
.RE
|
||||
.IP "--digest"
|
||||
(HTTP) Enables HTTP Digest authentication. This is a authentication that
|
||||
prevents the password from being sent over the wire in clear text. Use this in
|
||||
@@ -1068,16 +1083,18 @@ file will not be read and used. See the \fI-K, --config\fP for details on the
|
||||
default config file search path.
|
||||
.IP "-Q, --quote <command>"
|
||||
(FTP/SFTP) Send an arbitrary command to the remote FTP or SFTP server. Quote
|
||||
commands are sent BEFORE the transfer takes place (just after the
|
||||
initial PWD command in an FTP transfer, to be exact). To make commands
|
||||
take place after a successful transfer, prefix them with a dash '-'.
|
||||
To make commands be sent after libcurl has changed the working directory,
|
||||
just before the transfer command(s), prefix the command with a '+' (this
|
||||
is only supported for FTP). You may specify any number of commands. If
|
||||
the server returns failure for one of the commands, the entire operation
|
||||
will be aborted. You must send syntactically correct FTP commands as
|
||||
RFC 959 defines to FTP servers, or one of the commands listed below to
|
||||
SFTP servers. This option can be used multiple times.
|
||||
commands are sent BEFORE the transfer takes place (just after the initial PWD
|
||||
command in an FTP transfer, to be exact). To make commands take place after a
|
||||
successful transfer, prefix them with a dash '-'. To make commands be sent
|
||||
after libcurl has changed the working directory, just before the transfer
|
||||
command(s), prefix the command with a '+' (this is only supported for
|
||||
FTP). You may specify any number of commands. If the server returns failure
|
||||
for one of the commands, the entire operation will be aborted. You must send
|
||||
syntactically correct FTP commands as RFC 959 defines to FTP servers, or one
|
||||
of the commands listed below to SFTP servers. This option can be used
|
||||
multiple times. When speaking to a FTP server, prefix the command with an
|
||||
asterisk (*) to make libcurl continue even if the command fails as by default
|
||||
curl will stop at first failure.
|
||||
|
||||
SFTP is a binary protocol. Unlike for FTP, libcurl interprets SFTP quote
|
||||
commands itself before sending them to the server. File names may be quoted
|
||||
@@ -1266,9 +1283,8 @@ the port number is not specified, it is assumed at port 1080. (Added in
|
||||
This option overrides any previous use of \fI-x, --proxy\fP, as they are
|
||||
mutually exclusive.
|
||||
|
||||
Since 7.21.7, this option is superfluous since you can specify a
|
||||
socks5-hostnamae proxy with \fI-x, --proxy\fP using a socks5h:// protocol
|
||||
prefix.
|
||||
Since 7.21.7, this option is superfluous since you can specify a socks5
|
||||
hostname proxy with \fI-x, --proxy\fP using a socks5h:// protocol prefix.
|
||||
|
||||
If this option is used several times, the last one will be used. (This option
|
||||
was previously wrongly documented and used as --socks without the number
|
||||
@@ -1656,22 +1672,39 @@ Default config file, see \fI-K, --config\fP for details.
|
||||
The environment variables can be specified in lower case or upper case. The
|
||||
lower case version has precedence. http_proxy is an exception as it is only
|
||||
available in lower case.
|
||||
|
||||
Using an environment variable to set the proxy has the same effect as using
|
||||
the \fI--proxy\fP option.
|
||||
|
||||
.IP "http_proxy [protocol://]<host>[:port]"
|
||||
Sets the proxy server to use for HTTP.
|
||||
.IP "HTTPS_PROXY [protocol://]<host>[:port]"
|
||||
Sets the proxy server to use for HTTPS.
|
||||
.IP "FTP_PROXY [protocol://]<host>[:port]"
|
||||
Sets the proxy server to use for FTP.
|
||||
.IP "[url-protocol]_PROXY [protocol://]<host>[:port]"
|
||||
Sets the proxy server to use for [url-protocol], where the protocol is a
|
||||
protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP,
|
||||
SMTP, LDAP etc.
|
||||
.IP "ALL_PROXY [protocol://]<host>[:port]"
|
||||
Sets the proxy server to use if no protocol-specific proxy is set.
|
||||
.IP "NO_PROXY <comma-separated list of hosts>"
|
||||
list of host names that shouldn't go through any proxy. If set to a asterisk
|
||||
\&'*' only, it matches all hosts.
|
||||
.SH "PROXY PROTOCOL PREFIXES"
|
||||
Since curl version 7.21.7, the proxy string may be specified with a
|
||||
protocol:// prefix to specify alternative proxy protocols.
|
||||
|
||||
Since 7.21.7, the proxy string may be specified with a protocol:// prefix to
|
||||
specify alternative proxy protocols. Use socks4://, socks4a:// or socks5:// to
|
||||
request the specific SOCKS version to be used. No protocol specified, http://
|
||||
and all others will be treated as HTTP proxies.
|
||||
If no protocol is specified in the proxy string or if the string doesn't match
|
||||
a supported one, the proxy will be treated as a HTTP proxy.
|
||||
|
||||
The supported proxy protocol prefixes are as follows:
|
||||
.IP "socks4://"
|
||||
Makes it the equivalent of \fI--socks4\fP
|
||||
.IP "socks4a://"
|
||||
Makes it the equivalent of \fI--socks4a\fP
|
||||
.IP "socks5://"
|
||||
Makes it the equivalent of \fI--socks5\fP
|
||||
.IP "socks5h://"
|
||||
Makes it the equivalent of \fI--socks5-hostname\fP
|
||||
.SH EXIT CODES
|
||||
There are a bunch of different error codes and their corresponding error
|
||||
messages that may appear during bad conditions. At the time of this writing,
|
||||
@@ -1852,4 +1885,3 @@ ftp://ftp.sunet.se/pub/www/utilities/curl/
|
||||
.SH "SEE ALSO"
|
||||
.BR ftp (1),
|
||||
.BR wget (1)
|
||||
|
||||
|
3
docs/examples/.gitignore
vendored
3
docs/examples/.gitignore
vendored
@@ -4,6 +4,7 @@ certinfo
|
||||
chkspeed
|
||||
cookie_interface
|
||||
debug
|
||||
externalsocket
|
||||
fileupload
|
||||
fopen
|
||||
ftp-wildcard
|
||||
@@ -25,6 +26,8 @@ multi-single
|
||||
persistant
|
||||
post-callback
|
||||
postit2
|
||||
resolve
|
||||
rtsp
|
||||
sendrecv
|
||||
sepheaders
|
||||
simple
|
||||
|
@@ -4,7 +4,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
https multi-app multi-debugcallback multi-double multi-post multi-single \
|
||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||
smtp-multi simplesmtp smtp-tls
|
||||
smtp-multi simplesmtp smtp-tls rtsp externalsocket resolve
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
|
@@ -22,8 +22,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
|
@@ -35,8 +35,6 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
#define URL_BASE "http://speedtest.your.domain/"
|
||||
#define URL_1M URL_BASE "file_1M.bin"
|
||||
|
@@ -13,8 +13,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h> /* new for v7 */
|
||||
#include <curl/easy.h> /* new for v7 */
|
||||
|
||||
GtkWidget *Bar;
|
||||
|
||||
|
128
docs/examples/externalsocket.c
Normal file
128
docs/examples/externalsocket.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/*
|
||||
* This is an example demonstrating how an application can pass in a custom
|
||||
* socket to libcurl to use. This example also handles the connect itself.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/socket.h> /* socket definitions */
|
||||
#include <sys/types.h> /* socket types */
|
||||
#include <arpa/inet.h> /* inet (3) funtions */
|
||||
#include <unistd.h> /* misc. UNIX functions */
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* The IP address and port number to connect to */
|
||||
#define IPADDR "127.0.0.1"
|
||||
#define PORTNUM 80
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
int written = fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return written;
|
||||
}
|
||||
|
||||
static curl_socket_t opensocket(void *clientp,
|
||||
curlsocktype purpose,
|
||||
struct curl_sockaddr *address)
|
||||
{
|
||||
curl_socket_t sockfd = *(curl_socket_t *)clientp;
|
||||
/* the actual externally set socket is passed in via the OPENSOCKETDATA
|
||||
option */
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static int sockopt_callback(void *clientp, curl_socket_t curlfd,
|
||||
curlsocktype purpose)
|
||||
{
|
||||
/* This return code was added in libcurl 7.21.5 */
|
||||
return CURL_SOCKOPT_ALREADY_CONNECTED;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct sockaddr_in servaddr; /* socket address structure */
|
||||
curl_socket_t sockfd;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* Note that libcurl will internally think that you connect to the host
|
||||
* and port that you specify in the URL option.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
|
||||
|
||||
/* Create the socket "manually" */
|
||||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
|
||||
fprintf(stderr, "ECHOCLNT: Error creating listening socket.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORTNUM);
|
||||
|
||||
if(inet_aton(IPADDR, &servaddr.sin_addr) <= 0 )
|
||||
return 2;
|
||||
|
||||
if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) ==
|
||||
-1) {
|
||||
close(sockfd);
|
||||
printf("client error: connect: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
/* call this function to get a socket */
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
|
||||
|
||||
/* call this function to set options for the socket */
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(res) {
|
||||
printf("libcurl error: %d\n", res);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -22,8 +22,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an FTP server.
|
||||
|
@@ -23,8 +23,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* This is an example showing how to check a single file's size and mtime
|
||||
|
@@ -22,8 +22,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
/*
|
||||
* Similar to ftpget.c but this also stores the received response-lines
|
||||
|
@@ -36,10 +36,10 @@ struct MemoryStruct {
|
||||
|
||||
|
||||
static size_t
|
||||
WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)data;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if (mem->memory == NULL) {
|
||||
@@ -48,7 +48,7 @@ WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memcpy(&(mem->memory[mem->size]), ptr, realsize);
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
|
@@ -37,8 +37,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
51
docs/examples/resolve.c
Normal file
51
docs/examples/resolve.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
struct curl_slist *host = NULL;
|
||||
|
||||
/* Each single name resolve string should be written using the format
|
||||
HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve,
|
||||
PORT is the port number of the service where libcurl wants to connect to
|
||||
the HOST and ADDRESS is the numerical IP address
|
||||
*/
|
||||
host = curl_slist_append(NULL, "example.com:80:127.0.0.1");
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_slist_free_all(host);
|
||||
|
||||
return (int)res;
|
||||
}
|
271
docs/examples/rtsp.c
Normal file
271
docs/examples/rtsp.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Jim Hollinger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Jim Hollinger nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined (WIN32)
|
||||
# include <conio.h> /* _getch() */
|
||||
#else
|
||||
# include <termios.h>
|
||||
# include <unistd.h>
|
||||
|
||||
static int _getch(void)
|
||||
{
|
||||
struct termios oldt, newt;
|
||||
int ch;
|
||||
tcgetattr( STDIN_FILENO, &oldt );
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~( ICANON | ECHO );
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &newt );
|
||||
ch = getchar();
|
||||
tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define VERSION_STR "V1.0"
|
||||
|
||||
/* error handling macros */
|
||||
#define my_curl_easy_setopt(A, B, C) \
|
||||
if ((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \
|
||||
fprintf(stderr, "curl_easy_setopt(%s, %s, %s) failed: %d\n", \
|
||||
#A, #B, #C, res);
|
||||
|
||||
#define my_curl_easy_perform(A) \
|
||||
if ((res = curl_easy_perform((A))) != CURLE_OK) \
|
||||
fprintf(stderr, "curl_easy_perform(%s) failed: %d\n", #A, res);
|
||||
|
||||
|
||||
/* send RTSP OPTIONS request */
|
||||
static void rtsp_options(CURL *curl, const char *uri)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: OPTIONS %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
|
||||
/* send RTSP DESCRIBE request and write sdp response to a file */
|
||||
static void rtsp_describe(CURL *curl, const char *uri,
|
||||
const char *sdp_filename)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
FILE *sdp_fp = fopen(sdp_filename, "wt");
|
||||
printf("\nRTSP: DESCRIBE %s\n", uri);
|
||||
if (sdp_fp == NULL) {
|
||||
fprintf(stderr, "Could not open '%s' for writing\n", sdp_filename);
|
||||
sdp_fp = stdout;
|
||||
}
|
||||
else {
|
||||
printf("Writing SDP to '%s'\n", sdp_filename);
|
||||
}
|
||||
my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, sdp_fp);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE);
|
||||
my_curl_easy_perform(curl);
|
||||
my_curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout);
|
||||
if (sdp_fp != stdout) {
|
||||
fclose(sdp_fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* send RTSP SETUP request */
|
||||
static void rtsp_setup(CURL *curl, const char *uri, const char *transport)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: SETUP %s\n", uri);
|
||||
printf(" TRANSPORT %s\n", transport);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_TRANSPORT, transport);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
|
||||
/* send RTSP PLAY request */
|
||||
static void rtsp_play(CURL *curl, const char *uri, const char *range)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: PLAY %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_STREAM_URI, uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RANGE, range);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
|
||||
/* send RTSP TEARDOWN request */
|
||||
static void rtsp_teardown(CURL *curl, const char *uri)
|
||||
{
|
||||
CURLcode res = CURLE_OK;
|
||||
printf("\nRTSP: TEARDOWN %s\n", uri);
|
||||
my_curl_easy_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN);
|
||||
my_curl_easy_perform(curl);
|
||||
}
|
||||
|
||||
|
||||
/* convert url into an sdp filename */
|
||||
static void get_sdp_filename(const char *url, char *sdp_filename)
|
||||
{
|
||||
const char *s = strrchr(url, '/');
|
||||
strcpy(sdp_filename, "video.sdp");
|
||||
if (s != NULL) {
|
||||
s++;
|
||||
if (s[0] != '\0') {
|
||||
sprintf(sdp_filename, "%s.sdp", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* scan sdp file for media control attribute */
|
||||
static void get_media_control_attribute(const char *sdp_filename,
|
||||
char *control)
|
||||
{
|
||||
int max_len = 256;
|
||||
char *s = malloc(max_len);
|
||||
FILE *sdp_fp = fopen(sdp_filename, "rt");
|
||||
control[0] = '\0';
|
||||
if (sdp_fp != NULL) {
|
||||
while (fgets(s, max_len - 2, sdp_fp) != NULL) {
|
||||
sscanf(s, " a = control: %s", control);
|
||||
}
|
||||
fclose(sdp_fp);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
||||
/* main app */
|
||||
int main(int argc, char * const argv[])
|
||||
{
|
||||
#if 1
|
||||
const char *transport = "RTP/AVP;unicast;client_port=1234-1235"; /* UDP */
|
||||
#else
|
||||
const char *transport = "RTP/AVP/TCP;unicast;client_port=1234-1235"; /* TCP */
|
||||
#endif
|
||||
const char *range = "0.000-";
|
||||
int rc = EXIT_SUCCESS;
|
||||
char *basename = NULL;
|
||||
|
||||
printf("\nRTSP request %s\n", VERSION_STR);
|
||||
printf(" Project web site: http://code.google.com/p/rtsprequest/\n");
|
||||
printf(" Requires cURL V7.20 or greater\n\n");
|
||||
|
||||
/* check command line */
|
||||
if ((argc != 2) && (argc != 3)) {
|
||||
basename = strrchr(argv[0], '/');
|
||||
if (basename == NULL) {
|
||||
basename = strrchr(argv[0], '\\');
|
||||
}
|
||||
if (basename == NULL) {
|
||||
basename = argv[0];
|
||||
} else {
|
||||
basename++;
|
||||
}
|
||||
printf("Usage: %s url [transport]\n", basename);
|
||||
printf(" url of video server\n");
|
||||
printf(" transport (optional) specifier for media stream protocol\n");
|
||||
printf(" default transport: %s\n", transport);
|
||||
printf("Example: %s rtsp://192.168.0.2/media/video1\n\n", basename);
|
||||
rc = EXIT_FAILURE;
|
||||
} else {
|
||||
const char *url = argv[1];
|
||||
char *uri = malloc(strlen(url) + 32);
|
||||
char *sdp_filename = malloc(strlen(url) + 32);
|
||||
char *control = malloc(strlen(url) + 32);
|
||||
CURLcode res;
|
||||
get_sdp_filename(url, sdp_filename);
|
||||
if (argc == 3) {
|
||||
transport = argv[2];
|
||||
}
|
||||
|
||||
/* initialize curl */
|
||||
res = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if (res == CURLE_OK) {
|
||||
curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
|
||||
CURL *curl;
|
||||
fprintf(stderr, " cURL V%s loaded\n", data->version);
|
||||
|
||||
/* initialize this curl session */
|
||||
curl = curl_easy_init();
|
||||
if (curl != NULL) {
|
||||
my_curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||
my_curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
my_curl_easy_setopt(curl, CURLOPT_WRITEHEADER, stdout);
|
||||
my_curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* request server options */
|
||||
sprintf(uri, "%s", url);
|
||||
rtsp_options(curl, uri);
|
||||
|
||||
/* request session description and write response to sdp file */
|
||||
rtsp_describe(curl, uri, sdp_filename);
|
||||
|
||||
/* get media control attribute from sdp file */
|
||||
get_media_control_attribute(sdp_filename, control);
|
||||
|
||||
/* setup media stream */
|
||||
sprintf(uri, "%s/%s", url, control);
|
||||
rtsp_setup(curl, uri, transport);
|
||||
|
||||
/* start playing media stream */
|
||||
sprintf(uri, "%s/", url);
|
||||
rtsp_play(curl, uri, range);
|
||||
printf("Playing video, press any key to stop ...");
|
||||
_getch();
|
||||
printf("\n");
|
||||
|
||||
/* teardown session */
|
||||
rtsp_teardown(curl, uri);
|
||||
|
||||
/* cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl = NULL;
|
||||
} else {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
}
|
||||
curl_global_cleanup();
|
||||
} else {
|
||||
fprintf(stderr, "curl_global_init(%s) failed: %d\n",
|
||||
"CURL_GLOBAL_ALL", res);
|
||||
}
|
||||
free(control);
|
||||
free(sdp_filename);
|
||||
free(uri);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
@@ -24,8 +24,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
|
@@ -22,9 +22,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h>
|
||||
#include <curl/easy.h>
|
||||
|
||||
|
||||
/* some requirements for this to work:
|
||||
1. set pCertFile to the file with the client certificate
|
||||
|
@@ -37,8 +37,6 @@
|
||||
#include <pthread.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/types.h> /* new for v7 */
|
||||
#include <curl/easy.h> /* new for v7 */
|
||||
|
||||
#define NUMT 4
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -37,8 +37,15 @@ This will effectively close all connections this handle has used and possibly
|
||||
has kept open until now. Don't call this function if you intend to transfer
|
||||
more files.
|
||||
|
||||
Any uses of the \fBhandle\fP after this function has been called are
|
||||
illegal. This kills the handle and all memory associated with it!
|
||||
Occasionally you may get your progress callback or header callback called from
|
||||
within \fIcurl_easy_cleanup(3)\fP (if previously set for the handle using
|
||||
\fIcurl_easy_setopt(3)\fP). Like if libcurl decides to shut down the
|
||||
connection and the protocol is of a kind that requires a command/response
|
||||
sequence before disconnect. Examples of such protocols are FTP, POP3 and IMAP.
|
||||
|
||||
Any uses of the \fBhandle\fP after this function has been called and have
|
||||
returned, are illegal. This kills the handle and all memory associated with
|
||||
it!
|
||||
|
||||
With libcurl versions prior to 7.17.: when you've called this, you can safely
|
||||
remove all the strings you've previously told libcurl to use, as it won't use
|
||||
|
@@ -91,7 +91,9 @@ SIGPIPE signals, which otherwise are sent by the system when trying to send
|
||||
data to a socket which is closed in the other end. libcurl makes an effort to
|
||||
never cause such SIGPIPEs to trigger, but some operating systems have no way
|
||||
to avoid them and even on those that have there are some corner cases when
|
||||
they may still happen, contrary to our desire.
|
||||
they may still happen, contrary to our desire. In addition, using
|
||||
\fICURLAUTH_NTLM_WB\fP authentication could cause a SIGCHLD signal to be
|
||||
raised.
|
||||
.IP CURLOPT_WILDCARDMATCH
|
||||
Set this option to 1 if you want to transfer multiple files according to a
|
||||
file name pattern. The pattern can be specified as part of the
|
||||
@@ -890,6 +892,20 @@ prevent the password from being eavesdropped.
|
||||
|
||||
You need to build libcurl with OpenSSL support for this option to work, or
|
||||
build libcurl on Windows.
|
||||
.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
|
||||
is specified at compile time but is typically /usr/bin/ntlm_auth
|
||||
(Added in 7.22.0)
|
||||
|
||||
Note that libcurl will fork when necessary to run the winbind application and
|
||||
kill it when complete, calling waitpid() to await its exit when done. On POSIX
|
||||
operating systems, killing the process will cause a SIGCHLD signal to be
|
||||
raised (regardless of whether \fICURLOPT_NOSIGNAL\fP is set), which must be
|
||||
handled intelligently by the application. In particular, the application must
|
||||
not unconditionally call wait() in its SIGCHLD signal handler to avoid being
|
||||
subject to a race condition. This behavior is subject to change in future
|
||||
versions of libcurl.
|
||||
.IP CURLAUTH_ANY
|
||||
This is a convenience macro that sets all bits and thus makes libcurl pick any
|
||||
it finds suitable. libcurl will automatically select the one it finds most
|
||||
@@ -1313,18 +1329,22 @@ Examples with specified ports:
|
||||
You disable PORT again and go back to using the passive version by setting
|
||||
this option to NULL.
|
||||
.IP CURLOPT_QUOTE
|
||||
Pass a pointer to a linked list of FTP or SFTP commands to pass to
|
||||
the server prior to your FTP request. This will be done before any
|
||||
other commands are issued (even before the CWD command for FTP). The
|
||||
linked list should be a fully valid list of 'struct curl_slist' structs
|
||||
properly filled in with text strings. Use \fIcurl_slist_append(3)\fP
|
||||
to append strings (commands) to the list, and clear the entire list
|
||||
afterwards with \fIcurl_slist_free_all(3)\fP. Disable this operation
|
||||
again by setting a NULL to this option.
|
||||
The set of valid FTP commands depends on the server (see RFC959 for a
|
||||
list of mandatory commands).
|
||||
The valid SFTP commands are: chgrp, chmod, chown, ln, mkdir, pwd,
|
||||
rename, rm, rmdir, symlink (see
|
||||
Pass a pointer to a linked list of FTP or SFTP commands to pass to the server
|
||||
prior to your FTP request. This will be done before any other commands are
|
||||
issued (even before the CWD command for FTP). The linked list should be a
|
||||
fully valid list of 'struct curl_slist' structs properly filled in with text
|
||||
strings. Use \fIcurl_slist_append(3)\fP to append strings (commands) to the
|
||||
list, and clear the entire list afterwards with
|
||||
\fIcurl_slist_free_all(3)\fP. Disable this operation again by setting a NULL
|
||||
to this option. When speaking to a FTP server, prefix the command with an
|
||||
asterisk (*) to make libcurl continue even if the command fails as by default
|
||||
libcurl will stop at first failure.
|
||||
|
||||
The set of valid FTP commands depends on the server (see RFC959 for a list of
|
||||
mandatory commands).
|
||||
|
||||
The valid SFTP commands are: chgrp, chmod, chown, ln, mkdir, pwd, rename, rm,
|
||||
rmdir, symlink (see
|
||||
.BR curl (1))
|
||||
(SFTP support added in 7.16.3)
|
||||
.IP CURLOPT_POSTQUOTE
|
||||
@@ -2105,6 +2125,14 @@ of these, 'private' will be used. Set the string to NULL to disable kerberos
|
||||
support for FTP.
|
||||
|
||||
(This option was known as CURLOPT_KRB4LEVEL up to 7.16.3)
|
||||
.IP CURLOPT_GSSAPI_DELEGATION
|
||||
Set the parameter to CURLGSSAPI_DELEGATION_FLAG to allow unconditional GSSAPI
|
||||
credential delegation. The delegation is disabled by default since 7.21.7.
|
||||
Set the parameter to CURLGSSAPI_DELEGATION_POLICY_FLAG to delegate only if
|
||||
the OK-AS-DELEGATE flag is set in the service ticket in case this feature is
|
||||
supported by the GSSAPI implementation and the definition of
|
||||
GSS_C_DELEG_POLICY_FLAG was available at compile-time.
|
||||
(Added in 7.22.0)
|
||||
.SH SSH OPTIONS
|
||||
.IP CURLOPT_SSH_AUTH_TYPES
|
||||
Pass a long set to a bitmask consisting of one or more of
|
||||
|
@@ -128,6 +128,11 @@ the app having to pass them on. (Added in 7.13.2)
|
||||
.IP CURL_VERSION_CONV
|
||||
libcurl was built with support for character conversions, as provided by the
|
||||
CURLOPT_CONV_* callbacks. (Added in 7.15.4)
|
||||
.IP CURL_VERSION_TLSAUTH_SRP
|
||||
libcurl was built with support for TLS-SRP. (Added in 7.21.4)
|
||||
.IP CURL_VERSION_NTLM_WB
|
||||
libcurl was built with support for NTLM delegation to a winbind helper.
|
||||
(Added in 7.22.0)
|
||||
.RE
|
||||
\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
|
||||
has no SSL support, this is NULL.
|
||||
|
@@ -20,6 +20,7 @@ CURLAUTH_DIGEST_IE 7.19.3
|
||||
CURLAUTH_GSSNEGOTIATE 7.10.6
|
||||
CURLAUTH_NONE 7.10.6
|
||||
CURLAUTH_NTLM 7.10.6
|
||||
CURLAUTH_NTLM_WB 7.22.0
|
||||
CURLAUTH_ONLY 7.21.3
|
||||
CURLCLOSEPOLICY_CALLBACK 7.7
|
||||
CURLCLOSEPOLICY_LEAST_RECENTLY_USED 7.7
|
||||
@@ -186,6 +187,9 @@ CURLFTPSSL_TRY 7.11.0 7.17.0
|
||||
CURLFTP_CREATE_DIR 7.19.4
|
||||
CURLFTP_CREATE_DIR_NONE 7.19.4
|
||||
CURLFTP_CREATE_DIR_RETRY 7.19.4
|
||||
CURLGSSAPI_DELEGATION_FLAG 7.22.0
|
||||
CURLGSSAPI_DELEGATION_NONE 7.22.0
|
||||
CURLGSSAPI_DELEGATION_POLICY_FLAG 7.22.0
|
||||
CURLINFO_APPCONNECT_TIME 7.19.0
|
||||
CURLINFO_CERTINFO 7.19.1
|
||||
CURLINFO_CONDITION_UNMET 7.19.4
|
||||
@@ -344,6 +348,7 @@ CURLOPT_FTP_SSL_CCC 7.16.1
|
||||
CURLOPT_FTP_USE_EPRT 7.10.5
|
||||
CURLOPT_FTP_USE_EPSV 7.9.2
|
||||
CURLOPT_FTP_USE_PRET 7.20.0
|
||||
CURLOPT_GSSAPI_DELEGATION 7.22.0
|
||||
CURLOPT_HEADER 7.1
|
||||
CURLOPT_HEADERDATA 7.10
|
||||
CURLOPT_HEADERFUNCTION 7.7.2
|
||||
@@ -675,6 +680,7 @@ CURL_VERSION_KERBEROS4 7.10
|
||||
CURL_VERSION_LARGEFILE 7.11.1
|
||||
CURL_VERSION_LIBZ 7.10
|
||||
CURL_VERSION_NTLM 7.10.6
|
||||
CURL_VERSION_NTLM_WB 7.22.0
|
||||
CURL_VERSION_SPNEGO 7.10.8
|
||||
CURL_VERSION_SSL 7.10
|
||||
CURL_VERSION_SSPI 7.13.2
|
||||
|
@@ -55,18 +55,17 @@
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \
|
||||
!defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H))
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
|
||||
#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || defined(__LWIP_OPT_H__))
|
||||
/* The check above prevents the winsock2 inclusion if winsock.h already was
|
||||
included, since they can't co-exist without problems */
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
|
||||
libc5-based Linux systems. Only include it on system that are known to
|
||||
libc5-based Linux systems. Only include it on systems that are known to
|
||||
require it! */
|
||||
#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
|
||||
defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
|
||||
@@ -75,14 +74,13 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#if !defined(WIN32) && !defined(_WIN32_WCE)
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
#include <support/SupportDefs.h>
|
||||
@@ -122,7 +120,7 @@ typedef void CURL;
|
||||
|
||||
#ifndef curl_socket_typedef
|
||||
/* socket typedef */
|
||||
#ifdef WIN32
|
||||
#if defined(WIN32) && !defined(__LWIP_OPT_H__)
|
||||
typedef SOCKET curl_socket_t;
|
||||
#define CURL_SOCKET_BAD INVALID_SOCKET
|
||||
#else
|
||||
@@ -600,6 +598,7 @@ typedef enum {
|
||||
#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */
|
||||
#define CURLAUTH_NTLM (1<<3) /* NTLM */
|
||||
#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */
|
||||
#define CURLAUTH_NTLM_WB (1<<5) /* NTLM delegating to winbind helper */
|
||||
#define CURLAUTH_ONLY (1<<31) /* used together with a single other
|
||||
type to force no auth or just that
|
||||
single type */
|
||||
@@ -614,6 +613,10 @@ typedef enum {
|
||||
#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */
|
||||
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
|
||||
|
||||
#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */
|
||||
#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
|
||||
#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */
|
||||
|
||||
#define CURL_ERROR_SIZE 256
|
||||
|
||||
struct curl_khkey {
|
||||
@@ -916,9 +919,7 @@ typedef enum {
|
||||
/* send linked-list of post-transfer QUOTE commands */
|
||||
CINIT(POSTQUOTE, OBJECTPOINT, 39),
|
||||
|
||||
/* Pass a pointer to string of the output using full variable-replacement
|
||||
as described elsewhere. */
|
||||
CINIT(WRITEINFO, OBJECTPOINT, 40),
|
||||
CINIT(WRITEINFO, OBJECTPOINT, 40), /* DEPRECATED, do not use! */
|
||||
|
||||
CINIT(VERBOSE, LONG, 41), /* talk a lot */
|
||||
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
||||
@@ -994,8 +995,7 @@ typedef enum {
|
||||
/* Max amount of cached alive connections */
|
||||
CINIT(MAXCONNECTS, LONG, 71),
|
||||
|
||||
/* 72 - DEPRECATED */
|
||||
CINIT(CLOSEPOLICY, LONG, 72),
|
||||
CINIT(CLOSEPOLICY, LONG, 72), /* DEPRECATED, do not use! */
|
||||
|
||||
/* 73 = OBSOLETE */
|
||||
|
||||
@@ -1069,7 +1069,7 @@ typedef enum {
|
||||
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
||||
|
||||
/* Non-zero value means to use the global dns cache */
|
||||
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */
|
||||
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
|
||||
|
||||
/* DNS cache timeout */
|
||||
CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
|
||||
@@ -1483,6 +1483,9 @@ typedef enum {
|
||||
CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
|
||||
CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
|
||||
|
||||
/* allow GSSAPI credential delegation */
|
||||
CINIT(GSSAPI_DELEGATION, LONG, 210),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -2092,8 +2095,9 @@ typedef struct {
|
||||
#define CURL_VERSION_CONV (1<<12) /* character conversions supported */
|
||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
|
||||
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
|
||||
|
||||
/*
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
*
|
||||
* DESCRIPTION
|
||||
|
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.21.7-DEV"
|
||||
#define LIBCURL_VERSION "7.22.0-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 21
|
||||
#define LIBCURL_VERSION_PATCH 7
|
||||
#define LIBCURL_VERSION_MINOR 22
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -53,7 +53,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x071507
|
||||
#define LIBCURL_VERSION_NUM 0x071600
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@@ -89,7 +89,7 @@ ZLIB_ROOT = ..$(DS)..$(DS)zlib-1.2.5
|
||||
!ifdef %libssh2_root
|
||||
LIBSSH2_ROOT = $(%libssh2_root)
|
||||
!else
|
||||
LIBSSH2_ROOT = ..$(DS)..$(DS)libssh2-1.2.8
|
||||
LIBSSH2_ROOT = ..$(DS)..$(DS)libssh2-1.3.0
|
||||
!endif
|
||||
|
||||
!ifdef %librtmp_root
|
||||
|
@@ -14,7 +14,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.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 \
|
||||
http_negotiate.c http_ntlm.c inet_pton.c strtoofft.c strerror.c \
|
||||
http_negotiate.c inet_pton.c strtoofft.c strerror.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 \
|
||||
qssl.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
@@ -22,7 +22,8 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c polarssl.c \
|
||||
curl_rtmp.c openldap.c curl_gethostname.c gopher.c axtls.c \
|
||||
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
|
||||
asyn-ares.c asyn-thread.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
|
||||
|
||||
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 \
|
||||
@@ -30,11 +31,12 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
getinfo.h strequal.h krb4.h memdebug.h http_chunks.h curl_rand.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 http_ntlm.h inet_pton.h \
|
||||
curl_md5.h http_digest.h http_negotiate.h inet_pton.h \
|
||||
strtoofft.h strerror.h inet_ntop.h curlx.h curl_memory.h setup.h \
|
||||
transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \
|
||||
tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \
|
||||
curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h \
|
||||
curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h \
|
||||
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
|
||||
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h
|
||||
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h curl_ntlm.h \
|
||||
curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h curl_ntlm_msgs.h
|
||||
|
@@ -24,7 +24,7 @@ OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.8
|
||||
LIBSSH2_PATH = ../../libssh2-1.3.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
@@ -50,8 +50,16 @@ ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = ../ares
|
||||
endif
|
||||
|
||||
# Edit the var below to set to your architecture or set environment var.
|
||||
ifndef ARCH
|
||||
ARCH = w32
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 -Wall
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -D_AMD64_
|
||||
endif
|
||||
# comment LDFLAGS below to keep debug info
|
||||
LDFLAGS = -s
|
||||
AR = ar
|
||||
@@ -95,6 +103,9 @@ endif
|
||||
ifeq ($(findstring -sspi,$(CFG)),-sspi)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ldaps,$(CFG)),-ldaps)
|
||||
LDAPS = 1
|
||||
endif
|
||||
@@ -138,15 +149,17 @@ ifdef IDN
|
||||
DLL_LIBS += -L$(LIBIDN_PATH)/lib -lidn
|
||||
else
|
||||
ifdef WINIDN
|
||||
INCLUDES += -I"$(WINIDN_PATH)/include"
|
||||
CFLAGS += -DHAVE_NORMALIZATION_H
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
CFLAGS += -DWANT_IDN_PROTOTYPES
|
||||
DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
endif
|
||||
|
@@ -24,7 +24,7 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.8
|
||||
LIBSSH2_PATH = ../../libssh2-1.3.0
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
@@ -95,7 +95,7 @@ else
|
||||
endif
|
||||
PERL = perl
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
CP = cp -afv
|
||||
MKDIR = mkdir
|
||||
@@ -498,6 +498,7 @@ endif
|
||||
@echo $(DL)#define USE_MANUAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
|
@@ -20,6 +20,11 @@
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# fiels and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC6
|
||||
@@ -59,13 +64,14 @@
|
||||
|
||||
!INCLUDE ..\Makefile.msvc.names
|
||||
|
||||
|
||||
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.5
|
||||
!ENDIF
|
||||
@@ -100,6 +106,7 @@ WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
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
|
||||
@@ -219,6 +226,36 @@ CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(LIBSSH2_PATH)/Release/src/libssh2.lib $(ZLIB_PATH)/zlib.lib
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(LIBSSH2_PATH)/Release/src/libssh2.lib $(ZLIB_PATH)/zlib.lib
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
@@ -418,6 +455,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
@@ -425,6 +463,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
@@ -467,6 +506,10 @@ X_OBJS= \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_ntlm.obj \
|
||||
$(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_sspi.obj \
|
||||
@@ -494,7 +537,6 @@ X_OBJS= \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_negotiate_sspi.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
|
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
@@ -39,16 +37,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
|
@@ -22,9 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -37,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(USE_THREADS_POSIX)
|
||||
@@ -421,7 +414,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
socket error string function can be used for this pupose. */
|
||||
static const char *gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode){
|
||||
switch (ecode) {
|
||||
case EAI_AGAIN:
|
||||
return "The name could not be resolved at this time";
|
||||
case EAI_BADFLAGS:
|
||||
@@ -633,14 +626,28 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
int *waitp)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct in_addr in;
|
||||
Curl_addrinfo *res;
|
||||
int error;
|
||||
char sbuf[NI_MAXSERV];
|
||||
int pf = PF_INET;
|
||||
#ifdef CURLRES_IPV6
|
||||
struct in6_addr in6;
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
*waitp = 0; /* default to synchronous response */
|
||||
|
||||
#ifndef CURLRES_IPV4
|
||||
/* First check if this is an IPv4 address string */
|
||||
if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
|
||||
/* This is a dotted IP address 123.123.123.123-style */
|
||||
return Curl_ip2addr(AF_INET, &in, hostname, port);
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/* check if this is an IPv6 address string */
|
||||
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
|
||||
/* This is an IPv6 address literal */
|
||||
return Curl_ip2addr(AF_INET6, &in6, hostname, port);
|
||||
|
||||
/*
|
||||
* Check if a limited name resolve has been requested.
|
||||
*/
|
||||
@@ -660,7 +667,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
/* the stack seems to be a non-ipv6 one */
|
||||
pf = PF_INET;
|
||||
|
||||
#endif /* !CURLRES_IPV4 */
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
|
@@ -146,15 +146,15 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
|
||||
#ifndef CURLRES_ASYNCH
|
||||
/* convert these functions if an asynch resolver isn't used */
|
||||
#define Curl_resolver_cancel(x)
|
||||
#define Curl_resolver_cancel(x) Curl_nop_stmt
|
||||
#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
|
||||
#define Curl_resolver_getsock(x,y,z) 0
|
||||
#define Curl_resolver_duphandle(x,y) CURLE_OK
|
||||
#define Curl_resolver_init(x) CURLE_OK
|
||||
#define Curl_resolver_global_init() CURLE_OK
|
||||
#define Curl_resolver_global_cleanup()
|
||||
#define Curl_resolver_cleanup(x)
|
||||
#define Curl_resolver_global_cleanup() Curl_nop_stmt
|
||||
#define Curl_resolver_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
|
38
lib/axtls.c
38
lib/axtls.c
@@ -27,13 +27,11 @@
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_AXTLS
|
||||
#include <axTLS/ssl.h>
|
||||
#include "axtls.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -58,7 +56,7 @@ static int SSL_read(SSL *ssl, void *buf, int num)
|
||||
|
||||
while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
|
||||
|
||||
if(ret > SSL_OK){
|
||||
if(ret > SSL_OK) {
|
||||
memcpy(buf, read_buf, ret > num ? num : ret);
|
||||
}
|
||||
|
||||
@@ -187,10 +185,10 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
/* 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)
|
||||
!= SSL_OK){
|
||||
!= SSL_OK) {
|
||||
infof(data, "error reading ca cert file %s \n",
|
||||
data->set.ssl.CAfile);
|
||||
if(data->set.ssl.verifypeer){
|
||||
if(data->set.ssl.verifypeer) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
@@ -208,13 +206,13 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
*/
|
||||
|
||||
/* Load client certificate */
|
||||
if(data->set.str[STRING_CERT]){
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
i=0;
|
||||
/* Instead of trying to analyze cert type here, let axTLS try them all. */
|
||||
while(cert_types[i] != 0){
|
||||
while(cert_types[i] != 0) {
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
|
||||
data->set.str[STRING_CERT], NULL);
|
||||
if(ssl_fcn_return == SSL_OK){
|
||||
if(ssl_fcn_return == SSL_OK) {
|
||||
infof(data, "successfully read cert file %s \n",
|
||||
data->set.str[STRING_CERT]);
|
||||
break;
|
||||
@@ -222,7 +220,7 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
i++;
|
||||
}
|
||||
/* Tried all cert types, none worked. */
|
||||
if(cert_types[i] == 0){
|
||||
if(cert_types[i] == 0) {
|
||||
failf(data, "%s is not x509 or pkcs12 format",
|
||||
data->set.str[STRING_CERT]);
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
@@ -233,13 +231,13 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
/* Load client key.
|
||||
If a pkcs12 file successfully loaded a cert, then there's nothing to do
|
||||
because the key has already been loaded. */
|
||||
if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12){
|
||||
if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) {
|
||||
i=0;
|
||||
/* Instead of trying to analyze key type here, let axTLS try them all. */
|
||||
while(key_types[i] != 0){
|
||||
while(key_types[i] != 0) {
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
|
||||
data->set.str[STRING_KEY], NULL);
|
||||
if(ssl_fcn_return == SSL_OK){
|
||||
if(ssl_fcn_return == SSL_OK) {
|
||||
infof(data, "successfully read key file %s \n",
|
||||
data->set.str[STRING_KEY]);
|
||||
break;
|
||||
@@ -247,7 +245,7 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
i++;
|
||||
}
|
||||
/* Tried all key types, none worked. */
|
||||
if(key_types[i] == 0){
|
||||
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);
|
||||
@@ -273,7 +271,7 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
|
||||
/* Check to make sure handshake was ok. */
|
||||
ssl_fcn_return = ssl_handshake_status(ssl);
|
||||
if(ssl_fcn_return != SSL_OK){
|
||||
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);
|
||||
@@ -285,8 +283,8 @@ Curl_axtls_connect(struct connectdata *conn,
|
||||
*/
|
||||
|
||||
/* Verify server's certificate */
|
||||
if(data->set.ssl.verifypeer){
|
||||
if(ssl_verify_cert(ssl) != SSL_OK){
|
||||
if(data->set.ssl.verifypeer) {
|
||||
if(ssl_verify_cert(ssl) != SSL_OK) {
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "server cert verify failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@@ -415,7 +413,7 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
||||
sizeof(buf));
|
||||
|
||||
if(nread < SSL_OK){
|
||||
if(nread < SSL_OK) {
|
||||
failf(data, "close notify alert not received during shutdown");
|
||||
retval = -1;
|
||||
}
|
||||
@@ -447,13 +445,13 @@ static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
|
||||
|
||||
infof(conn->data, " axtls_recv\n");
|
||||
|
||||
if(connssl){
|
||||
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 ){
|
||||
if(ret == -3 ) {
|
||||
Curl_axtls_close(conn, num);
|
||||
}
|
||||
else if(ret < 0) {
|
||||
|
67
lib/base64.c
67
lib/base64.c
@@ -24,9 +24,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -71,12 +68,19 @@ static void decodeQuantum(unsigned char *dest, const char *src)
|
||||
/*
|
||||
* Curl_base64_decode()
|
||||
*
|
||||
* Given a base64 string at src, decode it and return an allocated memory in
|
||||
* the *outptr. Returns the length of the decoded data.
|
||||
* Given a base64 NUL-terminated string at src, decode it and return a
|
||||
* pointer in *outptr to a newly allocated memory area holding decoded
|
||||
* data. Size of decoded data is returned in variable pointed by outlen.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
* When decoded data length is 0, returns NULL in *outptr.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen)
|
||||
{
|
||||
size_t length = 0;
|
||||
size_t equalsTerm = 0;
|
||||
@@ -87,6 +91,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
unsigned char *newstr;
|
||||
|
||||
*outptr = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
while((src[length] != '=') && src[length])
|
||||
length++;
|
||||
@@ -100,7 +105,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
|
||||
/* Don't allocate a buffer if the decoded length is 0 */
|
||||
if(numQuantums == 0)
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
|
||||
rawlen = (numQuantums * 3) - equalsTerm;
|
||||
|
||||
@@ -108,7 +113,7 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
(which may be partially thrown out) and the zero terminator. */
|
||||
newstr = malloc(rawlen+4);
|
||||
if(!newstr)
|
||||
return 0;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
*outptr = newstr;
|
||||
|
||||
@@ -127,23 +132,34 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr)
|
||||
newstr[i] = lastQuantum[i];
|
||||
|
||||
newstr[i] = '\0'; /* zero terminate */
|
||||
return rawlen;
|
||||
|
||||
*outlen = rawlen; /* return size of decoded data */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64_encode()
|
||||
*
|
||||
* Returns the length of the newly created base64 string. The third argument
|
||||
* is a pointer to an allocated area holding the base64 data. If something
|
||||
* went wrong, 0 is returned.
|
||||
* Given a pointer to an input buffer and an input size, encode it and
|
||||
* return a pointer in *outptr to a newly allocated memory area holding
|
||||
* encoded data. Size of encoded data is returned in variable pointed by
|
||||
* outlen.
|
||||
*
|
||||
* Input length of 0 indicates input buffer holds a NUL-terminated string.
|
||||
*
|
||||
* Returns CURLE_OK on success, otherwise specific error code. Function
|
||||
* output shall not be considered valid unless CURLE_OK is returned.
|
||||
*
|
||||
* When encoded data length is 0, returns NULL in *outptr.
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr)
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode res;
|
||||
CURLcode error;
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
int i;
|
||||
@@ -154,24 +170,25 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
|
||||
const char *indata = inputbuff;
|
||||
|
||||
*outptr = NULL; /* set to NULL in case of failure before we reach the end */
|
||||
*outptr = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
if(0 == insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
base64data = output = malloc(insize*4/3+4);
|
||||
if(NULL == output)
|
||||
return 0;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/*
|
||||
* The base64 data needs to be created using the network encoding
|
||||
* not the host encoding. And we can't change the actual input
|
||||
* so we copy it to a buffer, translate it, and use that instead.
|
||||
*/
|
||||
res = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||
if(res) {
|
||||
error = Curl_convert_clone(data, indata, insize, &convbuf);
|
||||
if(error) {
|
||||
free(output);
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
if(convbuf)
|
||||
@@ -218,12 +235,14 @@ size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
}
|
||||
output += 4;
|
||||
}
|
||||
*output=0;
|
||||
*outptr = base64data; /* make it return the actual data memory */
|
||||
*output = '\0';
|
||||
*outptr = base64data; /* return pointer to new data, allocated memory */
|
||||
|
||||
if(convbuf)
|
||||
free(convbuf);
|
||||
|
||||
return strlen(base64data); /* return the length of the new data */
|
||||
*outlen = strlen(base64data); /* return the length of the new data */
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* ---- End of Base64 Encoding ---- */
|
||||
|
@@ -62,7 +62,7 @@ while(1) {
|
||||
next;
|
||||
}
|
||||
elsif($file =~ /-W(.*)/) {
|
||||
$wlist = $1;
|
||||
$wlist .= " $1 ";
|
||||
$file = shift @ARGV;
|
||||
next;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ if(!$file) {
|
||||
}
|
||||
|
||||
do {
|
||||
if($file ne "$wlist") {
|
||||
if("$wlist" !~ / $file /) {
|
||||
my $fullname = $file;
|
||||
$fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/');
|
||||
scanfile($fullname);
|
||||
@@ -145,9 +145,14 @@ sub scanfile {
|
||||
}
|
||||
|
||||
# check for "} else"
|
||||
if($l =~ /^(.*)\} else/) {
|
||||
if($l =~ /^(.*)\} *else/) {
|
||||
checkwarn($line, length($1), $file, $l, "else after closing brace on same line");
|
||||
}
|
||||
# check for "){"
|
||||
if($l =~ /^(.*)\)\{/) {
|
||||
checkwarn($line, length($1)+1, $file, $l, "missing space after close paren");
|
||||
}
|
||||
|
||||
# check for open brace first on line but not first column
|
||||
# only alert if previous line ended with a close paren and wasn't a cpp
|
||||
# line
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_CLOSESOCKET_CAMEL 1
|
||||
#define HAVE_ERRNO_H 1
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
#define HAVE_INET_ADDR 1
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#define PACKAGE "curl"
|
||||
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
#define HAVE_ERRNO_H 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
#define HAVE_GETADDRINFO 1
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#define OS "mac"
|
||||
|
||||
#define HAVE_ERRNO_H 1
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
@@ -97,6 +97,9 @@
|
||||
/* Define if you have the <des.h> header file. */
|
||||
#undef HAVE_DES_H
|
||||
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
#undef HAVE_ERR_H
|
||||
|
||||
|
@@ -92,6 +92,9 @@
|
||||
/* Define if you have the <des.h> header file. */
|
||||
#undef HAVE_DES_H
|
||||
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
#undef HAVE_ERR_H
|
||||
|
||||
|
@@ -143,6 +143,9 @@
|
||||
/* Define if you have the uname function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __LIB_CONFIG_WIN32_H
|
||||
#define __LIB_CONFIG_WIN32_H
|
||||
#ifndef HEADER_CURL_CONFIG_WIN32_H
|
||||
#define HEADER_CURL_CONFIG_WIN32_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -23,49 +23,57 @@
|
||||
***************************************************************************/
|
||||
|
||||
/* ================================================================ */
|
||||
/* lib/config-win32.h - Hand crafted config file for Windows */
|
||||
/* Hand crafted config file for Windows */
|
||||
/* ================================================================ */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* HEADER FILES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
/* Define if you have the <arpa/inet.h> header file. */
|
||||
/* #define HAVE_ARPA_INET_H 1 */
|
||||
|
||||
/* Define if you have the <assert.h> header file. */
|
||||
/* Define if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define if you have the <crypto.h> header file. */
|
||||
/* Define if you have the <crypto.h> header file. */
|
||||
/* #define HAVE_CRYPTO_H 1 */
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
/* #define HAVE_ERR_H 1 */
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <getopt.h> header file. */
|
||||
/* #define HAVE_GETOPT_H 1 */
|
||||
/* Define if you have the <getopt.h> header file. */
|
||||
#if defined(__MINGW32__) || defined(__POCC__)
|
||||
#define HAVE_GETOPT_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <io.h> header file. */
|
||||
/* Define if you have the <io.h> header file. */
|
||||
#define HAVE_IO_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you need the malloc.h header file even with stdlib.h */
|
||||
/* Define if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define if you need <malloc.h> header even with <stdlib.h> header file. */
|
||||
#if !defined(__SALFORDC__) && !defined(__POCC__)
|
||||
#define NEED_MALLOC_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
/* Define if you have the <netdb.h> header file. */
|
||||
/* #define HAVE_NETDB_H 1 */
|
||||
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
/* Define if you have the <netinet/in.h> header file. */
|
||||
/* #define HAVE_NETINET_IN_H 1 */
|
||||
|
||||
/* Define if you have the <process.h> header file. */
|
||||
/* Define if you have the <process.h> header file. */
|
||||
#ifndef __SALFORDC__
|
||||
#define HAVE_PROCESS_H 1
|
||||
#endif
|
||||
@@ -73,68 +81,68 @@
|
||||
/* Define if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define if you have the <sgtty.h> header file. */
|
||||
/* Define if you have the <sgtty.h> header file. */
|
||||
/* #define HAVE_SGTTY_H 1 */
|
||||
|
||||
/* Define if you have the <ssl.h> header file. */
|
||||
/* Define if you have the <ssl.h> header file. */
|
||||
/* #define HAVE_SSL_H 1 */
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
/* Define if you have the <sys/param.h> header file. */
|
||||
/* #define HAVE_SYS_PARAM_H 1 */
|
||||
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
/* Define if you have the <sys/select.h> header file. */
|
||||
/* #define HAVE_SYS_SELECT_H 1 */
|
||||
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
/* Define if you have the <sys/socket.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKET_H 1 */
|
||||
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
/* Define if you have the <sys/sockio.h> header file. */
|
||||
/* #define HAVE_SYS_SOCKIO_H 1 */
|
||||
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
/* Define if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define if you have the <sys/time.h> header file */
|
||||
/* Define if you have the <sys/time.h> header file. */
|
||||
/* #define HAVE_SYS_TIME_H 1 */
|
||||
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
/* Define if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
/* Define if you have the <sys/utime.h> header file. */
|
||||
#ifndef __BORLANDC__
|
||||
#define HAVE_SYS_UTIME_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
/* Define if you have the <termio.h> header file. */
|
||||
/* #define HAVE_TERMIO_H 1 */
|
||||
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
/* Define if you have the <termios.h> header file. */
|
||||
/* #define HAVE_TERMIOS_H 1 */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \
|
||||
defined(__POCC__)
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <windows.h> header file. */
|
||||
/* Define if you have the <windows.h> header file. */
|
||||
#define HAVE_WINDOWS_H 1
|
||||
|
||||
/* Define if you have the <winsock.h> header file. */
|
||||
/* Define if you have the <winsock.h> header file. */
|
||||
#define HAVE_WINSOCK_H 1
|
||||
|
||||
/* Define if you have the <winsock2.h> header file. */
|
||||
/* Define if you have the <winsock2.h> header file. */
|
||||
#ifndef __SALFORDC__
|
||||
#define HAVE_WINSOCK2_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the <ws2tcpip.h> header file. */
|
||||
/* Define if you have the <ws2tcpip.h> header file. */
|
||||
#ifndef __SALFORDC__
|
||||
#define HAVE_WS2TCPIP_H 1
|
||||
#endif
|
||||
@@ -146,41 +154,44 @@
|
||||
/* Define if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
/* #define TIME_WITH_SYS_TIME 1 */
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* FUNCTIONS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define if you have the closesocket function. */
|
||||
/* Define if you have the closesocket function. */
|
||||
#define HAVE_CLOSESOCKET 1
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
/* #define HAVE_DOPRNT 1 */
|
||||
|
||||
/* Define if you have the gethostbyaddr function. */
|
||||
/* Define if you have the ftruncate function. */
|
||||
#define HAVE_FTRUNCATE 1
|
||||
|
||||
/* Define if you have the gethostbyaddr function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
/* Define if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define if you have the getpass function. */
|
||||
/* Define if you have the getpass function. */
|
||||
/* #define HAVE_GETPASS 1 */
|
||||
|
||||
/* Define if you have the getservbyname function. */
|
||||
/* Define if you have the getservbyname function. */
|
||||
#define HAVE_GETSERVBYNAME 1
|
||||
|
||||
/* Define if you have the getprotobyname function. */
|
||||
/* Define if you have the getprotobyname function. */
|
||||
#define HAVE_GETPROTOBYNAME
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
/* Define if you have the gettimeofday function. */
|
||||
/* #define HAVE_GETTIMEOFDAY 1 */
|
||||
|
||||
/* Define if you have the inet_addr function. */
|
||||
/* Define if you have the inet_addr function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define if you have the ioctlsocket function. */
|
||||
@@ -189,35 +200,41 @@
|
||||
/* Define if you have a working ioctlsocket FIONBIO function. */
|
||||
#define HAVE_IOCTLSOCKET_FIONBIO 1
|
||||
|
||||
/* Define if you have the perror function. */
|
||||
/* Define if you have the perror function. */
|
||||
#define HAVE_PERROR 1
|
||||
|
||||
/* Define if you have the RAND_screen function when using SSL */
|
||||
/* Define if you have the RAND_screen function when using SSL. */
|
||||
#define HAVE_RAND_SCREEN 1
|
||||
|
||||
/* Define if you have the `RAND_status' function when using SSL. */
|
||||
#define HAVE_RAND_STATUS 1
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function.
|
||||
/* Define if you have the `CRYPTO_cleanup_all_ex_data' function.
|
||||
This is present in OpenSSL versions after 0.9.6b */
|
||||
#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
|
||||
|
||||
/* Define if you have the select function. */
|
||||
/* Define if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define if you have the setvbuf function. */
|
||||
/* Define if you have the setlocale function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define if you have the setmode function. */
|
||||
#define HAVE_SETMODE 1
|
||||
|
||||
/* Define if you have the setvbuf function. */
|
||||
#define HAVE_SETVBUF 1
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
/* Define if you have the socket function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/* Define if you have the strcasecmp function. */
|
||||
/* #define HAVE_STRCASECMP 1 */
|
||||
|
||||
/* Define if you have the strdup function. */
|
||||
/* Define if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have the stricmp function. */
|
||||
@@ -229,21 +246,21 @@
|
||||
/* Define if you have the strnicmp function. */
|
||||
#define HAVE_STRNICMP 1
|
||||
|
||||
/* Define if you have the strstr function. */
|
||||
/* Define if you have the strstr function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define if you have the strtoll function. */
|
||||
/* Define if you have the strtoll function. */
|
||||
#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__POCC__)
|
||||
#define HAVE_STRTOLL 1
|
||||
#endif
|
||||
|
||||
/* Define if you have the tcgetattr function. */
|
||||
/* Define if you have the tcgetattr function. */
|
||||
/* #define HAVE_TCGETATTR 1 */
|
||||
|
||||
/* Define if you have the tcsetattr function. */
|
||||
/* Define if you have the tcsetattr function. */
|
||||
/* #define HAVE_TCSETATTR 1 */
|
||||
|
||||
/* Define if you have the utime function */
|
||||
/* Define if you have the utime function. */
|
||||
#ifndef __BORLANDC__
|
||||
#define HAVE_UTIME 1
|
||||
#endif
|
||||
@@ -330,13 +347,13 @@
|
||||
/* TYPEDEF REPLACEMENTS */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if in_addr_t is not an available 'typedefed' type */
|
||||
/* Define if in_addr_t is not an available 'typedefed' type. */
|
||||
#define in_addr_t unsigned long
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
/* Define to the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define ssize_t if it is not an available 'typedefed' type */
|
||||
/* Define if ssize_t is not an available 'typedefed' type. */
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \
|
||||
defined(__POCC__) || \
|
||||
@@ -354,19 +371,19 @@
|
||||
/* TYPE SIZES */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
/* Define to the size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
/* Define to the size of `long double', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
/* Define to the size of `long long', as computed by sizeof. */
|
||||
/* #define SIZEOF_LONG_LONG 8 */
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
/* Define to the size of `short', as computed by sizeof. */
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
/* Define to the size of `size_t', as computed by sizeof. */
|
||||
#if defined(_WIN64)
|
||||
# define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
@@ -377,14 +394,49 @@
|
||||
/* STRUCT RELATED */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
/* Define if you have struct sockaddr_storage. */
|
||||
#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#endif
|
||||
|
||||
/* Define this if you have struct timeval */
|
||||
/* Define if you have struct timeval. */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define if struct sockaddr_in6 has the sin6_scope_id member. */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* BSD-style lwIP TCP/IP stack SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define to use BSD-style lwIP TCP/IP stack. */
|
||||
/* #define USE_LWIPSOCK 1 */
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# undef USE_WINSOCK
|
||||
# undef HAVE_WINSOCK_H
|
||||
# undef HAVE_WINSOCK2_H
|
||||
# undef HAVE_WS2TCPIP_H
|
||||
# undef HAVE_ERRNO_H
|
||||
# undef HAVE_GETHOSTNAME
|
||||
# undef HAVE_GETNAMEINFO
|
||||
# undef LWIP_POSIX_SOCKETS_IO_NAMES
|
||||
# undef RECV_TYPE_ARG1
|
||||
# undef RECV_TYPE_ARG3
|
||||
# undef SEND_TYPE_ARG1
|
||||
# undef SEND_TYPE_ARG3
|
||||
# define HAVE_FREEADDRINFO
|
||||
# define HAVE_GETADDRINFO
|
||||
# define HAVE_GETHOSTBYNAME
|
||||
# define HAVE_GETHOSTBYNAME_R
|
||||
# define HAVE_GETHOSTBYNAME_R_6
|
||||
# define LWIP_POSIX_SOCKETS_IO_NAMES 0
|
||||
# define RECV_TYPE_ARG1 int
|
||||
# define RECV_TYPE_ARG3 size_t
|
||||
# define SEND_TYPE_ARG1 int
|
||||
# define SEND_TYPE_ARG3 size_t
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* Watt-32 tcp/ip SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
@@ -413,8 +465,11 @@
|
||||
/* COMPILER SPECIFIC */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Undef keyword 'const' if it does not work. */
|
||||
/* #undef const */
|
||||
/* Define to nothing if compiler does not support 'const' qualifier. */
|
||||
/* #define const */
|
||||
|
||||
/* Define to nothing if compiler does not support 'volatile' qualifier. */
|
||||
/* #define volatile */
|
||||
|
||||
/* Windows should not have HAVE_GMTIME_R defined */
|
||||
/* #undef HAVE_GMTIME_R */
|
||||
@@ -429,14 +484,14 @@
|
||||
#define HAVE_LONGLONG 1
|
||||
#endif
|
||||
|
||||
/* Define to avoid VS2005 complaining about portable C functions */
|
||||
/* Define to avoid VS2005 complaining about portable C functions. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/* VS2005 and later dafault size for time_t is 64-bit, unless */
|
||||
/* _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */
|
||||
/* VS2005 and later dafault size for time_t is 64-bit, unless
|
||||
_USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
# ifndef _USE_32BIT_TIME_T
|
||||
# define SIZEOF_TIME_T 8
|
||||
@@ -446,12 +501,13 @@
|
||||
#endif
|
||||
|
||||
/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows
|
||||
2000 as a supported build target. VS2008 default installations provide an
|
||||
embedded Windows SDK v6.0A along with the claim that Windows 2000 is a
|
||||
valid build target for VS2008. Popular belief is that binaries built using
|
||||
Windows SDK versions 6.X and Windows 2000 as a build target are functional */
|
||||
2000 as a supported build target. VS2008 default installations provide
|
||||
an embedded Windows SDK v6.0A along with the claim that Windows 2000 is
|
||||
a valid build target for VS2008. Popular belief is that binaries built
|
||||
with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build
|
||||
target are functional. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
# define VS2008_MINIMUM_TARGET 0x0500
|
||||
# define VS2008_MIN_TARGET 0x0500
|
||||
#endif
|
||||
|
||||
/* When no build target is specified VS2008 default build target is Windows
|
||||
@@ -459,18 +515,18 @@
|
||||
for VS2008 we will target the minimum Officially supported build target,
|
||||
which happens to be Windows XP. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
# define VS2008_DEFAULT_TARGET 0x0501
|
||||
# define VS2008_DEF_TARGET 0x0501
|
||||
#endif
|
||||
|
||||
/* VS2008 default target settings and minimum build target check */
|
||||
/* VS2008 default target settings and minimum build target check. */
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT VS2008_DEFAULT_TARGET
|
||||
# define _WIN32_WINNT VS2008_DEF_TARGET
|
||||
# endif
|
||||
# ifndef WINVER
|
||||
# define WINVER VS2008_DEFAULT_TARGET
|
||||
# define WINVER VS2008_DEF_TARGET
|
||||
# endif
|
||||
# if (_WIN32_WINNT < VS2008_MINIMUM_TARGET) || (WINVER < VS2008_MINIMUM_TARGET)
|
||||
# if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET)
|
||||
# error VS2008 does not support Windows build targets prior to Windows 2000
|
||||
# endif
|
||||
#endif
|
||||
@@ -549,13 +605,13 @@
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS
|
||||
* Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS.
|
||||
*/
|
||||
|
||||
/* Define USE_ARES to enable c-ares asynchronous DNS lookups */
|
||||
/* Define to enable c-ares asynchronous DNS lookups. */
|
||||
/* #define USE_ARES 1 */
|
||||
|
||||
/* Define USE_THREADS_WIN32 to enable threaded asynchronous DNS lookups */
|
||||
/* Define to enable threaded asynchronous DNS lookups. */
|
||||
#define USE_THREADS_WIN32 1
|
||||
|
||||
#if defined(USE_ARES) && defined(USE_THREADS_WIN32)
|
||||
@@ -608,8 +664,11 @@
|
||||
/* Name of package */
|
||||
#define PACKAGE "curl"
|
||||
|
||||
/* If you want to build curl with the built-in manual */
|
||||
#define USE_MANUAL 1
|
||||
|
||||
#if defined(__POCC__) || (USE_IPV6)
|
||||
# define ENABLE_IPV6 1
|
||||
#endif
|
||||
|
||||
#endif /* __LIB_CONFIG_WIN32_H */
|
||||
#endif /* HEADER_CURL_CONFIG_WIN32_H */
|
||||
|
@@ -39,6 +39,9 @@
|
||||
/* Define if you have the <crypto.h> header file. */
|
||||
/* #define HAVE_CRYPTO_H 1 */
|
||||
|
||||
/* Define if you have the <errno.h> header file. */
|
||||
/* #define HAVE_ERRNO_H 1 */
|
||||
|
||||
/* Define if you have the <err.h> header file. */
|
||||
/* #define HAVE_ERR_H 1 */
|
||||
|
||||
|
@@ -22,9 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -52,9 +49,6 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
|
||||
#include <sys/filio.h>
|
||||
@@ -68,10 +62,6 @@
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -669,7 +659,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
*connected = FALSE; /* a very negative world view is best */
|
||||
|
||||
if(conn->bits.tcpconnect) {
|
||||
if(conn->bits.tcpconnect[sockindex]) {
|
||||
/* we are connected already! */
|
||||
*connected = TRUE;
|
||||
return CURLE_OK;
|
||||
@@ -708,9 +698,10 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
if(code)
|
||||
return code;
|
||||
|
||||
conn->bits.tcpconnect = TRUE;
|
||||
conn->bits.tcpconnect[sockindex] = TRUE;
|
||||
*connected = TRUE;
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||
if(sockindex == FIRSTSOCKET)
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
|
||||
Curl_verboseconnect(conn);
|
||||
Curl_updateconninfo(conn, sockfd);
|
||||
|
||||
@@ -756,7 +747,7 @@ static void tcpnodelay(struct connectdata *conn,
|
||||
#ifdef TCP_NODELAY
|
||||
struct SessionHandle *data= conn->data;
|
||||
curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
|
||||
int proto = IPPROTO_TCP;
|
||||
int level = IPPROTO_TCP;
|
||||
|
||||
#if 0
|
||||
/* The use of getprotobyname() is disabled since it isn't thread-safe on
|
||||
@@ -768,10 +759,10 @@ static void tcpnodelay(struct connectdata *conn,
|
||||
detected. */
|
||||
struct protoent *pe = getprotobyname("tcp");
|
||||
if(pe)
|
||||
proto = pe->p_proto;
|
||||
level = pe->p_proto;
|
||||
#endif
|
||||
|
||||
if(setsockopt(sockfd, proto, TCP_NODELAY, (void *)&onoff,
|
||||
if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
|
||||
sizeof(onoff)) < 0)
|
||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||
Curl_strerror(conn, SOCKERRNO));
|
||||
@@ -799,10 +790,10 @@ static void nosigpipe(struct connectdata *conn,
|
||||
Curl_strerror(conn, SOCKERRNO));
|
||||
}
|
||||
#else
|
||||
#define nosigpipe(x,y)
|
||||
#define nosigpipe(x,y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef USE_WINSOCK
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __CONNECT_H
|
||||
#define __CONNECT_H
|
||||
#ifndef HEADER_CURL_CONNECT_H
|
||||
#define HEADER_CURL_CONNECT_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -21,6 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
|
||||
|
||||
@@ -52,7 +53,7 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
struct connectdata **connp);
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef USE_WINSOCK
|
||||
/* When you run a program that uses the Windows Sockets API, you may
|
||||
experience slow performance when you copy data to a TCP server.
|
||||
|
||||
@@ -64,10 +65,11 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
*/
|
||||
void Curl_sndbufset(curl_socket_t sockfd);
|
||||
#else
|
||||
#define Curl_sndbufset(y)
|
||||
#define Curl_sndbufset(y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
|
||||
void Curl_persistconninfo(struct connectdata *conn);
|
||||
int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_CONNECT_H */
|
||||
|
@@ -24,9 +24,6 @@
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "sendf.h"
|
||||
@@ -52,6 +49,21 @@
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define RESERVED 0xE0 /* bits 5..7: reserved */
|
||||
|
||||
static voidpf
|
||||
zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
|
||||
{
|
||||
(void) opaque;
|
||||
/* not a typo, keep it calloc() */
|
||||
return (voidpf) calloc(items, size);
|
||||
}
|
||||
|
||||
static void
|
||||
zfree_cb(voidpf opaque, voidpf ptr)
|
||||
{
|
||||
(void) opaque;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
process_zlib_error(struct connectdata *conn, z_stream *z)
|
||||
{
|
||||
@@ -161,11 +173,10 @@ Curl_unencode_deflate_write(struct connectdata *conn,
|
||||
|
||||
/* Initialize zlib? */
|
||||
if(k->zlib_init == ZLIB_UNINIT) {
|
||||
z->zalloc = (alloc_func)Z_NULL;
|
||||
z->zfree = (free_func)Z_NULL;
|
||||
z->opaque = 0;
|
||||
z->next_in = NULL;
|
||||
z->avail_in = 0;
|
||||
memset(z, 0, sizeof(z_stream));
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(inflateInit(z) != Z_OK)
|
||||
return process_zlib_error(conn, z);
|
||||
k->zlib_init = ZLIB_INIT;
|
||||
@@ -272,11 +283,9 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
|
||||
/* Initialize zlib? */
|
||||
if(k->zlib_init == ZLIB_UNINIT) {
|
||||
z->zalloc = (alloc_func)Z_NULL;
|
||||
z->zfree = (free_func)Z_NULL;
|
||||
z->opaque = 0;
|
||||
z->next_in = NULL;
|
||||
z->avail_in = 0;
|
||||
memset(z, 0, sizeof(z_stream));
|
||||
z->zalloc = (alloc_func)zalloc_cb;
|
||||
z->zfree = (free_func)zfree_cb;
|
||||
|
||||
if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
|
||||
/* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __CURL_CONTENT_ENCODING_H
|
||||
#define __CURL_CONTENT_ENCODING_H
|
||||
#ifndef HEADER_CURL_CONTENT_ENCODING_H
|
||||
#define HEADER_CURL_CONTENT_ENCODING_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -32,7 +32,7 @@
|
||||
void Curl_unencode_cleanup(struct connectdata *conn);
|
||||
#else
|
||||
#define ALL_CONTENT_ENCODINGS "identity"
|
||||
#define Curl_unencode_cleanup(x)
|
||||
#define Curl_unencode_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
CURLcode Curl_unencode_deflate_write(struct connectdata *conn,
|
||||
@@ -45,4 +45,4 @@ Curl_unencode_gzip_write(struct connectdata *conn,
|
||||
ssize_t nread);
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* HEADER_CURL_CONTENT_ENCODING_H */
|
||||
|
327
lib/cookie.c
327
lib/cookie.c
@@ -81,9 +81,6 @@ Example set of cookies:
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _MPRINTF_REPLACE
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -129,7 +126,7 @@ static bool tailmatch(const char *little, const char *bigone)
|
||||
if(littlelen > biglen)
|
||||
return FALSE;
|
||||
|
||||
return (bool)Curl_raw_equal(little, bigone+biglen-littlelen);
|
||||
return Curl_raw_equal(little, bigone+biglen-littlelen) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -209,7 +206,6 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
if(httpheader) {
|
||||
/* This line was read off a HTTP-header */
|
||||
const char *ptr;
|
||||
const char *sep;
|
||||
const char *semiptr;
|
||||
char *what;
|
||||
|
||||
@@ -226,185 +222,186 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
|
||||
ptr = lineptr;
|
||||
do {
|
||||
/* we have a <what>=<this> pair or a 'secure' word here */
|
||||
sep = strchr(ptr, '=');
|
||||
if(sep && (!semiptr || (semiptr>sep)) ) {
|
||||
/*
|
||||
* There is a = sign and if there was a semicolon too, which make sure
|
||||
* that the semicolon comes _after_ the equal sign.
|
||||
*/
|
||||
/* we have a <what>=<this> pair or a stand-alone word here */
|
||||
name[0]=what[0]=0; /* init the buffers */
|
||||
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =]=%"
|
||||
MAX_COOKIE_LINE_TXT "[^;\r\n]",
|
||||
name, what)) {
|
||||
/* Use strstore() below to properly deal with received cookie
|
||||
headers that have the same string property set more than once,
|
||||
and then we use the last one. */
|
||||
const char *whatptr;
|
||||
bool done = FALSE;
|
||||
bool sep;
|
||||
size_t len=strlen(what);
|
||||
const char *endofn = &ptr[ strlen(name) ];
|
||||
|
||||
name[0]=what[0]=0; /* init the buffers */
|
||||
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;=]=%"
|
||||
MAX_COOKIE_LINE_TXT "[^;\r\n]",
|
||||
name, what)) {
|
||||
/* this is a <name>=<what> pair. We use strstore() below to properly
|
||||
deal with received cookie headers that have the same string
|
||||
property set more than once, and then we use the last one. */
|
||||
/* skip trailing spaces in name */
|
||||
while(*endofn && ISBLANK(*endofn))
|
||||
endofn++;
|
||||
|
||||
const char *whatptr;
|
||||
/* name ends with a '=' ? */
|
||||
sep = (*endofn == '=')?TRUE:FALSE;
|
||||
|
||||
/* Strip off trailing whitespace from the 'what' */
|
||||
size_t len=strlen(what);
|
||||
while(len && ISBLANK(what[len-1])) {
|
||||
what[len-1]=0;
|
||||
len--;
|
||||
/* Strip off trailing whitespace from the 'what' */
|
||||
while(len && ISBLANK(what[len-1])) {
|
||||
what[len-1]=0;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Skip leading whitespace from the 'what' */
|
||||
whatptr=what;
|
||||
while(*whatptr && ISBLANK(*whatptr))
|
||||
whatptr++;
|
||||
|
||||
if(!len) {
|
||||
/* this was a "<name>=" with no content, and we must allow
|
||||
'secure' and 'httponly' specified this weirdly */
|
||||
done = TRUE;
|
||||
if(Curl_raw_equal("secure", name))
|
||||
co->secure = TRUE;
|
||||
else if(Curl_raw_equal("httponly", name))
|
||||
co->httponly = TRUE;
|
||||
else if(sep)
|
||||
/* there was a '=' so we're not done parsing this field */
|
||||
done = FALSE;
|
||||
}
|
||||
if(done)
|
||||
;
|
||||
else if(Curl_raw_equal("path", name)) {
|
||||
strstore(&co->path, whatptr);
|
||||
if(!co->path) {
|
||||
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 */
|
||||
|
||||
/* Skip leading whitespace from the 'what' */
|
||||
whatptr=what;
|
||||
while(*whatptr && ISBLANK(*whatptr)) {
|
||||
whatptr++;
|
||||
}
|
||||
const char *domptr=whatptr;
|
||||
const char *nextptr;
|
||||
int dotcount=1;
|
||||
|
||||
if(Curl_raw_equal("path", name)) {
|
||||
strstore(&co->path, whatptr);
|
||||
if(!co->path) {
|
||||
badcookie = TRUE; /* out of memory bad */
|
||||
break;
|
||||
/* Count the dots, we need to make sure that there are enough
|
||||
of them. */
|
||||
|
||||
if('.' == whatptr[0])
|
||||
/* don't count the initial dot, assume it */
|
||||
domptr++;
|
||||
|
||||
do {
|
||||
nextptr = strchr(domptr, '.');
|
||||
if(nextptr) {
|
||||
if(domptr != nextptr)
|
||||
dotcount++;
|
||||
domptr = nextptr+1;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
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. */
|
||||
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])
|
||||
/* 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)) {
|
||||
strstore(&co->version, whatptr);
|
||||
if(!co->version) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("max-age", name)) {
|
||||
/* Defined in RFC2109:
|
||||
|
||||
Optional. The Max-Age attribute defines the lifetime of the
|
||||
cookie, in seconds. The delta-seconds value is a decimal non-
|
||||
negative integer. After delta-seconds seconds elapse, the
|
||||
client should discard the cookie. A value of zero means the
|
||||
cookie should be discarded immediately.
|
||||
|
||||
*/
|
||||
strstore(&co->maxage, whatptr);
|
||||
if(!co->maxage) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->expires =
|
||||
strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10)
|
||||
+ (long)now;
|
||||
}
|
||||
else if(Curl_raw_equal("expires", name)) {
|
||||
strstore(&co->expirestr, whatptr);
|
||||
if(!co->expirestr) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
/* Note that if the date couldn't get parsed for whatever reason,
|
||||
the cookie will be treated as a session cookie */
|
||||
co->expires = curl_getdate(what, &now);
|
||||
|
||||
/* Session cookies have expires set to 0 so if we get that back
|
||||
from the date parser let's add a second to make it a
|
||||
non-session cookie */
|
||||
if(co->expires == 0)
|
||||
co->expires = 1;
|
||||
else if(co->expires < 0)
|
||||
co->expires = 0;
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
co->value = strdup(whatptr);
|
||||
if(!co->name || !co->value) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else this is the second (or more) name we don't know
|
||||
about! */
|
||||
}
|
||||
else {
|
||||
/* this is an "illegal" <what>=<this> pair */
|
||||
else if(Curl_raw_equal("version", name)) {
|
||||
strstore(&co->version, whatptr);
|
||||
if(!co->version) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("max-age", name)) {
|
||||
/* Defined in RFC2109:
|
||||
|
||||
Optional. The Max-Age attribute defines the lifetime of the
|
||||
cookie, in seconds. The delta-seconds value is a decimal non-
|
||||
negative integer. After delta-seconds seconds elapse, the
|
||||
client should discard the cookie. A value of zero means the
|
||||
cookie should be discarded immediately.
|
||||
|
||||
*/
|
||||
strstore(&co->maxage, whatptr);
|
||||
if(!co->maxage) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->expires =
|
||||
strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10)
|
||||
+ (long)now;
|
||||
}
|
||||
else if(Curl_raw_equal("expires", name)) {
|
||||
strstore(&co->expirestr, whatptr);
|
||||
if(!co->expirestr) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
/* Note that if the date couldn't get parsed for whatever reason,
|
||||
the cookie will be treated as a session cookie */
|
||||
co->expires = curl_getdate(what, &now);
|
||||
|
||||
/* Session cookies have expires set to 0 so if we get that back
|
||||
from the date parser let's add a second to make it a
|
||||
non-session cookie */
|
||||
if(co->expires == 0)
|
||||
co->expires = 1;
|
||||
else if(co->expires < 0)
|
||||
co->expires = 0;
|
||||
}
|
||||
else if(!co->name) {
|
||||
co->name = strdup(name);
|
||||
co->value = strdup(whatptr);
|
||||
if(!co->name || !co->value) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else this is the second (or more) name we don't know
|
||||
about! */
|
||||
}
|
||||
else {
|
||||
if(sscanf(ptr, "%" MAX_COOKIE_LINE_TXT "[^;\r\n]",
|
||||
what)) {
|
||||
if(Curl_raw_equal("secure", what)) {
|
||||
co->secure = TRUE;
|
||||
}
|
||||
else if(Curl_raw_equal("httponly", what)) {
|
||||
co->httponly = TRUE;
|
||||
}
|
||||
/* else,
|
||||
unsupported keyword without assign! */
|
||||
|
||||
}
|
||||
/* this is an "illegal" <what>=<this> pair */
|
||||
}
|
||||
|
||||
if(!semiptr || !*semiptr) {
|
||||
/* we already know there are no more cookies */
|
||||
semiptr = NULL;
|
||||
@@ -530,7 +527,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
As far as I can see, it is set to true when the cookie says
|
||||
.domain.com and to false when the domain is complete www.domain.com
|
||||
*/
|
||||
co->tailmatch=(bool)Curl_raw_equal(ptr, "TRUE");
|
||||
co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 2:
|
||||
/* It turns out, that sometimes the file format allows the path
|
||||
@@ -550,7 +547,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
fields++; /* add a field and fall down to secure */
|
||||
/* FALLTHROUGH */
|
||||
case 3:
|
||||
co->secure = (bool)Curl_raw_equal(ptr, "TRUE");
|
||||
co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
|
||||
break;
|
||||
case 4:
|
||||
co->expires = curlx_strtoofft(ptr, NULL, 10);
|
||||
|
16
lib/cookie.h
16
lib/cookie.h
@@ -21,15 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(WIN32)
|
||||
#include <time.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -95,10 +87,10 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
|
||||
#define Curl_cookie_list(x) NULL
|
||||
#define Curl_cookie_loadfiles(x) do { } while (0)
|
||||
#define Curl_cookie_loadfiles(x) Curl_nop_stmt
|
||||
#define Curl_cookie_init(x,y,z,w) NULL
|
||||
#define Curl_cookie_cleanup(x) do { } while (0)
|
||||
#define Curl_flush_cookies(x,y)
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#ifdef __VMS
|
||||
# include <in.h>
|
||||
# include <inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if defined(NETWARE) && defined(__NOVELL_LIBC__)
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,10 +22,11 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
size_t Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr);
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
size_t Curl_base64_decode(const char *src, unsigned char **outptr);
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen);
|
||||
|
||||
#endif /* HEADER_CURL_BASE64_H */
|
||||
|
69
lib/curl_gssapi.c
Normal file
69
lib/curl_gssapi.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context,
|
||||
gss_name_t target_name,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags)
|
||||
{
|
||||
OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
||||
req_flags |= GSS_C_DELEG_POLICY_FLAG;
|
||||
#else
|
||||
infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
|
||||
"compiled in\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
|
||||
req_flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
return gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
context,
|
||||
target_name,
|
||||
GSS_C_NO_OID, /* mech_type */
|
||||
req_flags,
|
||||
0, /* time_req */
|
||||
input_chan_bindings,
|
||||
input_token,
|
||||
NULL, /* actual_mech_type */
|
||||
output_token,
|
||||
ret_flags,
|
||||
NULL /* time_rec */);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
57
lib/curl_gssapi.h
Normal file
57
lib/curl_gssapi.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef HEADER_CURL_GSSAPI_H
|
||||
#define HEADER_CURL_GSSAPI_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
#include "urldata.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
|
||||
#ifdef HAVE_GSSGNU
|
||||
# include <gss.h>
|
||||
#elif defined HAVE_GSSMIT
|
||||
/* MIT style */
|
||||
# include <gssapi/gssapi.h>
|
||||
# include <gssapi/gssapi_generic.h>
|
||||
# include <gssapi/gssapi_krb5.h>
|
||||
#else
|
||||
/* Heimdal-style */
|
||||
# include <gssapi.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Common method for using gss api */
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context,
|
||||
gss_name_t target_name,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags);
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
#endif /* HEADER_CURL_GSSAPI_H */
|
235
lib/curl_ntlm.c
Normal file
235
lib/curl_ntlm.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* http://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#define DEBUG_ME 0
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_ntlm.h"
|
||||
#include "curl_ntlm_msgs.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#if defined(USE_NSS)
|
||||
#include "nssg.h"
|
||||
#elif defined(USE_WINDOWS_SSPI)
|
||||
#include "curl_sspi.h"
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if DEBUG_ME
|
||||
# define DEBUG_OUT(x) x
|
||||
#else
|
||||
# define DEBUG_OUT(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
bool proxy, /* if proxy or not */
|
||||
const char *header) /* rest of the www-authenticate:
|
||||
header */
|
||||
{
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
#ifdef USE_NSS
|
||||
result = Curl_nss_force_init(conn->data);
|
||||
if(result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
||||
|
||||
/* skip initial whitespaces */
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
if(checkprefix("NTLM", header)) {
|
||||
header += strlen("NTLM");
|
||||
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
result = Curl_ntlm_decode_type2_message(conn->data, header, ntlm);
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(ntlm->state >= NTLMSTATE_TYPE1) {
|
||||
infof(conn->data, "NTLM handshake failure (internal error)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for creating ntlm header output
|
||||
*/
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy)
|
||||
{
|
||||
char *base64 = NULL;
|
||||
CURLcode error;
|
||||
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
|
||||
/* point to the name and password for this */
|
||||
const char *userp;
|
||||
const char *passwdp;
|
||||
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
struct auth *authp;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->data);
|
||||
|
||||
#ifdef USE_NSS
|
||||
if(CURLE_OK != Curl_nss_force_init(conn->data))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
ntlm = &conn->ntlm;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp = "";
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if(s_hSecDll == NULL) {
|
||||
/* not thread safe and leaks - use curl_global_init() to avoid */
|
||||
CURLcode err = Curl_sspi_global_init();
|
||||
if(s_hSecDll == NULL)
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(ntlm->state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
/* Create a type-1 message */
|
||||
error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(base64) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
|
||||
free(base64);
|
||||
}
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We already received the type-2 message, create a type-3 message */
|
||||
error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
|
||||
ntlm, &base64);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(base64) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
free(base64);
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
|
||||
authp->done = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
if(*allocuserpwd) {
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = NULL;
|
||||
}
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn)
|
||||
{
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
Curl_ntlm_sspi_cleanup(&conn->ntlm);
|
||||
Curl_ntlm_sspi_cleanup(&conn->proxyntlm);
|
||||
#elif defined(NTLM_WB_ENABLED)
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
#else
|
||||
(void)conn;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
44
lib/curl_ntlm.h
Normal file
44
lib/curl_ntlm.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef HEADER_CURL_NTLM_H
|
||||
#define HEADER_CURL_NTLM_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
|
||||
/* this is for ntlm header input */
|
||||
CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
|
||||
const char *header);
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn);
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_http_ntlm_cleanup(a) Curl_nop_stmt
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_H */
|
379
lib/curl_ntlm_core.c
Normal file
379
lib/curl_ntlm_core.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* http://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
|
||||
# ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h>
|
||||
# endif
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# else
|
||||
# include <des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <md4.h>
|
||||
# endif
|
||||
# include <md5.h>
|
||||
# include <ssl.h>
|
||||
# include <rand.h>
|
||||
# endif
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
||||
# define DES_key_schedule des_key_schedule
|
||||
# define DES_cblock des_cblock
|
||||
# define DES_set_odd_parity des_set_odd_parity
|
||||
# define DES_set_key des_set_key
|
||||
# define DES_ecb_encrypt des_ecb_encrypt
|
||||
# define DESKEY(x) x
|
||||
# define DESKEYARG(x) x
|
||||
# else
|
||||
# define DESKEYARG(x) *x
|
||||
# define DESKEY(x) &x
|
||||
# endif
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <gcrypt.h>
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
# define MD4_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
# include <pk11pub.h>
|
||||
# include <hasht.h>
|
||||
# include "curl_md4.h"
|
||||
# define MD5_DIGEST_LENGTH MD5_LENGTH
|
||||
|
||||
#else
|
||||
# error "Can't compile NTLM support without a crypto library."
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
key[0] = key_56[0];
|
||||
key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
||||
key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
||||
key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
||||
key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
||||
key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
||||
key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
|
||||
DES_set_odd_parity(&key);
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
|
||||
#else /* defined(USE_SSLEAY) */
|
||||
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key. Used by GnuTLS and NSS.
|
||||
*/
|
||||
static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
{
|
||||
key[0] = key_56[0];
|
||||
key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
||||
key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
||||
key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
||||
key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
||||
key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
||||
key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
}
|
||||
|
||||
#if defined(USE_GNUTLS)
|
||||
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
gcry_cipher_hd_t *des)
|
||||
{
|
||||
char key[8];
|
||||
extend_key_56_to_64(key_56, key);
|
||||
gcry_cipher_setkey(*des, key, 8);
|
||||
}
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
/*
|
||||
* Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
|
||||
* the expanded key. The caller is responsible for giving 64 bit of valid
|
||||
* data is IN and (at least) 64 bit large buffer as OUT.
|
||||
*/
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
|
||||
PK11SlotInfo *slot = NULL;
|
||||
char key[8]; /* expanded 64 bit key */
|
||||
SECItem key_item;
|
||||
PK11SymKey *symkey = NULL;
|
||||
SECItem *param = NULL;
|
||||
PK11Context *ctx = NULL;
|
||||
int out_len; /* not used, required by NSS */
|
||||
bool rv = FALSE;
|
||||
|
||||
/* use internal slot for DES encryption (requires NSS to be initialized) */
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if(!slot)
|
||||
return FALSE;
|
||||
|
||||
/* expand the 56 bit key to 64 bit and wrap by NSS */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
key_item.data = (unsigned char *)key;
|
||||
key_item.len = /* hard-wired */ 8;
|
||||
symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
|
||||
&key_item, NULL);
|
||||
if(!symkey)
|
||||
goto fail;
|
||||
|
||||
/* create DES encryption context */
|
||||
param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
|
||||
if(!param)
|
||||
goto fail;
|
||||
ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
|
||||
if(!ctx)
|
||||
goto fail;
|
||||
|
||||
/* perform the encryption */
|
||||
if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
|
||||
(unsigned char *)in, /* inbuflen */ 8)
|
||||
&& SECSuccess == PK11_Finalize(ctx))
|
||||
rv = /* all OK */ TRUE;
|
||||
|
||||
fail:
|
||||
/* cleanup */
|
||||
if(ctx)
|
||||
PK11_DestroyContext(ctx, PR_TRUE);
|
||||
if(symkey)
|
||||
PK11_FreeSymKey(symkey);
|
||||
if(param)
|
||||
SECITEM_FreeItem(param, PR_TRUE);
|
||||
PK11_FreeSlot(slot);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif /* defined(USE_NSS) */
|
||||
|
||||
#endif /* defined(USE_SSLEAY) */
|
||||
|
||||
/*
|
||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||
* 8 byte plaintext is encrypted with each key and the resulting 24
|
||||
* bytes are stored in the results array.
|
||||
*/
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results)
|
||||
{
|
||||
#ifdef USE_SSLEAY
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(keys + 14, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_cipher_hd_t des;
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys, &des);
|
||||
gcry_cipher_encrypt(des, results, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys + 7, &des);
|
||||
gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(keys + 14, &des);
|
||||
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
encrypt_des(plaintext, results + 16, keys + 14);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up lanmanager hashed password
|
||||
*/
|
||||
void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
CURLcode res;
|
||||
unsigned char pw[14];
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
};
|
||||
size_t len = CURLMIN(strlen(password), 14);
|
||||
|
||||
Curl_strntoupper((char *)pw, password, len);
|
||||
memset(&pw[len], 0, 14 - len);
|
||||
|
||||
/*
|
||||
* The LanManager hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
*/
|
||||
res = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(res)
|
||||
return;
|
||||
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
|
||||
setup_des_key(pw + 7, DESKEY(ks));
|
||||
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
|
||||
DESKEY(ks), DES_ENCRYPT);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_cipher_hd_t des;
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(pw, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
|
||||
gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
||||
setup_des_key(pw + 7, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
#endif
|
||||
|
||||
memset(lmbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
size_t srclen)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < srclen; i++) {
|
||||
dest[2 * i] = (unsigned char)src[i];
|
||||
dest[2 * i + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up nt hashed passwords
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */)
|
||||
{
|
||||
size_t len = strlen(password);
|
||||
unsigned char *pw = malloc(len * 2);
|
||||
CURLcode result;
|
||||
if(!pw)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ascii_to_unicode_le(pw, password, len);
|
||||
|
||||
/*
|
||||
* The NT hashed password needs to be created using the password in the
|
||||
* network encoding not the host encoding.
|
||||
*/
|
||||
result = Curl_convert_to_network(data, (char *)pw, len * 2);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create NT hashed password. */
|
||||
#ifdef USE_SSLEAY
|
||||
MD4_CTX MD4pw;
|
||||
MD4_Init(&MD4pw);
|
||||
MD4_Update(&MD4pw, pw, 2 * len);
|
||||
MD4_Final(ntbuffer, &MD4pw);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_md_hd_t MD4pw;
|
||||
gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
|
||||
gcry_md_write(MD4pw, pw, 2 * len);
|
||||
memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
|
||||
gcry_md_close(MD4pw);
|
||||
#elif defined(USE_NSS)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#endif
|
||||
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
|
||||
free(pw);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif /* USE_NTRESPONSES */
|
||||
|
||||
#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
|
68
lib/curl_ntlm_core.h
Normal file
68
lib/curl_ntlm_core.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef HEADER_CURL_NTLM_CORE_H
|
||||
#define HEADER_CURL_NTLM_CORE_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
# if !defined(OPENSSL_VERSION_NUMBER) && \
|
||||
!defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
|
||||
# error "curl_ntlm_core.h shall not be included before OpenSSL headers."
|
||||
# endif
|
||||
# ifdef OPENSSL_NO_MD4
|
||||
# define USE_NTRESPONSES 0
|
||||
# define USE_NTLM2SESSION 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
|
||||
* the NT response message. Define USE_NTLM2SESSION to 1 in order to make
|
||||
* the type-3 message include the NTLM2Session response message, requires
|
||||
* USE_NTRESPONSES defined to 1.
|
||||
*/
|
||||
|
||||
#ifndef USE_NTRESPONSES
|
||||
# define USE_NTRESPONSES 1
|
||||
# define USE_NTLM2SESSION 1
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
#endif
|
||||
|
||||
#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_CORE_H */
|
964
lib/curl_ntlm_msgs.c
Normal file
964
lib/curl_ntlm_msgs.c
Normal file
@@ -0,0 +1,964 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* http://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#define DEBUG_ME 0
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
|
||||
# ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <openssl/md4.h>
|
||||
# endif
|
||||
# include <openssl/md5.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/rand.h>
|
||||
# else
|
||||
# include <des.h>
|
||||
# ifndef OPENSSL_NO_MD4
|
||||
# include <md4.h>
|
||||
# endif
|
||||
# include <md5.h>
|
||||
# include <ssl.h>
|
||||
# include <rand.h>
|
||||
# endif
|
||||
# include "ssluse.h"
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
|
||||
# include <gcrypt.h>
|
||||
# include "gtls.h"
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
# define MD4_DIGEST_LENGTH 16
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
|
||||
# include <nss.h>
|
||||
# include <pk11pub.h>
|
||||
# include <hasht.h>
|
||||
# include "nssg.h"
|
||||
# include "curl_md4.h"
|
||||
# define MD5_DIGEST_LENGTH MD5_LENGTH
|
||||
|
||||
#elif defined(USE_WINDOWS_SSPI)
|
||||
# include "curl_sspi.h"
|
||||
#else
|
||||
# error "Can't compile NTLM support without a crypto library."
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_gethostname.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define BUILDING_CURL_NTLM_MSGS_C
|
||||
#include "curl_ntlm_msgs.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Hostname buffer size */
|
||||
#define HOSTNAME_MAX 1024
|
||||
|
||||
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
|
||||
#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
|
||||
|
||||
#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
|
||||
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \
|
||||
(((x) >> 16) & 0xff), (((x) >> 24) & 0xff)
|
||||
|
||||
#if DEBUG_ME
|
||||
# define DEBUG_OUT(x) x
|
||||
static void ntlm_print_flags(FILE *handle, unsigned long flags)
|
||||
{
|
||||
if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_OEM)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
|
||||
if(flags & NTLMFLAG_REQUEST_TARGET)
|
||||
fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
|
||||
if(flags & (1<<3))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_SIGN)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_SEAL)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
|
||||
if(flags & (1<<10))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
|
||||
if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
|
||||
fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
|
||||
if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
|
||||
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
|
||||
if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
|
||||
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
|
||||
if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
|
||||
fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
|
||||
if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
|
||||
fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
|
||||
if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
|
||||
fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
|
||||
if(flags & (1<<24))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
|
||||
if(flags & (1<<25))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
|
||||
if(flags & (1<<26))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
|
||||
if(flags & (1<<27))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
|
||||
if(flags & (1<<28))
|
||||
fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_128)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
|
||||
if(flags & NTLMFLAG_NEGOTIATE_56)
|
||||
fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
|
||||
}
|
||||
|
||||
static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
|
||||
{
|
||||
const char *p = buf;
|
||||
(void)handle;
|
||||
fprintf(stderr, "0x");
|
||||
while(len-- > 0)
|
||||
fprintf(stderr, "%02.2x", (unsigned int)*p++);
|
||||
}
|
||||
#else
|
||||
# define DEBUG_OUT(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
/*
|
||||
* This function converts from the little endian format used in the
|
||||
* incoming package to whatever endian format we're using natively.
|
||||
* Argument is a pointer to a 4 byte buffer.
|
||||
*/
|
||||
static unsigned int readint_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
NTLM message structure notes:
|
||||
|
||||
A 'short' is a 'network short', a little-endian 16-bit unsigned value.
|
||||
|
||||
A 'long' is a 'network long', a little-endian, 32-bit unsigned value.
|
||||
|
||||
A 'security buffer' represents a triplet used to point to a buffer,
|
||||
consisting of two shorts and one long:
|
||||
|
||||
1. A 'short' containing the length of the buffer content in bytes.
|
||||
2. A 'short' containing the allocated space for the buffer in bytes.
|
||||
3. A 'long' containing the offset to the start of the buffer in bytes,
|
||||
from the beginning of the NTLM message.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Curl_ntlm_decode_type2_message()
|
||||
*
|
||||
* This is used to decode a ntlm type-2 message received from a: HTTP, SMTP
|
||||
* or POP3 server. The message is first decoded from a base64 string into a
|
||||
* raw ntlm message and checked for validity before the appropriate data for
|
||||
* creating a type-3 message is written to the given ntlm data structure.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - Pointer to session handle.
|
||||
* header [in] - Pointer to the input buffer.
|
||||
* ntlm [in] - Pointer to ntlm data struct being used and modified.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
const char* header,
|
||||
struct ntlmdata* ntlm)
|
||||
{
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
|
||||
#endif
|
||||
|
||||
/* NTLM type-2 message structure:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x02000000)
|
||||
12 Target Name security buffer
|
||||
20 Flags long
|
||||
24 Challenge 8 bytes
|
||||
(32) Context 8 bytes (two consecutive longs) (*)
|
||||
(40) Target Information security buffer (*)
|
||||
(48) OS Version Structure 8 bytes (*)
|
||||
32 (48) (56) Start of data block (*)
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
size_t size = 0;
|
||||
unsigned char *buffer = NULL;
|
||||
CURLcode error;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
error = Curl_base64_decode(header, &buffer, &size);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(!buffer) {
|
||||
infof(data, "NTLM handshake failure (unhandled condition)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
ntlm->type_2 = malloc(size + 1);
|
||||
if(ntlm->type_2 == NULL) {
|
||||
free(buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
ntlm->n_type_2 = (unsigned long)size;
|
||||
memcpy(ntlm->type_2, buffer, size);
|
||||
#else
|
||||
ntlm->flags = 0;
|
||||
|
||||
if((size < 32) ||
|
||||
(memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
|
||||
(memcmp(buffer + 8, type2_marker, sizeof(type2_marker)) != 0)) {
|
||||
/* This was not a good enough type-2 message */
|
||||
free(buffer);
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ntlm->flags = readint_le(&buffer[20]);
|
||||
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
|
||||
ntlm_print_flags(stderr, ntlm->flags);
|
||||
fprintf(stderr, "\n nonce=");
|
||||
ntlm_print_hex(stderr, (char *)ntlm->nonce, 8);
|
||||
fprintf(stderr, "\n****\n");
|
||||
fprintf(stderr, "**** Header %s\n ", header);
|
||||
});
|
||||
#endif
|
||||
free(buffer);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
||||
{
|
||||
if(ntlm->type_2) {
|
||||
free(ntlm->type_2);
|
||||
ntlm->type_2 = NULL;
|
||||
}
|
||||
if(ntlm->has_handles) {
|
||||
s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
|
||||
s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
|
||||
ntlm->has_handles = 0;
|
||||
}
|
||||
if(ntlm->p_identity) {
|
||||
if(ntlm->identity.User) free(ntlm->identity.User);
|
||||
if(ntlm->identity.Password) free(ntlm->identity.Password);
|
||||
if(ntlm->identity.Domain) free(ntlm->identity.Domain);
|
||||
ntlm->p_identity = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
/* copy the source to the destination and fill in zeroes in every
|
||||
other destination byte! */
|
||||
static void unicodecpy(unsigned char *dest,
|
||||
const char *src, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < length; i++) {
|
||||
dest[2 * i] = (unsigned char)src[i];
|
||||
dest[2 * i + 1] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ntlm_create_type1_message()
|
||||
*
|
||||
* This is used to generate an already encoded NTLM type-1 message ready
|
||||
* for sending to the recipient, be it a: HTTP, SMTP or POP3 server,
|
||||
* using the appropriate compile time crypo API.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* userp [in] - The user name in the format User or Domain\User.
|
||||
* passdwp [in] - The user's password.
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
* outptr [in/out] - The adress where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr)
|
||||
{
|
||||
/* NTLM type-1 message structure:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x01000000)
|
||||
12 Flags long
|
||||
(16) Supplied Domain security buffer (*)
|
||||
(24) Supplied Workstation security buffer (*)
|
||||
(32) OS Version Structure 8 bytes (*)
|
||||
(32) (40) Start of data block (*)
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t base64_sz = 0;
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
SecBuffer buf;
|
||||
SecBufferDesc desc;
|
||||
SECURITY_STATUS status;
|
||||
ULONG attrs;
|
||||
const char *dest = "";
|
||||
const char *user;
|
||||
const char *domain = "";
|
||||
size_t userlen = 0;
|
||||
size_t domlen = 0;
|
||||
size_t passwdlen = 0;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
user = strchr(userp, '\\');
|
||||
if(!user)
|
||||
user = strchr(userp, '/');
|
||||
|
||||
if(user) {
|
||||
domain = userp;
|
||||
domlen = user - userp;
|
||||
user++;
|
||||
}
|
||||
else {
|
||||
user = userp;
|
||||
domain = "";
|
||||
domlen = 0;
|
||||
}
|
||||
|
||||
if(user)
|
||||
userlen = strlen(user);
|
||||
|
||||
if(passwdp)
|
||||
passwdlen = strlen(passwdp);
|
||||
|
||||
if(userlen > 0) {
|
||||
/* note: initialize all of this before doing the mallocs so that
|
||||
* it can be cleaned up later without leaking memory.
|
||||
*/
|
||||
ntlm->p_identity = &ntlm->identity;
|
||||
memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
|
||||
if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ntlm->identity.UserLength = (unsigned long)userlen;
|
||||
if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ntlm->identity.PasswordLength = (unsigned long)strlen(passwdp);
|
||||
if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
strncpy((char *)ntlm->identity.Domain, domain, domlen);
|
||||
ntlm->identity.Domain[domlen] = '\0';
|
||||
ntlm->identity.DomainLength = (unsigned long)domlen;
|
||||
ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
}
|
||||
else
|
||||
ntlm->p_identity = NULL;
|
||||
|
||||
status = s_pSecFn->AcquireCredentialsHandleA(NULL, (void *)"NTLM",
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
ntlm->p_identity, NULL, NULL,
|
||||
&ntlm->handle, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
desc.ulVersion = SECBUFFER_VERSION;
|
||||
desc.cBuffers = 1;
|
||||
desc.pBuffers = &buf;
|
||||
buf.cbBuffer = NTLM_BUFSIZE;
|
||||
buf.BufferType = SECBUFFER_TOKEN;
|
||||
buf.pvBuffer = ntlmbuf;
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
|
||||
(void *)dest,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
NULL, 0,
|
||||
&ntlm->c_handle, &desc,
|
||||
&attrs, &tsDummy);
|
||||
|
||||
if(status == SEC_I_COMPLETE_AND_CONTINUE ||
|
||||
status == SEC_I_CONTINUE_NEEDED)
|
||||
s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
|
||||
else if(status != SEC_E_OK) {
|
||||
s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
ntlm->has_handles = 1;
|
||||
size = buf.cbBuffer;
|
||||
|
||||
#else
|
||||
|
||||
const char *host = ""; /* empty */
|
||||
const char *domain = ""; /* empty */
|
||||
size_t hostlen = 0;
|
||||
size_t domlen = 0;
|
||||
size_t hostoff = 0;
|
||||
size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
|
||||
domain are empty */
|
||||
(void)userp;
|
||||
(void)passwdp;
|
||||
(void)ntlm;
|
||||
|
||||
#if USE_NTLM2SESSION
|
||||
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
|
||||
#else
|
||||
#define NTLM2FLAG 0
|
||||
#endif
|
||||
snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
|
||||
NTLMSSP_SIGNATURE "%c"
|
||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%s" /* host name */
|
||||
"%s", /* domain string */
|
||||
0, /* trailing zero */
|
||||
0, 0, 0, /* part of type-1 long */
|
||||
|
||||
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
|
||||
NTLMFLAG_REQUEST_TARGET |
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY |
|
||||
NTLM2FLAG |
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0, 0,
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0, 0,
|
||||
host, /* this is empty */
|
||||
domain /* this is empty */);
|
||||
|
||||
/* Initial packet length */
|
||||
size = 32 + hostlen + domlen;
|
||||
|
||||
#endif
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
|
||||
"0x%08.8x ",
|
||||
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
|
||||
NTLMFLAG_REQUEST_TARGET |
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY |
|
||||
NTLM2FLAG |
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
|
||||
NTLMFLAG_NEGOTIATE_OEM |
|
||||
NTLMFLAG_REQUEST_TARGET |
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY |
|
||||
NTLM2FLAG |
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
ntlm_print_flags(stderr,
|
||||
NTLMFLAG_NEGOTIATE_OEM |
|
||||
NTLMFLAG_REQUEST_TARGET |
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY |
|
||||
NTLM2FLAG |
|
||||
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
|
||||
fprintf(stderr, "\n****\n");
|
||||
});
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ntlm_create_type3_message()
|
||||
*
|
||||
* This is used to generate an already encoded NTLM type-3 message ready
|
||||
* for sending to the recipient, be it a: HTTP, SMTP or POP3 server,
|
||||
* using the appropriate compile time crypo API.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* userp [in] - The user name in the format User or Domain\User.
|
||||
* passdwp [in] - The user's password.
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
* outptr [in/out] - The adress where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr)
|
||||
{
|
||||
/* NTLM type-3 message structure:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x03000000)
|
||||
12 LM/LMv2 Response security buffer
|
||||
20 NTLM/NTLMv2 Response security buffer
|
||||
28 Target Name security buffer
|
||||
36 User Name security buffer
|
||||
44 Workstation Name security buffer
|
||||
(52) Session Key security buffer (*)
|
||||
(60) Flags long (*)
|
||||
(64) OS Version Structure 8 bytes (*)
|
||||
52 (64) (72) Start of data block
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t base64_sz = 0;
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
const char *dest = "";
|
||||
SecBuffer type_2;
|
||||
SecBuffer type_3;
|
||||
SecBufferDesc type_2_desc;
|
||||
SecBufferDesc type_3_desc;
|
||||
SECURITY_STATUS status;
|
||||
ULONG attrs;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
(void)passwdp;
|
||||
(void)userp;
|
||||
(void)data;
|
||||
|
||||
type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
|
||||
type_2_desc.pBuffers = &type_2;
|
||||
type_3_desc.pBuffers = &type_3;
|
||||
|
||||
type_2.BufferType = SECBUFFER_TOKEN;
|
||||
type_2.pvBuffer = ntlm->type_2;
|
||||
type_2.cbBuffer = ntlm->n_type_2;
|
||||
type_3.BufferType = SECBUFFER_TOKEN;
|
||||
type_3.pvBuffer = ntlmbuf;
|
||||
type_3.cbBuffer = NTLM_BUFSIZE;
|
||||
|
||||
status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
|
||||
&ntlm->c_handle,
|
||||
(void *)dest,
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
&type_2_desc,
|
||||
0, &ntlm->c_handle,
|
||||
&type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
size = type_3.cbBuffer;
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
#else
|
||||
int lmrespoff;
|
||||
unsigned char lmresp[24]; /* fixed-size */
|
||||
#if USE_NTRESPONSES
|
||||
int ntrespoff;
|
||||
unsigned char ntresp[24]; /* fixed-size */
|
||||
#endif
|
||||
bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE;
|
||||
char host[HOSTNAME_MAX + 1] = "";
|
||||
const char *user;
|
||||
const char *domain = "";
|
||||
size_t hostoff = 0;
|
||||
size_t useroff = 0;
|
||||
size_t domoff = 0;
|
||||
size_t hostlen = 0;
|
||||
size_t userlen = 0;
|
||||
size_t domlen = 0;
|
||||
CURLcode res;
|
||||
|
||||
user = strchr(userp, '\\');
|
||||
if(!user)
|
||||
user = strchr(userp, '/');
|
||||
|
||||
if(user) {
|
||||
domain = userp;
|
||||
domlen = (user - domain);
|
||||
user++;
|
||||
}
|
||||
else
|
||||
user = userp;
|
||||
|
||||
if(user)
|
||||
userlen = strlen(user);
|
||||
|
||||
if(Curl_gethostname(host, HOSTNAME_MAX)) {
|
||||
infof(data, "gethostname() failed, continuing without!");
|
||||
hostlen = 0;
|
||||
}
|
||||
else {
|
||||
/* If the workstation if configured with a full DNS name (i.e.
|
||||
* workstation.somewhere.net) gethostname() returns the fully qualified
|
||||
* name, which NTLM doesn't like.
|
||||
*/
|
||||
char *dot = strchr(host, '.');
|
||||
if(dot)
|
||||
*dot = '\0';
|
||||
hostlen = strlen(host);
|
||||
}
|
||||
|
||||
if(unicode) {
|
||||
domlen = domlen * 2;
|
||||
userlen = userlen * 2;
|
||||
hostlen = hostlen * 2;
|
||||
}
|
||||
|
||||
#if USE_NTLM2SESSION
|
||||
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
unsigned char tmp[0x18];
|
||||
unsigned char md5sum[MD5_DIGEST_LENGTH];
|
||||
unsigned char entropy[8];
|
||||
|
||||
/* Need to create 8 bytes random data */
|
||||
#ifdef USE_SSLEAY
|
||||
MD5_CTX MD5pw;
|
||||
Curl_ossl_seed(data); /* Initiate the seed if not already done */
|
||||
RAND_bytes(entropy, 8);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_md_hd_t MD5pw;
|
||||
Curl_gtls_seed(data); /* Initiate the seed if not already done */
|
||||
gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
|
||||
#elif defined(USE_NSS)
|
||||
PK11Context *MD5pw;
|
||||
unsigned int outlen;
|
||||
Curl_nss_seed(data); /* Initiate the seed if not already done */
|
||||
PK11_GenerateRandom(entropy, 8);
|
||||
#endif
|
||||
|
||||
/* 8 bytes random data as challenge in lmresp */
|
||||
memcpy(lmresp, entropy, 8);
|
||||
|
||||
/* Pad with zeros */
|
||||
memset(lmresp + 8, 0, 0x10);
|
||||
|
||||
/* Fill tmp with challenge(nonce?) + entropy */
|
||||
memcpy(tmp, &ntlm->nonce[0], 8);
|
||||
memcpy(tmp + 8, entropy, 8);
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
MD5_Init(&MD5pw);
|
||||
MD5_Update(&MD5pw, tmp, 16);
|
||||
MD5_Final(md5sum, &MD5pw);
|
||||
#elif defined(USE_GNUTLS)
|
||||
gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
|
||||
gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);
|
||||
memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH);
|
||||
gcry_md_close(MD5pw);
|
||||
#elif defined(USE_NSS)
|
||||
MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
|
||||
PK11_DigestOp(MD5pw, tmp, 16);
|
||||
PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH);
|
||||
PK11_DestroyContext(MD5pw, PR_TRUE);
|
||||
#endif
|
||||
|
||||
/* We shall only use the first 8 bytes of md5sum, but the des
|
||||
code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
|
||||
if(CURLE_OUT_OF_MEMORY ==
|
||||
Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
|
||||
|
||||
/* End of NTLM2 Session code */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
unsigned char ntbuffer[0x18];
|
||||
#endif
|
||||
unsigned char lmbuffer[0x18];
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
if(CURLE_OUT_OF_MEMORY ==
|
||||
Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
|
||||
#endif
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
|
||||
Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
|
||||
/* A safer but less compatible alternative is:
|
||||
* Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
|
||||
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
|
||||
}
|
||||
|
||||
lmrespoff = 64; /* size of the message header */
|
||||
#if USE_NTRESPONSES
|
||||
ntrespoff = lmrespoff + 0x18;
|
||||
domoff = ntrespoff + 0x18;
|
||||
#else
|
||||
domoff = lmrespoff + 0x18;
|
||||
#endif
|
||||
useroff = domoff + domlen;
|
||||
hostoff = useroff + userlen;
|
||||
|
||||
/* Create the big type-3 message binary blob */
|
||||
size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
|
||||
NTLMSSP_SIGNATURE "%c"
|
||||
"\x03%c%c%c" /* 32-bit type = 3 */
|
||||
|
||||
"%c%c" /* LanManager length */
|
||||
"%c%c" /* LanManager allocated space */
|
||||
"%c%c" /* LanManager offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* NT-response length */
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* session key length (unknown purpose) */
|
||||
"%c%c" /* session key allocated space (unknown purpose) */
|
||||
"%c%c" /* session key offset (unknown purpose) */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c%c%c", /* flags */
|
||||
|
||||
/* domain string */
|
||||
/* user string */
|
||||
/* host string */
|
||||
/* LanManager response */
|
||||
/* NT response */
|
||||
|
||||
0, /* zero termination */
|
||||
0, 0, 0, /* type-3 long, the 24 upper bits */
|
||||
|
||||
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(ntrespoff),
|
||||
0x0, 0x0,
|
||||
#else
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
#endif
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(userlen),
|
||||
SHORTPAIR(useroff),
|
||||
0x0, 0x0,
|
||||
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostlen),
|
||||
SHORTPAIR(hostoff),
|
||||
0x0, 0x0,
|
||||
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
|
||||
LONGQUARTET(ntlm->flags));
|
||||
|
||||
DEBUGASSERT(size == 64);
|
||||
DEBUGASSERT(size == (size_t)lmrespoff);
|
||||
|
||||
/* We append the binary hashes */
|
||||
if(size < (NTLM_BUFSIZE - 0x18)) {
|
||||
memcpy(&ntlmbuf[size], lmresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "**** TYPE3 header lmresp=");
|
||||
ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
|
||||
});
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
if(size < (NTLM_BUFSIZE - 0x18)) {
|
||||
DEBUGASSERT(size == (size_t)ntrespoff);
|
||||
memcpy(&ntlmbuf[size], ntresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "\n ntresp=");
|
||||
ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
|
||||
LONGQUARTET(ntlm->flags), ntlm->flags);
|
||||
ntlm_print_flags(stderr, ntlm->flags);
|
||||
fprintf(stderr, "\n****\n");
|
||||
});
|
||||
|
||||
/* Make sure that the domain, user and host strings fit in the
|
||||
buffer before we copy them there. */
|
||||
if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
|
||||
failf(data, "user + domain + host name too big");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
DEBUGASSERT(size == domoff);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], domain, domlen / 2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], domain, domlen);
|
||||
|
||||
size += domlen;
|
||||
|
||||
DEBUGASSERT(size == useroff);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], user, userlen / 2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], user, userlen);
|
||||
|
||||
size += userlen;
|
||||
|
||||
DEBUGASSERT(size == hostoff);
|
||||
if(unicode)
|
||||
unicodecpy(&ntlmbuf[size], host, hostlen / 2);
|
||||
else
|
||||
memcpy(&ntlmbuf[size], host, hostlen);
|
||||
|
||||
size += hostlen;
|
||||
|
||||
/* Convert domain, user, and host to ASCII but leave the rest as-is */
|
||||
res = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
|
||||
size - domoff);
|
||||
if(res)
|
||||
return CURLE_CONV_FAILED;
|
||||
|
||||
#endif
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz);
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __HTTP_NTLM_H
|
||||
#define __HTTP_NTLM_H
|
||||
#ifndef HEADER_CURL_NTLM_MSGS_H
|
||||
#define HEADER_CURL_NTLM_MSGS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,27 +22,39 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
CURLNTLM_NONE, /* not a ntlm */
|
||||
CURLNTLM_BAD, /* an ntlm, but one we don't like */
|
||||
CURLNTLM_FIRST, /* the first 401-reply we got with NTLM */
|
||||
CURLNTLM_FINE, /* an ntlm we act on */
|
||||
#include "setup.h"
|
||||
|
||||
CURLNTLM_LAST /* last entry in this enum, don't use */
|
||||
} CURLntlm;
|
||||
#ifdef USE_NTLM
|
||||
|
||||
/* this is for ntlm header input */
|
||||
CURLntlm Curl_input_ntlm(struct connectdata *conn, bool proxy,
|
||||
const char *header);
|
||||
/* This is to generate a base64 encoded NTLM type-1 message */
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr);
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
/* This is to generate a base64 encoded NTLM type-3 message */
|
||||
CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr);
|
||||
|
||||
void Curl_ntlm_cleanup(struct connectdata *conn);
|
||||
#ifndef USE_NTLM
|
||||
#define Curl_ntlm_cleanup(x)
|
||||
/* This is to decode a NTLM type-2 message */
|
||||
CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
const char* header,
|
||||
struct ntlmdata* ntlm);
|
||||
|
||||
/* This is to clean up the ntlm data structure */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
|
||||
#endif
|
||||
|
||||
/* NTLM buffer fixed size, large enough for long user + host + domain */
|
||||
#define NTLM_BUFSIZE 1024
|
||||
|
||||
/* Stuff only required for curl_ntlm_msgs.c */
|
||||
#ifdef BUILDING_CURL_NTLM_MSGS_C
|
||||
|
||||
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
|
||||
@@ -146,4 +158,9 @@ void Curl_ntlm_cleanup(struct connectdata *conn);
|
||||
|
||||
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
|
||||
/* Indicates that 56-bit encryption is supported. */
|
||||
#endif
|
||||
|
||||
#endif /* BUILDING_CURL_NTLM_MSGS_C */
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_MSGS_H */
|
394
lib/curl_ntlm_wb.c
Normal file
394
lib/curl_ntlm_wb.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* http://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#define DEBUG_ME 0
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "select.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if DEBUG_ME
|
||||
# define DEBUG_OUT(x) x
|
||||
#else
|
||||
# define DEBUG_OUT(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/* Portable 'sclose_nolog' used only in child process instead of 'sclose'
|
||||
to avoid fooling the socket leak detector */
|
||||
#if defined(HAVE_CLOSESOCKET)
|
||||
# define sclose_nolog(x) closesocket((x))
|
||||
#elif defined(HAVE_CLOSESOCKET_CAMEL)
|
||||
# define sclose_nolog(x) CloseSocket((x))
|
||||
#else
|
||||
# define sclose_nolog(x) close((x))
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_wb_cleanup(struct connectdata *conn)
|
||||
{
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
|
||||
sclose(conn->ntlm_auth_hlpr_socket);
|
||||
conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
if(conn->ntlm_auth_hlpr_pid) {
|
||||
int i;
|
||||
for(i = 0; i < 4; i++) {
|
||||
pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
|
||||
if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
|
||||
break;
|
||||
switch(i) {
|
||||
case 0:
|
||||
kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
|
||||
break;
|
||||
case 1:
|
||||
/* Give the process another moment to shut down cleanly before
|
||||
bringing down the axe */
|
||||
Curl_wait_ms(1);
|
||||
break;
|
||||
case 2:
|
||||
kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
}
|
||||
conn->ntlm_auth_hlpr_pid = 0;
|
||||
}
|
||||
|
||||
Curl_safefree(conn->challenge_header);
|
||||
conn->challenge_header = NULL;
|
||||
Curl_safefree(conn->response_header);
|
||||
conn->response_header = NULL;
|
||||
}
|
||||
|
||||
static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
{
|
||||
curl_socket_t sockfds[2];
|
||||
pid_t child_pid;
|
||||
const char *username;
|
||||
char *slash, *domain = NULL;
|
||||
const char *ntlm_auth = NULL;
|
||||
char *ntlm_auth_alloc = NULL;
|
||||
int error;
|
||||
|
||||
/* Return if communication with ntlm_auth already set up */
|
||||
if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
|
||||
conn->ntlm_auth_hlpr_pid)
|
||||
return CURLE_OK;
|
||||
|
||||
username = userp;
|
||||
slash = strpbrk(username, "\\/");
|
||||
if(slash) {
|
||||
if((domain = strdup(username)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
slash = domain + (slash - username);
|
||||
*slash = '\0';
|
||||
username = username + (slash - domain) + 1;
|
||||
}
|
||||
|
||||
/* For testing purposes, when DEBUGBUILD is defined and environment
|
||||
variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
|
||||
NTLM challenge/response which only accepts commands and output
|
||||
strings pre-written in test case definitions */
|
||||
#ifdef DEBUGBUILD
|
||||
ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
|
||||
if(ntlm_auth_alloc)
|
||||
ntlm_auth = ntlm_auth_alloc;
|
||||
else
|
||||
#endif
|
||||
ntlm_auth = NTLM_WB_FILE;
|
||||
|
||||
if(access(ntlm_auth, X_OK) != 0) {
|
||||
error = ERRNO;
|
||||
failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
|
||||
ntlm_auth, error, Curl_strerror(conn, error));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
|
||||
error = ERRNO;
|
||||
failf(conn->data, "Could not open socket pair. errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
goto done;
|
||||
}
|
||||
|
||||
child_pid = fork();
|
||||
if(child_pid == -1) {
|
||||
error = ERRNO;
|
||||
sclose(sockfds[0]);
|
||||
sclose(sockfds[1]);
|
||||
failf(conn->data, "Could not fork. errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
goto done;
|
||||
}
|
||||
else if(!child_pid) {
|
||||
/*
|
||||
* child process
|
||||
*/
|
||||
|
||||
/* Don't use sclose in the child since it fools the socket leak detector */
|
||||
sclose_nolog(sockfds[0]);
|
||||
if(dup2(sockfds[1], STDIN_FILENO) == -1) {
|
||||
error = ERRNO;
|
||||
failf(conn->data, "Could not redirect child stdin. errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
|
||||
error = ERRNO;
|
||||
failf(conn->data, "Could not redirect child stdout. errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(domain)
|
||||
execl(ntlm_auth, ntlm_auth,
|
||||
"--helper-protocol", "ntlmssp-client-1",
|
||||
"--use-cached-creds",
|
||||
"--username", username,
|
||||
"--domain", domain,
|
||||
NULL);
|
||||
else
|
||||
execl(ntlm_auth, ntlm_auth,
|
||||
"--helper-protocol", "ntlmssp-client-1",
|
||||
"--use-cached-creds",
|
||||
"--username", username,
|
||||
NULL);
|
||||
|
||||
error = ERRNO;
|
||||
sclose_nolog(sockfds[1]);
|
||||
failf(conn->data, "Could not execl(). errno %d: %s",
|
||||
error, Curl_strerror(conn, error));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sclose(sockfds[1]);
|
||||
conn->ntlm_auth_hlpr_socket = sockfds[0];
|
||||
conn->ntlm_auth_hlpr_pid = child_pid;
|
||||
Curl_safefree(domain);
|
||||
Curl_safefree(ntlm_auth_alloc);
|
||||
return CURLE_OK;
|
||||
|
||||
done:
|
||||
Curl_safefree(domain);
|
||||
Curl_safefree(ntlm_auth_alloc);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
const char *input, curlntlm state)
|
||||
{
|
||||
ssize_t size;
|
||||
char buf[200]; /* enough, type 1, 3 message length is less then 200 */
|
||||
char *tmpbuf = buf;
|
||||
size_t len_in = strlen(input), len_out = sizeof(buf);
|
||||
|
||||
while(len_in > 0) {
|
||||
ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
|
||||
if(written == -1) {
|
||||
/* Interrupted by a signal, retry it */
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
/* write failed if other errors happen */
|
||||
goto done;
|
||||
}
|
||||
input += written;
|
||||
len_in -= written;
|
||||
}
|
||||
/* Read one line */
|
||||
while(len_out > 0) {
|
||||
size = sread(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out);
|
||||
if(size == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
goto done;
|
||||
}
|
||||
else if(size == 0)
|
||||
goto done;
|
||||
else if(tmpbuf[size - 1] == '\n') {
|
||||
tmpbuf[size - 1] = '\0';
|
||||
goto wrfinish;
|
||||
}
|
||||
tmpbuf += size;
|
||||
len_out -= size;
|
||||
}
|
||||
goto done;
|
||||
wrfinish:
|
||||
/* Samba/winbind installed but not configured */
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
size == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
/* invalid response */
|
||||
if(size < 4)
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
(buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE2 &&
|
||||
(buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
|
||||
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
|
||||
goto done;
|
||||
|
||||
conn->response_header = aprintf("NTLM %.*s", size - 4, buf + 3);
|
||||
return CURLE_OK;
|
||||
done:
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is for creating ntlm header output by delegating challenge/response
|
||||
* to Samba's winbind daemon helper ntlm_auth.
|
||||
*/
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
bool proxy)
|
||||
{
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
/* point to the name and password for this */
|
||||
const char *userp;
|
||||
/* point to the correct struct with this */
|
||||
struct ntlmdata *ntlm;
|
||||
struct auth *authp;
|
||||
|
||||
CURLcode res = CURLE_OK;
|
||||
char *input;
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(conn->data);
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
ntlm = &conn->ntlm;
|
||||
authp = &conn->data->state.authhost;
|
||||
}
|
||||
authp->done = FALSE;
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp="";
|
||||
|
||||
switch(ntlm->state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default:
|
||||
/* Use Samba's 'winbind' daemon to support NTLM authentication,
|
||||
* by delegating the NTLM challenge/response protocal to a helper
|
||||
* in ntlm_auth.
|
||||
* http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
|
||||
* http://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
|
||||
* http://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
|
||||
* Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
|
||||
* feature is enabled and 'NTLM_WB_FILE' symbol holds absolute
|
||||
* filename of ntlm_auth helper.
|
||||
* If NTLM authentication using winbind fails, go back to original
|
||||
* request handling process.
|
||||
*/
|
||||
/* Create communication with ntlm_auth */
|
||||
res = ntlm_wb_init(conn, userp);
|
||||
if(res)
|
||||
return res;
|
||||
res = ntlm_wb_response(conn, "YR\n", ntlm->state);
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
|
||||
Curl_safefree(conn->response_header);
|
||||
conn->response_header = NULL;
|
||||
break;
|
||||
case NTLMSTATE_TYPE2:
|
||||
input = aprintf("TT %s", conn->challenge_header);
|
||||
if(!input)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
res = ntlm_wb_response(conn, input, ntlm->state);
|
||||
free(input);
|
||||
input = NULL;
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
Curl_safefree(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
authp->done = TRUE;
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
break;
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
if(*allocuserpwd) {
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd=NULL;
|
||||
}
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM && NTLM_WB_ENABLED */
|
37
lib/curl_ntlm_wb.h
Normal file
37
lib/curl_ntlm_wb.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef HEADER_CURL_NTLM_WB_H
|
||||
#define HEADER_CURL_NTLM_WB_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
|
||||
/* this is for creating ntlm header output by delegating challenge/response
|
||||
to Samba's winbind daemon helper ntlm_auth */
|
||||
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_ntlm_wb_cleanup(struct connectdata *conn);
|
||||
|
||||
#endif /* USE_NTLM && NTLM_WB_ENABLED */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_WB_H */
|
@@ -19,6 +19,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if defined(USE_THREADS_POSIX)
|
||||
|
11
lib/cyassl.c
11
lib/cyassl.c
@@ -27,16 +27,17 @@
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_CYASSL
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "inet_pton.h"
|
||||
@@ -412,7 +413,7 @@ int Curl_cyassl_init(void)
|
||||
bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex)
|
||||
{
|
||||
if(conn->ssl[connindex].handle) /* SSL is in use */
|
||||
return (bool)(0 != SSL_pending(conn->ssl[connindex].handle));
|
||||
return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_CYASSL
|
||||
|
||||
@@ -45,7 +46,7 @@ CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
|
||||
|
||||
/* API setup for CyaSSL */
|
||||
#define curlssl_init Curl_cyassl_init
|
||||
#define curlssl_cleanup()
|
||||
#define curlssl_cleanup() Curl_nop_stmt
|
||||
#define curlssl_connect Curl_cyassl_connect
|
||||
#define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking
|
||||
#define curlssl_session_free(x) Curl_cyassl_session_free(x)
|
||||
|
19
lib/dict.c
19
lib/dict.c
@@ -24,28 +24,18 @@
|
||||
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -64,9 +54,6 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
|
24
lib/easy.c
24
lib/easy.c
@@ -22,29 +22,12 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "strequal.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -65,8 +48,7 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#endif /* WIN32 ... */
|
||||
|
||||
#include "strequal.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
@@ -81,7 +63,7 @@
|
||||
#include "easyif.h"
|
||||
#include "select.h"
|
||||
#include "sendf.h" /* for failf function prototype */
|
||||
#include "http_ntlm.h"
|
||||
#include "curl_ntlm.h"
|
||||
#include "connect.h" /* for Curl_getconnectinfo */
|
||||
#include "slist.h"
|
||||
#include "curl_rand.h"
|
||||
@@ -143,6 +125,8 @@ static CURLcode win32_init(void)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
/* The Windows Sockets DLL is acceptable. Proceed. */
|
||||
#elif defined(USE_LWIPSOCK)
|
||||
lwip_init();
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
@@ -24,12 +24,9 @@
|
||||
* allocated string or NULL if an error occurred. */
|
||||
|
||||
#include "setup.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "curl_memory.h"
|
||||
#include "urldata.h"
|
||||
#include "warnless.h"
|
||||
|
16
lib/file.c
16
lib/file.c
@@ -23,27 +23,13 @@
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -68,8 +54,6 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include "strtoofft.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
|
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "strdup.h"
|
||||
#include "fileinfo.h"
|
||||
|
||||
@@ -49,9 +48,8 @@ void Curl_fileinfo_dtor(void *user, void *element)
|
||||
if(!finfo)
|
||||
return;
|
||||
|
||||
if(finfo->b_data){
|
||||
if(finfo->b_data)
|
||||
free(finfo->b_data);
|
||||
}
|
||||
|
||||
free(finfo);
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* Length of the random boundary string. */
|
||||
@@ -28,14 +29,10 @@
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h" /* for struct SessionHandle */
|
||||
#include "formdata.h"
|
||||
#include "curl_rand.h"
|
||||
@@ -462,7 +459,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if(current_form->flags & HTTPPOST_FILENAME) {
|
||||
if(filename) {
|
||||
if((current_form = AddFormInfo(strdup(filename),
|
||||
NULL, current_form)) == NULL)
|
||||
NULL, current_form)) == NULL)
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
@@ -487,46 +484,18 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
break;
|
||||
}
|
||||
|
||||
case CURLFORM_BUFFER:
|
||||
{
|
||||
const char *filename = array_state?array_value:
|
||||
va_arg(params, char *);
|
||||
|
||||
if(current_form->value) {
|
||||
if(current_form->flags & HTTPPOST_BUFFER) {
|
||||
if(filename) {
|
||||
if((current_form = AddFormInfo(strdup(filename),
|
||||
NULL, current_form)) == NULL)
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
}
|
||||
else {
|
||||
if(filename) {
|
||||
current_form->value = strdup(filename);
|
||||
if(!current_form->value)
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
current_form->flags |= HTTPPOST_BUFFER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CURLFORM_BUFFERPTR:
|
||||
current_form->flags |= HTTPPOST_PTRBUFFER;
|
||||
current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
|
||||
if(current_form->buffer)
|
||||
return_value = CURL_FORMADD_OPTION_TWICE;
|
||||
else {
|
||||
char *buffer =
|
||||
array_state?array_value:va_arg(params, char *);
|
||||
if(buffer)
|
||||
if(buffer) {
|
||||
current_form->buffer = buffer; /* store for the moment */
|
||||
current_form->value = buffer; /* make it non-NULL to be accepted
|
||||
as fine */
|
||||
}
|
||||
else
|
||||
return_value = CURL_FORMADD_NULL;
|
||||
}
|
||||
@@ -567,8 +536,8 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
if(current_form->flags & HTTPPOST_FILENAME) {
|
||||
if(contenttype) {
|
||||
if((current_form = AddFormInfo(NULL,
|
||||
strdup(contenttype),
|
||||
current_form)) == NULL)
|
||||
strdup(contenttype),
|
||||
current_form)) == NULL)
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else
|
||||
@@ -606,6 +575,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
break;
|
||||
}
|
||||
case CURLFORM_FILENAME:
|
||||
case CURLFORM_BUFFER:
|
||||
{
|
||||
const char *filename = array_state?array_value:
|
||||
va_arg(params, char *);
|
||||
@@ -622,6 +592,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
}
|
||||
default:
|
||||
return_value = CURL_FORMADD_UNKNOWN_OPTION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,7 +896,8 @@ void curl_formfree(struct curl_httppost *form)
|
||||
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
|
||||
free(form->name); /* free the name */
|
||||
if(!(form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_CALLBACK)) &&
|
||||
if(!(form->flags &
|
||||
(HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) &&
|
||||
form->contents)
|
||||
free(form->contents); /* free the contents */
|
||||
if(form->contenttype)
|
||||
@@ -1301,7 +1273,7 @@ static size_t readfromfile(struct Form *form, char *buffer,
|
||||
size_t size)
|
||||
{
|
||||
size_t nread;
|
||||
bool callback = (bool)(form->data->type == FORM_CALLBACK);
|
||||
bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE;
|
||||
|
||||
if(callback) {
|
||||
if(form->fread_func == ZERO_NULL)
|
||||
|
111
lib/ftp.c
111
lib/ftp.c
@@ -23,11 +23,6 @@
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@@ -109,7 +104,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef CURL_DISABLE_VERBOSE_STRINGS
|
||||
#define ftp_pasv_verbose(a,b,c,d) do { } while(0)
|
||||
#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/* Local API functions */
|
||||
@@ -279,7 +274,7 @@ static void freedirs(struct ftp_conn *ftpc)
|
||||
{
|
||||
int i;
|
||||
if(ftpc->dirs) {
|
||||
for(i=0; i < ftpc->dirdepth; i++){
|
||||
for(i=0; i < ftpc->dirdepth; i++) {
|
||||
if(ftpc->dirs[i]) {
|
||||
free(ftpc->dirs[i]);
|
||||
ftpc->dirs[i]=NULL;
|
||||
@@ -303,8 +298,8 @@ static void freedirs(struct ftp_conn *ftpc)
|
||||
*/
|
||||
static bool isBadFtpString(const char *string)
|
||||
{
|
||||
return (bool)((NULL != strchr(string, '\r')) ||
|
||||
(NULL != strchr(string, '\n')));
|
||||
return ((NULL != strchr(string, '\r')) ||
|
||||
(NULL != strchr(string, '\n'))) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -810,7 +805,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
host = addr;
|
||||
else
|
||||
host = hbuf; /* use the hbuf for host name */
|
||||
}else
|
||||
}
|
||||
else
|
||||
/* there was only a port(-range) given, default the host */
|
||||
host = NULL;
|
||||
} /* data->set.ftpport */
|
||||
@@ -1004,8 +1000,14 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
|
||||
sa->sa_family == AF_INET?1:2,
|
||||
myhost, port);
|
||||
if(result)
|
||||
if(result) {
|
||||
Curl_closesocket(conn, portsock);
|
||||
/* don't retry using PORT */
|
||||
ftpc->count1 = PORT;
|
||||
/* bail out */
|
||||
state(conn, FTP_STOP);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(PORT == fcmd) {
|
||||
@@ -1025,8 +1027,12 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
|
||||
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
|
||||
if(result)
|
||||
if(result) {
|
||||
Curl_closesocket(conn, portsock);
|
||||
/* bail out */
|
||||
state(conn, FTP_STOP);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1048,7 +1054,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
The *proper* fix is to make sure that the active connection from the
|
||||
server is done in a non-blocking way. Currently, it is still BLOCKING.
|
||||
*/
|
||||
conn->bits.tcpconnect = TRUE;
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
|
||||
|
||||
state(conn, FTP_PORT);
|
||||
return result;
|
||||
@@ -1234,13 +1240,16 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
PPSENDF(&conn->proto.ftpc.pp, "%s",cmd);
|
||||
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
|
||||
|
||||
if(lstArg)
|
||||
free(lstArg);
|
||||
|
||||
free(cmd);
|
||||
|
||||
if(result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
state(conn, FTP_LIST);
|
||||
|
||||
return result;
|
||||
@@ -1708,7 +1717,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
conn->bits.tcpconnect = connected; /* simply TRUE or FALSE */
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
|
||||
|
||||
/*
|
||||
* When this is used from the multi interface, this might've returned with
|
||||
@@ -1746,6 +1755,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
/* FIX: this MUST wait for a proper connect first if 'connected' is
|
||||
* FALSE */
|
||||
@@ -1768,10 +1780,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
data->state.proto.ftp = ftp_save;
|
||||
|
||||
if(CURLE_OK != result)
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
|
||||
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
|
||||
@@ -2528,7 +2541,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if(ftpcode/100 == 2)
|
||||
/* We have enabled SSL for the data connection! */
|
||||
conn->ssl[SECONDARYSOCKET].use =
|
||||
(bool)(data->set.ftp_ssl != CURLUSESSL_CONTROL);
|
||||
(data->set.ftp_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
|
||||
/* FTP servers typically responds with 500 if they decide to reject
|
||||
our 'P' request */
|
||||
else if(data->set.ftp_ssl > CURLUSESSL_CONTROL)
|
||||
@@ -2604,12 +2617,6 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
store++;
|
||||
ptr++;
|
||||
}
|
||||
if(ftpc->entrypath)
|
||||
free(ftpc->entrypath);
|
||||
ftpc->entrypath =dir; /* remember this */
|
||||
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
|
||||
/* also save it where getinfo can access it: */
|
||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||
|
||||
/* If the path name does not look like an absolute path (i.e.: it
|
||||
does not start with a '/'), we probably need some server-dependent
|
||||
@@ -2623,11 +2630,27 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if the path name looks strange to minimize overhead on other
|
||||
systems. */
|
||||
|
||||
if(!ftpc->server_os && ftpc->entrypath[0] != '/') {
|
||||
PPSENDF(&ftpc->pp, "SYST", NULL);
|
||||
if(!ftpc->server_os && dir[0] != '/') {
|
||||
|
||||
result = Curl_pp_sendf(&ftpc->pp, "SYST", NULL);
|
||||
if(result != CURLE_OK) {
|
||||
free(dir);
|
||||
return result;
|
||||
}
|
||||
Curl_safefree(ftpc->entrypath);
|
||||
ftpc->entrypath = dir; /* remember this */
|
||||
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
|
||||
/* also save it where getinfo can access it: */
|
||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||
state(conn, FTP_SYST);
|
||||
break;
|
||||
}
|
||||
|
||||
Curl_safefree(ftpc->entrypath);
|
||||
ftpc->entrypath = dir; /* remember this */
|
||||
infof(data, "Entry path is '%s'\n", ftpc->entrypath);
|
||||
/* also save it where getinfo can access it: */
|
||||
data->state.most_recent_ftp_entrypath = ftpc->entrypath;
|
||||
}
|
||||
else {
|
||||
/* couldn't get the path */
|
||||
@@ -2657,19 +2680,28 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
for(store = os; *ptr && *ptr != ' ';)
|
||||
*store++ = *ptr++;
|
||||
*store = '\0'; /* zero terminate */
|
||||
ftpc->server_os = os;
|
||||
|
||||
/* Check for special servers here. */
|
||||
|
||||
if(strequal(ftpc->server_os, "OS/400")) {
|
||||
if(strequal(os, "OS/400")) {
|
||||
/* Force OS400 name format 1. */
|
||||
PPSENDF(&ftpc->pp, "SITE NAMEFMT 1", NULL);
|
||||
result = Curl_pp_sendf(&ftpc->pp, "SITE NAMEFMT 1", NULL);
|
||||
if(result != CURLE_OK) {
|
||||
free(os);
|
||||
return result;
|
||||
}
|
||||
/* remember target server OS */
|
||||
Curl_safefree(ftpc->server_os);
|
||||
ftpc->server_os = os;
|
||||
state(conn, FTP_NAMEFMT);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Nothing special for the target server. */
|
||||
}
|
||||
else {
|
||||
/* Nothing special for the target server. */
|
||||
/* remember target server OS */
|
||||
Curl_safefree(ftpc->server_os);
|
||||
ftpc->server_os = os;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Cannot identify server OS. Continue anyway and cross fingers. */
|
||||
@@ -2820,7 +2852,7 @@ static CURLcode ftp_multi_statemach(struct connectdata *conn,
|
||||
/* Check for the state outside of the Curl_socket_ready() return code checks
|
||||
since at times we are in fact already in this state when this function
|
||||
gets called. */
|
||||
*done = (bool)(ftpc->state == FTP_STOP);
|
||||
*done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -2874,9 +2906,9 @@ static CURLcode ftp_init(struct connectdata *conn)
|
||||
*/
|
||||
ftp->user = conn->user;
|
||||
ftp->passwd = conn->passwd;
|
||||
if(TRUE == isBadFtpString(ftp->user))
|
||||
if(isBadFtpString(ftp->user))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
if(TRUE == isBadFtpString(ftp->passwd))
|
||||
if(isBadFtpString(ftp->passwd))
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
|
||||
@@ -3478,7 +3510,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
result = ftp_easy_statemach(conn);
|
||||
*dophase_done = TRUE; /* with the easy interface we are done here */
|
||||
}
|
||||
*connected = conn->bits.tcpconnect;
|
||||
*connected = conn->bits.tcpconnect[FIRSTSOCKET];
|
||||
|
||||
if(*dophase_done)
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
@@ -4099,12 +4131,13 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
static CURLcode ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = ftp_multi_statemach(conn, dophase_done);
|
||||
CURLcode result = ftp_multi_statemach(conn, dophase_done);
|
||||
|
||||
if(*dophase_done) {
|
||||
if(result)
|
||||
DEBUGF(infof(conn->data, "DO phase failed\n"));
|
||||
else if(*dophase_done) {
|
||||
result = ftp_dophase_done(conn, FALSE /* not connected */);
|
||||
|
||||
DEBUGF(infof(conn->data, "DO phase is complete\n"));
|
||||
|
@@ -37,8 +37,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_fnmatch.h"
|
||||
|
||||
|
@@ -22,10 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __VMS
|
||||
#include <unixlib.h>
|
||||
#endif
|
||||
|
@@ -27,10 +27,6 @@
|
||||
#include "urldata.h"
|
||||
#include "getinfo.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "curl_memory.h"
|
||||
#include "sslgen.h"
|
||||
#include "connect.h" /* Curl_getconnectinfo() */
|
||||
|
19
lib/gopher.c
19
lib/gopher.c
@@ -24,28 +24,18 @@
|
||||
|
||||
#ifndef CURL_DISABLE_GOPHER
|
||||
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -64,9 +54,6 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
|
@@ -29,14 +29,13 @@
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_GNUTLS
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
10
lib/gtls.h
10
lib/gtls.h
@@ -1,5 +1,5 @@
|
||||
#ifndef __GTLS_H
|
||||
#define __GTLS_H
|
||||
#ifndef HEADER_CURL_GTLS_H
|
||||
#define HEADER_CURL_GTLS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -22,8 +22,12 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_GNUTLS
|
||||
|
||||
#include "urldata.h"
|
||||
|
||||
int Curl_gtls_init(void);
|
||||
int Curl_gtls_cleanup(void);
|
||||
CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex);
|
||||
@@ -60,4 +64,4 @@ int Curl_gtls_seed(struct SessionHandle *data);
|
||||
#define curlssl_data_pending(x,y) (x=x, y=y, 0)
|
||||
|
||||
#endif /* USE_GNUTLS */
|
||||
#endif
|
||||
#endif /* HEADER_CURL_GTLS_H */
|
||||
|
@@ -22,9 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hash.h"
|
||||
#include "llist.h"
|
||||
|
||||
|
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -36,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
|
10
lib/hostip.c
10
lib/hostip.c
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -36,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETJMP_H
|
||||
@@ -560,6 +554,10 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
if(timeoutms < 0)
|
||||
/* got an already expired timeout */
|
||||
return CURLRESOLV_TIMEDOUT;
|
||||
|
||||
#ifdef USE_ALARM_TIMEOUT
|
||||
if(data->set.no_signal)
|
||||
/* Ignore the timeout when signals are disabled */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -37,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
|
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -36,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
@@ -160,7 +154,7 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define dump_addrinfo(x,y)
|
||||
#define dump_addrinfo(x,y) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
@@ -36,16 +34,12 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h> /* required for free() prototypes */
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for the close() proto */
|
||||
#endif
|
||||
#ifdef __VMS
|
||||
#include <in.h>
|
||||
#include <inet.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PROCESS_H
|
||||
|
206
lib/http.c
206
lib/http.c
@@ -23,32 +23,13 @@
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@@ -70,8 +51,6 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
@@ -83,7 +62,8 @@
|
||||
#include "strequal.h"
|
||||
#include "sslgen.h"
|
||||
#include "http_digest.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "curl_ntlm.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "url.h"
|
||||
#include "share.h"
|
||||
@@ -252,11 +232,13 @@ static char *copy_header_value(const char *h)
|
||||
*/
|
||||
static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
char *authorization;
|
||||
struct SessionHandle *data=conn->data;
|
||||
size_t size = 0;
|
||||
char *authorization = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char **userp;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
CURLcode error;
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
@@ -270,20 +252,24 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
}
|
||||
|
||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||
if(Curl_base64_encode(data, data->state.buffer,
|
||||
strlen(data->state.buffer),
|
||||
&authorization) > 0) {
|
||||
if(*userp)
|
||||
free(*userp);
|
||||
*userp = aprintf( "%sAuthorization: Basic %s\r\n",
|
||||
proxy?"Proxy-":"",
|
||||
authorization);
|
||||
free(authorization);
|
||||
if(!*userp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
|
||||
error = Curl_base64_encode(data,
|
||||
data->state.buffer, strlen(data->state.buffer),
|
||||
&authorization, &size);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(!authorization)
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
|
||||
Curl_safefree(*userp);
|
||||
*userp = aprintf("%sAuthorization: Basic %s\r\n",
|
||||
proxy?"Proxy-":"",
|
||||
authorization);
|
||||
free(authorization);
|
||||
if(!*userp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -307,6 +293,8 @@ static bool pickoneauth(struct auth *pick)
|
||||
pick->picked = CURLAUTH_DIGEST;
|
||||
else if(avail & CURLAUTH_NTLM)
|
||||
pick->picked = CURLAUTH_NTLM;
|
||||
else if(avail & CURLAUTH_NTLM_WB)
|
||||
pick->picked = CURLAUTH_NTLM_WB;
|
||||
else if(avail & CURLAUTH_BASIC)
|
||||
pick->picked = CURLAUTH_BASIC;
|
||||
else {
|
||||
@@ -393,15 +381,19 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
if((expectsend == -1) || (expectsend > bytessent)) {
|
||||
/* There is still data left to send */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM)) {
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->ntlm.state != NTLMSTATE_NONE)) {
|
||||
/* The NTLM-negotiation has started *OR* there is just a little (<2K)
|
||||
data left to send, keep on sending. */
|
||||
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg)
|
||||
if(!conn->bits.authneg) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
@@ -554,6 +546,15 @@ output_auth_headers(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authstatus->picked == CURLAUTH_NTLM_WB) {
|
||||
auth="NTLM_WB";
|
||||
result = Curl_output_ntlm_wb(conn, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if(authstatus->picked == CURLAUTH_DIGEST) {
|
||||
auth="Digest";
|
||||
@@ -587,7 +588,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
proxy?"Proxy":"Server", auth,
|
||||
proxy?(conn->proxyuser?conn->proxyuser:""):
|
||||
(conn->user?conn->user:""));
|
||||
authstatus->multi = (bool)(!authstatus->done);
|
||||
authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
|
||||
}
|
||||
else
|
||||
authstatus->multi = FALSE;
|
||||
@@ -744,7 +745,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else {
|
||||
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
|
||||
neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
if(neg == 0) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
@@ -766,13 +767,35 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
if(checkprefix("NTLM", start)) {
|
||||
*availp |= CURLAUTH_NTLM;
|
||||
authp->avail |= CURLAUTH_NTLM;
|
||||
if(authp->picked == CURLAUTH_NTLM) {
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLntlm ntlm =
|
||||
Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
|
||||
|
||||
if(CURLNTLM_BAD != ntlm)
|
||||
CURLcode ntlm =
|
||||
Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
if(CURLE_OK == ntlm) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
*availp &= ~CURLAUTH_NTLM;
|
||||
authp->avail &= ~CURLAUTH_NTLM;
|
||||
*availp |= CURLAUTH_NTLM_WB;
|
||||
authp->avail |= CURLAUTH_NTLM_WB;
|
||||
|
||||
/* Get the challenge-message which will be passed to
|
||||
* ntlm_auth for generating the type 3 message later */
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(checkprefix("NTLM", start)) {
|
||||
start += strlen("NTLM");
|
||||
while(*start && ISSPACE(*start))
|
||||
start++;
|
||||
if(*start)
|
||||
if((conn->challenge_header = strdup(start)) == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
@@ -794,7 +817,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
/* We call this function on input Digest headers even if Digest
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use Digest. */
|
||||
dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
|
||||
dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
|
||||
|
||||
if(CURLDIGEST_FINE != dig) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
@@ -923,7 +946,7 @@ static size_t readmoredata(char *buffer,
|
||||
return 0;
|
||||
|
||||
/* make sure that a HTTP request is never sent away chunked! */
|
||||
conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
|
||||
conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
|
||||
|
||||
if(http->postsize <= (curl_off_t)fullsize) {
|
||||
memcpy(buffer, http->postdata, (size_t)http->postsize);
|
||||
@@ -1456,11 +1479,11 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
static bool use_http_1_1(const struct SessionHandle *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
return (bool)((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
|
||||
return ((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
|
||||
((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
|
||||
((conn->httpversion == 11) ||
|
||||
((conn->httpversion != 10) &&
|
||||
(data->state.httpversion != 10)))));
|
||||
(data->state.httpversion != 10))))) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/* check and possibly add an Expect: header */
|
||||
@@ -1615,7 +1638,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
curl_off_t included_body = 0;
|
||||
const char *httpstring;
|
||||
Curl_send_buffer *req_buffer;
|
||||
curl_off_t postsize; /* off_t type to be able to hold a large file size */
|
||||
curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
|
||||
int seekerr = CURL_SEEKFUNC_OK;
|
||||
|
||||
/* Always consider the DO phase done after this function call, even if there
|
||||
@@ -1648,6 +1671,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(!data->state.first_host)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
http->writebytecount = http->readbytecount = 0;
|
||||
|
||||
if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
|
||||
data->set.upload) {
|
||||
@@ -2130,8 +2154,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->allocptr.cookiehost?
|
||||
conn->allocptr.cookiehost:host,
|
||||
data->state.path,
|
||||
(bool)(conn->handler->protocol&CURLPROTO_HTTPS?
|
||||
TRUE:FALSE));
|
||||
(conn->handler->protocol&CURLPROTO_HTTPS)?
|
||||
TRUE:FALSE);
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
|
||||
}
|
||||
if(co) {
|
||||
@@ -2508,6 +2532,17 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
Curl_pgrsSetUploadCounter(data, http->writebytecount);
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
if(http->writebytecount >= postsize) {
|
||||
/* already sent the entire request body, mark the "upload" as
|
||||
complete */
|
||||
infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
|
||||
"%" FORMAT_OFF_T " bytes\n",
|
||||
http->writebytecount, postsize);
|
||||
data->req.upload_done = TRUE;
|
||||
data->req.keepon &= ~KEEP_SEND; /* we're done writing */
|
||||
data->req.exp100 = EXP100_SEND_DATA; /* already sent */
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -2547,7 +2582,7 @@ checkhttpprefix(struct SessionHandle *data,
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
if((rc != TRUE) && (checkprefix("HTTP/", s)))
|
||||
if(!rc && (checkprefix("HTTP/", s)))
|
||||
rc = TRUE;
|
||||
|
||||
#ifdef CURL_DOES_CONVERSIONS
|
||||
@@ -2779,17 +2814,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
|
||||
if(417 == k->httpcode) {
|
||||
/*
|
||||
* we got: "417 Expectation Failed" this means:
|
||||
* we have made a HTTP call and our Expect Header
|
||||
* seems to cause a problem => abort the write operations
|
||||
* (or prevent them from starting).
|
||||
*/
|
||||
k->exp100 = EXP100_FAILED;
|
||||
k->keepon &= ~KEEP_SEND;
|
||||
}
|
||||
|
||||
/*
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
@@ -2829,6 +2853,46 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(k->httpcode >= 300) {
|
||||
if((!conn->bits.authneg) && !conn->bits.close &&
|
||||
!conn->bits.rewindaftersend) {
|
||||
/*
|
||||
* General treatment of errors when about to send data. Including :
|
||||
* "417 Expectation Failed", while waiting for 100-continue.
|
||||
*
|
||||
* The check for close above is done simply because of something
|
||||
* else has already deemed the connection to get closed then
|
||||
* something else should've considered the big picture and we
|
||||
* avoid this check.
|
||||
*
|
||||
* rewindaftersend indicates that something has told libcurl to
|
||||
* continue sending even if it gets discarded
|
||||
*/
|
||||
|
||||
switch(data->set.httpreq) {
|
||||
case HTTPREQ_PUT:
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
/* We got an error response. If this happened before the whole
|
||||
* request body has been sent we stop sending and mark the
|
||||
* connection for closure after we've read the entire response.
|
||||
*/
|
||||
if(!k->upload_done) {
|
||||
infof(data, "HTTP error before end of send, stop sending\n");
|
||||
conn->bits.close = TRUE; /* close after this */
|
||||
k->upload_done = TRUE;
|
||||
k->keepon &= ~KEEP_SEND; /* don't send */
|
||||
if(data->state.expect100header)
|
||||
k->exp100 = EXP100_FAILED;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* default label present to avoid compiler warnings */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(conn->bits.rewindaftersend) {
|
||||
/* We rewind after a complete send, so thus we continue
|
||||
sending now */
|
||||
@@ -2929,23 +2993,23 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
|
||||
if(conn->handler->protocol & CURLPROTO_HTTP) {
|
||||
nc = sscanf(HEADER1,
|
||||
" HTTP/%d.%d %3d",
|
||||
&httpversion_major,
|
||||
&conn->httpversion,
|
||||
&k->httpcode);
|
||||
" HTTP/%d.%d %3d",
|
||||
&httpversion_major,
|
||||
&conn->httpversion,
|
||||
&k->httpcode);
|
||||
if(nc==3) {
|
||||
conn->httpversion += 10 * httpversion_major;
|
||||
}
|
||||
else {
|
||||
/* this is the real world, not a Nirvana
|
||||
NCSA 1.5.x returns this crap when asked for HTTP/1.1
|
||||
*/
|
||||
*/
|
||||
nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
|
||||
conn->httpversion = 10;
|
||||
|
||||
/* If user has set option HTTP200ALIASES,
|
||||
compare header line against list of aliases
|
||||
*/
|
||||
*/
|
||||
if(!nc) {
|
||||
if(checkhttpprefix(data, k->p)) {
|
||||
nc = 1;
|
||||
|
@@ -19,15 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h" /* it includes http_chunks.h */
|
||||
#include "sendf.h" /* for the client write stuff */
|
||||
@@ -84,9 +79,9 @@
|
||||
We avoid the use of isxdigit to accommodate non-ASCII hosts. */
|
||||
static bool Curl_isxdigit(char digit)
|
||||
{
|
||||
return (bool)( (digit >= 0x30 && digit <= 0x39) /* 0-9 */
|
||||
|| (digit >= 0x41 && digit <= 0x46) /* A-F */
|
||||
|| (digit >= 0x61 && digit <= 0x66) ); /* a-f */
|
||||
return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */
|
||||
|| (digit >= 0x41 && digit <= 0x46) /* A-F */
|
||||
|| (digit >= 0x61 && digit <= 0x66) /* a-f */ ) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void Curl_httpchunk_init(struct connectdata *conn)
|
||||
|
@@ -19,15 +19,10 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -285,7 +280,8 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
unsigned char *ha1;
|
||||
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
||||
char cnoncebuf[7];
|
||||
char *cnonce;
|
||||
char *cnonce = NULL;
|
||||
size_t cnonce_sz = 0;
|
||||
char *tmp = NULL;
|
||||
struct timeval now;
|
||||
|
||||
@@ -348,10 +344,12 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
/* Generate a cnonce */
|
||||
now = Curl_tvnow();
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%06ld", (long)now.tv_sec);
|
||||
if(Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), &cnonce))
|
||||
d->cnonce = cnonce;
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||
&cnonce, &cnonce_sz);
|
||||
if(rc)
|
||||
return rc;
|
||||
d->cnonce = cnonce;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef __HTTP_DIGEST_H
|
||||
#define __HTTP_DIGEST_H
|
||||
#ifndef HEADER_CURL_HTTP_DIGEST_H
|
||||
#define HEADER_CURL_HTTP_DIGEST_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@@ -21,6 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
typedef enum {
|
||||
CURLDIGEST_NONE, /* not a digest */
|
||||
@@ -50,7 +51,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
#else
|
||||
#define Curl_digest_cleanup(x) do {} while(0)
|
||||
#define Curl_digest_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* HEADER_CURL_HTTP_DIGEST_H */
|
||||
|
@@ -19,27 +19,25 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef HAVE_OLD_GSSMIT
|
||||
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
|
||||
#define NCOMPAT 1
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_gssapi.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_base64.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
#include "url.h"
|
||||
|
||||
#ifdef HAVE_SPNEGO
|
||||
# include <spnegohelp.h>
|
||||
@@ -134,15 +132,18 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status,
|
||||
int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
|
||||
&data->state.negotiate;
|
||||
OM_uint32 major_status, minor_status, minor_status2;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
int ret;
|
||||
size_t len, rawlen;
|
||||
size_t len;
|
||||
size_t rawlen = 0;
|
||||
bool gss;
|
||||
const char* protocol;
|
||||
CURLcode error;
|
||||
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
@@ -171,7 +172,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* We finished successfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
* can't invent anything better */
|
||||
Curl_cleanup_negotiate(conn->data);
|
||||
Curl_cleanup_negotiate(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -185,9 +186,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
len = strlen(header);
|
||||
if(len > 0) {
|
||||
rawlen = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token.value);
|
||||
if(rawlen == 0)
|
||||
error = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token.value, &rawlen);
|
||||
if(error || rawlen == 0)
|
||||
return -1;
|
||||
input_token.length = rawlen;
|
||||
|
||||
@@ -220,7 +221,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
NULL)) {
|
||||
free(spnegoToken);
|
||||
spnegoToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token failed\n");
|
||||
infof(data, "Parse SPNEGO Target Token failed\n");
|
||||
}
|
||||
else {
|
||||
free(input_token.value);
|
||||
@@ -232,30 +233,25 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
input_token.length = mechTokenLength;
|
||||
free(mechToken);
|
||||
mechToken = NULL;
|
||||
infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
|
||||
infof(data, "Parse SPNEGO Target Token succeeded\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
major_status = gss_init_sec_context(&minor_status,
|
||||
GSS_C_NO_CREDENTIAL,
|
||||
&neg_ctx->context,
|
||||
neg_ctx->server_name,
|
||||
GSS_C_NO_OID,
|
||||
0,
|
||||
0,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
NULL,
|
||||
&output_token,
|
||||
NULL,
|
||||
NULL);
|
||||
major_status = Curl_gss_init_sec_context(data,
|
||||
&minor_status,
|
||||
&neg_ctx->context,
|
||||
neg_ctx->server_name,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
&output_token,
|
||||
NULL);
|
||||
if(input_token.length > 0)
|
||||
gss_release_buffer(&minor_status2, &input_token);
|
||||
neg_ctx->status = major_status;
|
||||
if(GSS_ERROR(major_status)) {
|
||||
/* Curl_cleanup_negotiate(conn->data) ??? */
|
||||
/* Curl_cleanup_negotiate(data) ??? */
|
||||
log_gss_error(conn, minor_status,
|
||||
"gss_init_sec_context() failed: ");
|
||||
return -1;
|
||||
@@ -277,8 +273,9 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
char *encoded = NULL;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
CURLcode error;
|
||||
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", neg_ctx->protocol)) {
|
||||
@@ -324,13 +321,21 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
len = Curl_base64_encode(conn->data,
|
||||
neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length,
|
||||
&encoded);
|
||||
error = Curl_base64_encode(conn->data,
|
||||
neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length,
|
||||
&encoded, &len);
|
||||
if(error) {
|
||||
Curl_safefree(neg_ctx->output_token.value);
|
||||
neg_ctx->output_token.value = NULL;
|
||||
return error;
|
||||
}
|
||||
|
||||
if(len == 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
if(len == 0) {
|
||||
Curl_safefree(neg_ctx->output_token.value);
|
||||
neg_ctx->output_token.value = NULL;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||
neg_ctx->protocol, encoded);
|
||||
|
@@ -19,17 +19,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -45,13 +40,16 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, bool proxy, char *server)
|
||||
get_gss_name(struct connectdata *conn, bool proxy,
|
||||
struct negotiatedata *neg_ctx)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
const char* service;
|
||||
size_t length;
|
||||
|
||||
if(proxy && !conn->proxy.name)
|
||||
/* proxy auth requested but no given proxy name, error out! */
|
||||
return -1;
|
||||
|
||||
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
|
||||
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
|
||||
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
|
||||
@@ -71,7 +69,7 @@ get_gss_name(struct connectdata *conn, bool proxy, char *server)
|
||||
if(length + 1 > sizeof(neg_ctx->server_name))
|
||||
return EMSGSIZE;
|
||||
|
||||
snprintf(server, sizeof(neg_ctx->server_name), "%s/%s",
|
||||
snprintf(neg_ctx->server_name, sizeof(neg_ctx->server_name), "%s/%s",
|
||||
service, proxy ? conn->proxy.name : conn->host.name);
|
||||
|
||||
return 0;
|
||||
@@ -84,7 +82,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
BYTE *input_token = 0;
|
||||
BYTE *input_token = 0;
|
||||
SecBufferDesc out_buff_desc;
|
||||
SecBuffer out_sec_buff;
|
||||
SecBufferDesc in_buff_desc;
|
||||
@@ -96,6 +94,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
size_t len = 0, input_token_len = 0;
|
||||
bool gss = FALSE;
|
||||
const char* protocol;
|
||||
CURLcode error;
|
||||
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
@@ -129,9 +128,11 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(strlen(neg_ctx->server_name) == 0 &&
|
||||
(ret = get_gss_name(conn, proxy, neg_ctx->server_name)))
|
||||
return ret;
|
||||
if(0 == strlen(neg_ctx->server_name)) {
|
||||
ret = get_gss_name(conn, proxy, neg_ctx);
|
||||
if(ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(!neg_ctx->output_token) {
|
||||
PSecPkgInfo SecurityPackage;
|
||||
@@ -176,9 +177,10 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
if(!input_token)
|
||||
return -1;
|
||||
|
||||
input_token_len = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token);
|
||||
if(input_token_len == 0)
|
||||
error = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token,
|
||||
&input_token_len);
|
||||
if(error || input_token_len == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -238,16 +240,19 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
char *encoded = NULL;
|
||||
size_t len;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
CURLcode error;
|
||||
|
||||
len = Curl_base64_encode(conn->data,
|
||||
(const char*)neg_ctx->output_token,
|
||||
neg_ctx->output_token_length,
|
||||
&encoded);
|
||||
error = Curl_base64_encode(conn->data,
|
||||
(const char*)neg_ctx->output_token,
|
||||
neg_ctx->output_token_length,
|
||||
&encoded, &len);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(len == 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
|
||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||
neg_ctx->protocol, encoded);
|
||||
|
1329
lib/http_ntlm.c
1329
lib/http_ntlm.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user