Compare commits
219 Commits
curl-7_37_
...
curl-7_38_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
202aa9f775 | ||
![]() |
9636fc2588 | ||
![]() |
a76825a5ef | ||
![]() |
8a75dbeb23 | ||
![]() |
1ccfabb66d | ||
![]() |
40bcd5447c | ||
![]() |
4455f1f599 | ||
![]() |
9e6c3638e6 | ||
![]() |
fa50d9d96d | ||
![]() |
38ced24ad1 | ||
![]() |
921a0c22a6 | ||
![]() |
af45542cfe | ||
![]() |
55f8b03948 | ||
![]() |
55d6cba5e1 | ||
![]() |
3963adca3d | ||
![]() |
6beb0eeea1 | ||
![]() |
8acbb074f8 | ||
![]() |
be83356e5e | ||
![]() |
797d56cbd8 | ||
![]() |
9ee502ac6b | ||
![]() |
ed285ae5c9 | ||
![]() |
436a841354 | ||
![]() |
4a6fa4c204 | ||
![]() |
c25cd9094b | ||
![]() |
21db158722 | ||
![]() |
e40197315d | ||
![]() |
fd1ce3856a | ||
![]() |
c6ee182bd4 | ||
![]() |
4989695ec3 | ||
![]() |
0b48d1c821 | ||
![]() |
9e50d8f8bc | ||
![]() |
a6c48c8be7 | ||
![]() |
3c8c873252 | ||
![]() |
4901ec2324 | ||
![]() |
e608324f9f | ||
![]() |
0c14b31df4 | ||
![]() |
0426670f0a | ||
![]() |
cacdc27f52 | ||
![]() |
09b5a99816 | ||
![]() |
4c134bcfce | ||
![]() |
2434a4e88d | ||
![]() |
c9a981778d | ||
![]() |
367b784738 | ||
![]() |
7bff23b166 | ||
![]() |
accbbd7dc3 | ||
![]() |
889de6b285 | ||
![]() |
1d30f40950 | ||
![]() |
1cd5008bba | ||
![]() |
da933ee29d | ||
![]() |
d4a4a42cb3 | ||
![]() |
11bb05ba48 | ||
![]() |
0072422576 | ||
![]() |
dfd821c738 | ||
![]() |
ee40b6882d | ||
![]() |
36a7638073 | ||
![]() |
2603618831 | ||
![]() |
b17b4b4a4a | ||
![]() |
f646e9075f | ||
![]() |
ba8795083f | ||
![]() |
06de7d6936 | ||
![]() |
febcfab23d | ||
![]() |
1269df2e3b | ||
![]() |
dda86f386d | ||
![]() |
7320e53d9e | ||
![]() |
118977f19d | ||
![]() |
88c17d5587 | ||
![]() |
73a1a639a7 | ||
![]() |
8f4da2965e | ||
![]() |
14aa8f0c11 | ||
![]() |
898808fa8c | ||
![]() |
a20da5523e | ||
![]() |
5be48639b1 | ||
![]() |
1a073a20db | ||
![]() |
63a0bd4270 | ||
![]() |
98633c2a19 | ||
![]() |
bdfc75e751 | ||
![]() |
da23624b57 | ||
![]() |
30f2d0c0b3 | ||
![]() |
f854130b7b | ||
![]() |
2f2d84033b | ||
![]() |
b1341b3068 | ||
![]() |
23d52ca4a7 | ||
![]() |
437b9ba46f | ||
![]() |
f6e15d25a3 | ||
![]() |
75be5a6681 | ||
![]() |
c4410c85ab | ||
![]() |
97f6049bc2 | ||
![]() |
29240cb5c1 | ||
![]() |
7679cb3fa8 | ||
![]() |
0574196acb | ||
![]() |
14b3a2e4c3 | ||
![]() |
5663272435 | ||
![]() |
03f368d94c | ||
![]() |
96034c4a51 | ||
![]() |
078d1fbf2b | ||
![]() |
9eba83c156 | ||
![]() |
0187c9e11d | ||
![]() |
472d1d8e05 | ||
![]() |
629f52843f | ||
![]() |
c126bac153 | ||
![]() |
cff0757c31 | ||
![]() |
b5c56190b2 | ||
![]() |
4b491c675f | ||
![]() |
3ec253532e | ||
![]() |
215f932e49 | ||
![]() |
076c0ab683 | ||
![]() |
57b53918d1 | ||
![]() |
fc5a5a4f07 | ||
![]() |
01368d395c | ||
![]() |
cb1f18661a | ||
![]() |
97d2e4bd75 | ||
![]() |
33a95659e2 | ||
![]() |
35b078b29a | ||
![]() |
2384c11ff1 | ||
![]() |
4c4a188a22 | ||
![]() |
cd6ecf6a89 | ||
![]() |
d804ff0d6b | ||
![]() |
343befa44b | ||
![]() |
72945b856e | ||
![]() |
d01e30431c | ||
![]() |
ff5dcb8df2 | ||
![]() |
f187372f0a | ||
![]() |
1b69122810 | ||
![]() |
e9b4a96975 | ||
![]() |
37f0e8a32c | ||
![]() |
b91e97eabd | ||
![]() |
cda4aaba4d | ||
![]() |
ea864fb24d | ||
![]() |
5908ce5115 | ||
![]() |
159c3aafd8 | ||
![]() |
df739784e5 | ||
![]() |
03d34b683d | ||
![]() |
dc61480c54 | ||
![]() |
f05e1a991a | ||
![]() |
7ceada43af | ||
![]() |
26393a97b2 | ||
![]() |
7d2f61f66a | ||
![]() |
40e13829af | ||
![]() |
f719a97e12 | ||
![]() |
6c6983f477 | ||
![]() |
c399f6eeb2 | ||
![]() |
f8a8ed73fe | ||
![]() |
f8af8606a5 | ||
![]() |
524833e155 | ||
![]() |
5b37db44a3 | ||
![]() |
0e452a02f1 | ||
![]() |
ea6d371e7c | ||
![]() |
7efff86639 | ||
![]() |
67920e1516 | ||
![]() |
4d4dd7aea0 | ||
![]() |
cac1dd58a8 | ||
![]() |
595f5f0e43 | ||
![]() |
e4f6adb023 | ||
![]() |
8da2124060 | ||
![]() |
b9f6ca1d32 | ||
![]() |
05e81222d4 | ||
![]() |
7bb4c8cadb | ||
![]() |
f8f2188888 | ||
![]() |
0c23ec232b | ||
![]() |
a439e438f3 | ||
![]() |
028a408d57 | ||
![]() |
3d5be801b9 | ||
![]() |
1aa6418af9 | ||
![]() |
524bb823c9 | ||
![]() |
2c1db913f7 | ||
![]() |
01a0168806 | ||
![]() |
0e811d8c59 | ||
![]() |
df52f3500c | ||
![]() |
f0369223cd | ||
![]() |
16cb818a74 | ||
![]() |
8dfd22089c | ||
![]() |
37faf55e17 | ||
![]() |
30b093f6fc | ||
![]() |
f3bd3deddd | ||
![]() |
6543f6e36c | ||
![]() |
2fab0d45a9 | ||
![]() |
dc7a598126 | ||
![]() |
5828e886e6 | ||
![]() |
c56aa6f121 | ||
![]() |
e1b13eba75 | ||
![]() |
aae4e4bf70 | ||
![]() |
9c1cf96664 | ||
![]() |
821d4a1e55 | ||
![]() |
4e11bd156e | ||
![]() |
64010d603c | ||
![]() |
c31dec7f98 | ||
![]() |
5b22c47ca9 | ||
![]() |
8efc11a0c1 | ||
![]() |
2cd0c2d244 | ||
![]() |
05a887ebfa | ||
![]() |
81cd24adb8 | ||
![]() |
713f96ee0c | ||
![]() |
cc52d776dd | ||
![]() |
a8206adcad | ||
![]() |
3cad5ab77a | ||
![]() |
eed1c63c70 | ||
![]() |
e38ba43014 | ||
![]() |
46750c39bd | ||
![]() |
5128672731 | ||
![]() |
eda12bcff8 | ||
![]() |
a4cece3d47 | ||
![]() |
d242839af8 | ||
![]() |
6f8046f7a4 | ||
![]() |
c6e7cbb94e | ||
![]() |
12bf451ca4 | ||
![]() |
af46c96d65 | ||
![]() |
2856027e59 | ||
![]() |
fb93fa9216 | ||
![]() |
da172b0dde | ||
![]() |
6ffc113ceb | ||
![]() |
1abc42b26c | ||
![]() |
d19dfa974c | ||
![]() |
3de576efda | ||
![]() |
6bc76194e8 | ||
![]() |
f78ae415d2 | ||
![]() |
59431c242b | ||
![]() |
9ad282b1ae | ||
![]() |
223612afa2 | ||
![]() |
9008f3d564 |
@@ -19,21 +19,17 @@ macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
|
||||
if(${ARGC} GREATER 2)
|
||||
# then add the third argument as a message
|
||||
set(message "${ARGV2} (${VAR})")
|
||||
endif(${ARGC} GREATER 2)
|
||||
endif()
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
else(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
endif()
|
||||
if(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
|
||||
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
|
||||
else(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CURL_CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
|
||||
endif(CMAKE_REQUIRED_INCLUDES)
|
||||
endif()
|
||||
set(src "")
|
||||
foreach(def ${EXTRA_DEFINES})
|
||||
set(src "${src}#define ${def} 1\n")
|
||||
@@ -63,13 +59,13 @@ macro(CURL_CHECK_C_SOURCE_COMPILES SOURCE VAR)
|
||||
"Performing C SOURCE FILE Test ${message} succeded with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${src}\n")
|
||||
else(${VAR})
|
||||
else()
|
||||
message(STATUS "Performing Test ${message} - Failed")
|
||||
set(${VAR} "" CACHE INTERNAL "Test ${message}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing C SOURCE FILE Test ${message} failed with the following output:\n"
|
||||
"${OUTPUT}\n"
|
||||
"Source file was:\n${src}\n")
|
||||
endif(${VAR})
|
||||
endif("${VAR}" MATCHES "^${VAR}$" OR "${VAR}" MATCHES "UNKNOWN")
|
||||
endmacro(CURL_CHECK_C_SOURCE_COMPILES)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
35
CMake/FindLibSSH2.cmake
Normal file
35
CMake/FindLibSSH2.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
# - Try to find the libssh2 library
|
||||
# Once done this will define
|
||||
#
|
||||
# LIBSSH2_FOUND - system has the libssh2 library
|
||||
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
|
||||
# LIBSSH2_LIBRARY - the libssh2 library name
|
||||
|
||||
if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
|
||||
set(LibSSH2_FIND_QUIETLY TRUE)
|
||||
endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
|
||||
|
||||
FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
|
||||
)
|
||||
|
||||
if(LIBSSH2_INCLUDE_DIR)
|
||||
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
|
||||
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
|
||||
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
|
||||
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
|
||||
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
|
||||
|
||||
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
|
||||
endif(LIBSSH2_INCLUDE_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
|
||||
|
||||
MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)
|
@@ -1,21 +0,0 @@
|
||||
# Extension of the standard FindOpenSSL.cmake
|
||||
# Adds OPENSSL_INCLUDE_DIRS and libeay32
|
||||
include("${CMAKE_ROOT}/Modules/FindOpenSSL.cmake")
|
||||
|
||||
# starting 2.8 it is better to use standard modules
|
||||
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
# Bill Hoffman told that libeay32 is necessary for him:
|
||||
find_library(SSL_LIBEAY NAMES libeay32)
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
if(SSL_LIBEAY)
|
||||
list(APPEND OPENSSL_LIBRARIES ${SSL_LIBEAY})
|
||||
else()
|
||||
set(OPENSSL_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
endif() # if (CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
|
||||
if(OPENSSL_FOUND)
|
||||
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
@@ -1,10 +0,0 @@
|
||||
# Locate zlib
|
||||
include("${CMAKE_ROOT}/Modules/FindZLIB.cmake")
|
||||
|
||||
# starting 2.8 it is better to use standard modules
|
||||
if(CMAKE_MAJOR_VERSION EQUAL "2" AND CMAKE_MINOR_VERSION LESS "8")
|
||||
find_library(ZLIB_LIBRARY_DEBUG NAMES zd zlibd zdlld zlib1d )
|
||||
if(ZLIB_FOUND AND ZLIB_LIBRARY_DEBUG)
|
||||
set( ZLIB_LIBRARIES optimized "${ZLIB_LIBRARY}" debug ${ZLIB_LIBRARY_DEBUG})
|
||||
endif()
|
||||
endif()
|
89
CMake/Macros.cmake
Normal file
89
CMake/Macros.cmake
Normal file
@@ -0,0 +1,89 @@
|
||||
#File defines convenience macros for available feature testing
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
# does, it prepends library to the list.
|
||||
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
||||
${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
|
||||
|
||||
# Check if header file exists and add it to the list.
|
||||
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
|
||||
check_include_file("${FILE}" ${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_INCLUDE_FILE_CONCAT)
|
||||
|
||||
# For other curl specific tests, use this macro.
|
||||
macro(CURL_INTERNAL_TEST CURL_TEST)
|
||||
if("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_compile(${CURL_TEST}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
else(${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
endif(${CURL_TEST})
|
||||
endif("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
|
||||
endmacro(CURL_INTERNAL_TEST)
|
||||
|
||||
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
|
||||
if("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}")
|
||||
if(${CURL_TEST}_COMPILE)
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"There was a problem running this test\n")
|
||||
endif(${CURL_TEST}_COMPILE)
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"\n\n")
|
||||
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
endif("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
|
||||
endmacro(CURL_INTERNAL_TEST_RUN)
|
@@ -21,6 +21,9 @@ if(HAVE_WINDOWS_H)
|
||||
set(EXTRA_DEFINES ${EXTRA_DEFINES}
|
||||
"__unused7\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n#define __unused3")
|
||||
set(signature_call_conv "PASCAL")
|
||||
if(HAVE_LIBWS2_32)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
||||
endif()
|
||||
else(HAVE_WINDOWS_H)
|
||||
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
|
||||
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
|
||||
|
331
CMakeLists.txt
331
CMakeLists.txt
@@ -38,9 +38,10 @@
|
||||
# To check:
|
||||
# (From Daniel Stenberg) The cmake build selected to run gcc with -fPIC on my box while the plain configure script did not.
|
||||
# (From Daniel Stenberg) The gcc command line use neither -g nor any -O options. As a developer, I also treasure our configure scripts's --enable-debug option that sets a long range of "picky" compiler options.
|
||||
cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
|
||||
include(Utilities)
|
||||
include(Macros)
|
||||
|
||||
project( CURL C )
|
||||
|
||||
@@ -133,6 +134,19 @@ mark_as_advanced(CURL_DISABLE_HTTP)
|
||||
option(CURL_DISABLE_LDAPS "to disable LDAPS" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_LDAPS)
|
||||
|
||||
option(CURL_DISABLE_RTSP "to disable RTSP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_RTSP)
|
||||
option(CURL_DISABLE_PROXY "to disable proxy" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_PROXY)
|
||||
option(CURL_DISABLE_POP3 "to disable POP3" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_POP3)
|
||||
option(CURL_DISABLE_IMAP "to disable IMAP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_IMAP)
|
||||
option(CURL_DISABLE_SMTP "to disable SMTP" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_SMTP)
|
||||
option(CURL_DISABLE_GOPHER "to disable Gopher" OFF)
|
||||
mark_as_advanced(CURL_DISABLE_GOPHER)
|
||||
|
||||
if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_FTP ON)
|
||||
set(CURL_DISABLE_LDAP ON)
|
||||
@@ -141,6 +155,11 @@ if(HTTP_ONLY)
|
||||
set(CURL_DISABLE_DICT ON)
|
||||
set(CURL_DISABLE_FILE ON)
|
||||
set(CURL_DISABLE_TFTP ON)
|
||||
set(CURL_DISABLE_RTSP ON)
|
||||
set(CURL_DISABLE_POP3 ON)
|
||||
set(CURL_DISABLE_IMAP ON)
|
||||
set(CURL_DISABLE_SMTP ON)
|
||||
set(CURL_DISABLE_GOPHER ON)
|
||||
endif()
|
||||
|
||||
option(CURL_DISABLE_COOKIES "to disable cookies support" OFF)
|
||||
@@ -177,22 +196,13 @@ include (CheckIncludeFiles)
|
||||
include (CheckLibraryExists)
|
||||
include (CheckSymbolExists)
|
||||
include (CheckTypeSize)
|
||||
include (CheckCSourceCompiles)
|
||||
|
||||
# On windows preload settings
|
||||
if(WIN32)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
|
||||
endif(WIN32)
|
||||
|
||||
# This macro checks if the symbol exists in the library and if it
|
||||
# does, it prepends library to the list.
|
||||
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
|
||||
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
|
||||
${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
|
||||
|
||||
# Check for all needed libraries
|
||||
check_library_exists_concat("dl" dlopen HAVE_LIBDL)
|
||||
check_library_exists_concat("socket" connect HAVE_LIBSOCKET)
|
||||
@@ -209,37 +219,120 @@ if(NOT NOT_NEED_LIBNSL)
|
||||
check_library_exists_concat("nsl" gethostbyname HAVE_LIBNSL)
|
||||
endif(NOT NOT_NEED_LIBNSL)
|
||||
|
||||
check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32)
|
||||
check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
|
||||
check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
|
||||
|
||||
if(WIN32)
|
||||
set(CURL_DEFAULT_DISABLE_LDAP OFF)
|
||||
# some windows compilers do not have wldap32
|
||||
if(NOT HAVE_WLDAP32)
|
||||
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
|
||||
message(STATUS "wldap32 not found CURL_DISABLE_LDAP set ON")
|
||||
option(CURL_LDAP_WIN "Use Windows LDAP implementation" OFF)
|
||||
else()
|
||||
option(CURL_LDAP_WIN "Use Windows LDAP implementation" ON)
|
||||
endif()
|
||||
mark_as_advanced(CURL_LDAP_WIN)
|
||||
check_library_exists_concat("ws2_32" getch HAVE_LIBWS2_32)
|
||||
check_library_exists_concat("winmm" getch HAVE_LIBWINMM)
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_LDAP)
|
||||
|
||||
# IF(NOT CURL_SPECIAL_LIBZ)
|
||||
# CHECK_LIBRARY_EXISTS_CONCAT("z" inflateEnd HAVE_LIBZ)
|
||||
# ENDIF(NOT CURL_SPECIAL_LIBZ)
|
||||
if(WIN32)
|
||||
option(CURL_LDAP_WIN "Use Windows LDAP implementation" ON)
|
||||
if(CURL_LDAP_WIN)
|
||||
check_library_exists("wldap32" cldap_open "" HAVE_WLDAP32)
|
||||
if(NOT HAVE_WLDAP32)
|
||||
set(CURL_LDAP_WIN OFF)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CMAKE_USE_OPENLDAP "Use OpenLDAP code." OFF)
|
||||
mark_as_advanced(CMAKE_USE_OPENLDAP)
|
||||
set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
|
||||
set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
|
||||
|
||||
if(CMAKE_USE_OPENLDAP AND CURL_LDAP_WIN)
|
||||
message(FATAL_ERROR "Cannot use CURL_LDAP_WIN and CMAKE_USE_OPENLDAP at the same time")
|
||||
endif()
|
||||
|
||||
# Now that we know, we're not using windows LDAP...
|
||||
if(NOT CURL_LDAP_WIN)
|
||||
# Check for LDAP
|
||||
check_library_exists_concat(${CMAKE_LDAP_LIB} ldap_init HAVE_LIBLDAP)
|
||||
check_library_exists_concat(${CMAKE_LBER_LIB} ber_init HAVE_LIBLBER)
|
||||
else()
|
||||
check_include_file_concat("winldap.h" HAVE_WINLDAP_H)
|
||||
check_include_file_concat("winber.h" HAVE_WINBER_H)
|
||||
endif()
|
||||
|
||||
set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
|
||||
if(CMAKE_LDAP_INCLUDE_DIR)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
|
||||
endif()
|
||||
check_include_file_concat("ldap.h" HAVE_LDAP_H)
|
||||
check_include_file_concat("lber.h" HAVE_LBER_H)
|
||||
|
||||
if(NOT HAVE_LDAP_H)
|
||||
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
|
||||
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
|
||||
elseif(NOT HAVE_LIBLDAP)
|
||||
message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
|
||||
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
|
||||
else()
|
||||
if(CMAKE_USE_OPENLDAP)
|
||||
set(USE_OPENLDAP ON)
|
||||
endif()
|
||||
if(CMAKE_LDAP_INCLUDE_DIR)
|
||||
include_directories(${CMAKE_LDAP_INCLUDE_DIR})
|
||||
endif()
|
||||
set(NEED_LBER_H ON)
|
||||
set(_HEADER_LIST)
|
||||
if(HAVE_WINDOWS_H)
|
||||
list(APPEND _HEADER_LIST "windows.h")
|
||||
endif()
|
||||
if(HAVE_SYS_TYPES_H)
|
||||
list(APPEND _HEADER_LIST "sys/types.h")
|
||||
endif()
|
||||
list(APPEND _HEADER_LIST "ldap.h")
|
||||
|
||||
set(_SRC_STRING "")
|
||||
foreach(_HEADER ${_HEADER_LIST})
|
||||
set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
|
||||
endforeach()
|
||||
|
||||
set(_SRC_STRING
|
||||
"
|
||||
${_INCLUDE_STRING}
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
BerValue *bvp = NULL;
|
||||
BerElement *bep = ber_init(bvp);
|
||||
ber_free(bep, 1);
|
||||
return 0;
|
||||
}"
|
||||
)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "-DLDAP_DEPRECATED=1" "-DWIN32_LEAN_AND_MEAN")
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
|
||||
if(HAVE_LIBLBER)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
|
||||
endif()
|
||||
check_c_source_compiles("${_SRC_STRING}" NOT_NEED_LBER_H)
|
||||
|
||||
if(NOT_NEED_LBER_H)
|
||||
set(NEED_LBER_H OFF)
|
||||
else()
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# No ldap, no ldaps.
|
||||
if(CURL_DISABLE_LDAP)
|
||||
if(NOT CURL_DISABLE_LDAPS)
|
||||
message(STATUS "LDAP needs to be enabled to support LDAPS")
|
||||
set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CURL_DISABLE_LDAPS)
|
||||
check_include_file_concat("ldap_ssl.h" HAVE_LDAP_SSL_H)
|
||||
check_include_file_concat("ldapssl.h" HAVE_LDAPSSL_H)
|
||||
endif()
|
||||
|
||||
# Check for idn
|
||||
check_library_exists_concat("idn" idna_to_ascii_lz HAVE_LIBIDN)
|
||||
|
||||
# Check for LDAP
|
||||
check_library_exists_concat("ldap" ldap_init HAVE_LIBLDAP)
|
||||
# if(NOT HAVE_LIBLDAP)
|
||||
# SET(CURL_DISABLE_LDAP ON)
|
||||
# endif(NOT HAVE_LIBLDAP)
|
||||
|
||||
# Check for symbol dlopen (same as HAVE_LIBDL)
|
||||
check_library_exists("${CURL_LIBS}" dlopen "" HAVE_DLOPEN)
|
||||
|
||||
@@ -250,7 +343,7 @@ option(CURL_ZLIB "Set to ON to enable building cURL with zlib support." ON)
|
||||
set(HAVE_LIBZ OFF)
|
||||
set(HAVE_ZLIB_H OFF)
|
||||
set(HAVE_ZLIB OFF)
|
||||
if(CURL_ZLIB) # AND CURL_CONFIG_HAS_BEEN_RUN_BEFORE
|
||||
if(CURL_ZLIB)
|
||||
find_package(ZLIB QUIET)
|
||||
if(ZLIB_FOUND)
|
||||
set(HAVE_ZLIB_H ON)
|
||||
@@ -262,37 +355,70 @@ endif()
|
||||
|
||||
option(CMAKE_USE_OPENSSL "Use OpenSSL code. Experimental" ON)
|
||||
mark_as_advanced(CMAKE_USE_OPENSSL)
|
||||
|
||||
set(USE_SSLEAY OFF)
|
||||
set(USE_OPENSSL OFF)
|
||||
set(HAVE_LIBCRYPTO OFF)
|
||||
set(HAVE_LIBSSL OFF)
|
||||
|
||||
if(CMAKE_USE_OPENSSL)
|
||||
|
||||
set(USE_SSLEAY OFF)
|
||||
set(USE_OPENSSL OFF)
|
||||
set(HAVE_LIBCRYPTO OFF)
|
||||
set(HAVE_LIBSSL OFF)
|
||||
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
set(USE_SSLEAY ON)
|
||||
set(USE_OPENSSL ON)
|
||||
set(HAVE_LIBCRYPTO ON)
|
||||
set(HAVE_LIBSSL ON)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||
check_include_file_concat("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
|
||||
check_include_file_concat("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
|
||||
check_include_file_concat("openssl/err.h" HAVE_OPENSSL_ERR_H)
|
||||
check_include_file_concat("openssl/pem.h" HAVE_OPENSSL_PEM_H)
|
||||
check_include_file_concat("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
|
||||
check_include_file_concat("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
|
||||
check_include_file_concat("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
|
||||
check_include_file_concat("openssl/x509.h" HAVE_OPENSSL_X509_H)
|
||||
check_include_file_concat("openssl/rand.h" HAVE_OPENSSL_RAND_H)
|
||||
endif(OPENSSL_FOUND)
|
||||
endif(CMAKE_USE_OPENSSL)
|
||||
|
||||
#libSSH2
|
||||
option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON)
|
||||
mark_as_advanced(CMAKE_USE_LIBSSH2)
|
||||
set(USE_LIBSSH2 OFF)
|
||||
set(HAVE_LIBSSH2 OFF)
|
||||
set(HAVE_LIBSSH2_H OFF)
|
||||
|
||||
if(CMAKE_USE_LIBSSH2)
|
||||
find_package(LibSSH2)
|
||||
if(LIBSSH2_FOUND)
|
||||
list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBRARY})
|
||||
set(CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
|
||||
set(HAVE_LIBSSH2 ON)
|
||||
set(USE_LIBSSH2 ON)
|
||||
|
||||
# find_package has already found the headers
|
||||
set(HAVE_LIBSSH2_H ON)
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} "${LIBSSH2_INCLUDE_DIR}/libssh2.h")
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DHAVE_LIBSSH2_H")
|
||||
|
||||
# now check for specific libssh2 symbols as they were added in different versions
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "libssh2.h")
|
||||
check_function_exists(libssh2_version HAVE_LIBSSH2_VERSION)
|
||||
check_function_exists(libssh2_init HAVE_LIBSSH2_INIT)
|
||||
check_function_exists(libssh2_exit HAVE_LIBSSH2_EXIT)
|
||||
check_function_exists(libssh2_scp_send64 HAVE_LIBSSH2_SCP_SEND64)
|
||||
check_function_exists(libssh2_session_handshake HAVE_LIBSSH2_SESSION_HANDSHAKE)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "")
|
||||
|
||||
endif(LIBSSH2_FOUND)
|
||||
endif(CMAKE_USE_LIBSSH2)
|
||||
|
||||
# If we have features.h, then do the _BSD_SOURCE magic
|
||||
check_include_file("features.h" HAVE_FEATURES_H)
|
||||
|
||||
# Check if header file exists and add it to the list.
|
||||
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
|
||||
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
|
||||
if(${VARIABLE})
|
||||
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
|
||||
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
|
||||
endif(${VARIABLE})
|
||||
endmacro(CHECK_INCLUDE_FILE_CONCAT)
|
||||
|
||||
|
||||
# Check for header files
|
||||
if(NOT UNIX)
|
||||
check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H)
|
||||
@@ -336,24 +462,13 @@ check_include_file_concat("ifaddrs.h" HAVE_IFADDRS_H)
|
||||
check_include_file_concat("io.h" HAVE_IO_H)
|
||||
check_include_file_concat("krb.h" HAVE_KRB_H)
|
||||
check_include_file_concat("libgen.h" HAVE_LIBGEN_H)
|
||||
check_include_file_concat("libssh2.h" HAVE_LIBSSH2_H)
|
||||
check_include_file_concat("limits.h" HAVE_LIMITS_H)
|
||||
check_include_file_concat("locale.h" HAVE_LOCALE_H)
|
||||
check_include_file_concat("net/if.h" HAVE_NET_IF_H)
|
||||
check_include_file_concat("netdb.h" HAVE_NETDB_H)
|
||||
check_include_file_concat("netinet/in.h" HAVE_NETINET_IN_H)
|
||||
check_include_file_concat("netinet/tcp.h" HAVE_NETINET_TCP_H)
|
||||
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
|
||||
check_include_file_concat("openssl/crypto.h" HAVE_OPENSSL_CRYPTO_H)
|
||||
check_include_file_concat("openssl/engine.h" HAVE_OPENSSL_ENGINE_H)
|
||||
check_include_file_concat("openssl/err.h" HAVE_OPENSSL_ERR_H)
|
||||
check_include_file_concat("openssl/pem.h" HAVE_OPENSSL_PEM_H)
|
||||
check_include_file_concat("openssl/pkcs12.h" HAVE_OPENSSL_PKCS12_H)
|
||||
check_include_file_concat("openssl/rsa.h" HAVE_OPENSSL_RSA_H)
|
||||
check_include_file_concat("openssl/ssl.h" HAVE_OPENSSL_SSL_H)
|
||||
check_include_file_concat("openssl/x509.h" HAVE_OPENSSL_X509_H)
|
||||
check_include_file_concat("openssl/rand.h" HAVE_OPENSSL_RAND_H)
|
||||
endif(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
|
||||
|
||||
check_include_file_concat("pem.h" HAVE_PEM_H)
|
||||
check_include_file_concat("poll.h" HAVE_POLL_H)
|
||||
check_include_file_concat("pwd.h" HAVE_PWD_H)
|
||||
@@ -382,25 +497,13 @@ check_include_file_concat("stddef.h" HAVE_STDDEF_H)
|
||||
check_include_file_concat("dlfcn.h" HAVE_DLFCN_H)
|
||||
check_include_file_concat("malloc.h" HAVE_MALLOC_H)
|
||||
check_include_file_concat("memory.h" HAVE_MEMORY_H)
|
||||
check_include_file_concat("ldap.h" HAVE_LDAP_H)
|
||||
check_include_file_concat("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H)
|
||||
check_include_file_concat("stdint.h" HAVE_STDINT_H)
|
||||
check_include_file_concat("sockio.h" HAVE_SOCKIO_H)
|
||||
check_include_file_concat("sys/utsname.h" HAVE_SYS_UTSNAME_H)
|
||||
check_include_file_concat("idna.h" HAVE_IDNA_H)
|
||||
|
||||
if(NOT HAVE_LDAP_H)
|
||||
message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
|
||||
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
# No ldap, no ldaps.
|
||||
if(CURL_DISABLE_LDAP)
|
||||
if(NOT CURL_DISABLE_LDAPS)
|
||||
message(STATUS "LDAP needs to be enabled to support LDAPS")
|
||||
set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_type_size(size_t SIZEOF_SIZE_T)
|
||||
check_type_size(ssize_t SIZEOF_SSIZE_T)
|
||||
@@ -574,76 +677,12 @@ if(NOT HAVE_STRICMP)
|
||||
set(HAVE_LDAP_URL_PARSE 1)
|
||||
endif(NOT HAVE_STRICMP)
|
||||
|
||||
# For other curl specific tests, use this macro.
|
||||
macro(CURL_INTERNAL_TEST CURL_TEST)
|
||||
if("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_compile(${CURL_TEST}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
else(${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}\n")
|
||||
endif(${CURL_TEST})
|
||||
endif("${CURL_TEST}" MATCHES "^${CURL_TEST}$")
|
||||
endmacro(CURL_INTERNAL_TEST)
|
||||
|
||||
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
|
||||
if("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
|
||||
set(MACRO_CHECK_FUNCTION_DEFINITIONS
|
||||
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CURL_TEST_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST}")
|
||||
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
|
||||
"${CURL_TEST_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
|
||||
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
|
||||
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
|
||||
"${OUTPUT}")
|
||||
if(${CURL_TEST}_COMPILE)
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"There was a problem running this test\n")
|
||||
endif(${CURL_TEST}_COMPILE)
|
||||
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
|
||||
"\n\n")
|
||||
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
|
||||
endif("${CURL_TEST}_COMPILE" MATCHES "^${CURL_TEST}_COMPILE$")
|
||||
endmacro(CURL_INTERNAL_TEST_RUN)
|
||||
|
||||
# Do curl specific tests
|
||||
if(HAVE_LIBWS2_32)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
|
||||
endif()
|
||||
foreach(CURL_TEST
|
||||
HAVE_FCNTL_O_NONBLOCK
|
||||
HAVE_IOCTLSOCKET
|
||||
@@ -835,14 +874,14 @@ endif(MSVC)
|
||||
function(SETUP_CURL_DEPENDENCIES TARGET_NAME)
|
||||
if(CURL_ZLIB AND ZLIB_FOUND)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
#ADD_DEFINITIONS( -DHAVE_ZLIB_H -DHAVE_ZLIB -DHAVE_LIBZ )
|
||||
endif()
|
||||
|
||||
if(CMAKE_USE_OPENSSL AND OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
if(CMAKE_USE_OPENSSL AND CURL_CONFIG_HAS_BEEN_RUN_BEFORE)
|
||||
#ADD_DEFINITIONS( -DUSE_SSLEAY )
|
||||
|
||||
if(CMAKE_USE_LIBSSH2 AND LIBSSH2_FOUND)
|
||||
include_directories(${LIBSSH2_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET_NAME} ${CURL_LIBS})
|
||||
|
@@ -24,10 +24,9 @@ AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
|
||||
CMake/CurlCheckCSourceCompiles.cmake CMake/CurlCheckCSourceRuns.cmake \
|
||||
CMake/CurlTests.c CMake/FindOpenSSL.cmake CMake/FindZLIB.cmake \
|
||||
CMake/OtherTests.cmake CMake/Platforms/WindowsCache.cmake \
|
||||
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
|
||||
CMake/CurlCheckCSourceCompiles.cmake CMake/CurlCheckCSourceRuns.cmake \
|
||||
CMake/CurlTests.c CMake/OtherTests.cmake CMake/Platforms/WindowsCache.cmake \
|
||||
CMake/Utilities.cmake include/curl/curlbuild.h.cmake
|
||||
|
||||
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
|
||||
|
186
RELEASE-NOTES
186
RELEASE-NOTES
@@ -1,67 +1,92 @@
|
||||
Curl and libcurl 7.37.1
|
||||
Curl and libcurl 7.38.0
|
||||
|
||||
Public curl releases: 140
|
||||
Public curl releases: 141
|
||||
Command line options: 162
|
||||
curl_easy_setopt() options: 208
|
||||
Public functions in libcurl: 58
|
||||
Contributors: 1155
|
||||
Contributors: 1216
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o bits.close: introduce connection close tracking
|
||||
o darwinssl: Add support for --cacert
|
||||
o polarssl: add ALPN support
|
||||
o docs: Added new option man pages
|
||||
o CURLE_HTTP2 is a new error code
|
||||
o CURLAUTH_NEGOTIATE is a new auth define
|
||||
o CURL_VERSION_GSSAPI is a new capability bit
|
||||
o no longer use fbopenssl for anything
|
||||
o schannel: use CryptGenRandom for random numbers
|
||||
o axtls: define curlssl_random using axTLS's PRNG
|
||||
o cyassl: use RNG_GenerateBlock to generate a good random number
|
||||
o findprotocol: show unsupported protocol within quotes
|
||||
o version: detect and show LibreSSL
|
||||
o version: detect and show BoringSSL
|
||||
o imap/pop3/smtp: Kerberos (SASL GSSAPI) authentication via Windows SSPI
|
||||
o http2: requires nghttp2 0.6.0 or later
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o build: Fixed incorrect reference to curl_setup.h in Visual Studio files
|
||||
o build: Use $(TargetDir) and $(TargetName) macros for .pdb and .lib output
|
||||
o curl.1: clarify that -u can't specify a user with colon [1]
|
||||
o openssl: Fix uninitialized variable use in NPN callback
|
||||
o curl_easy_reset: reset the URL [2]
|
||||
o curl_version_info.3: returns a pointer to a static struct
|
||||
o url-parser: only use if_nametoindex if detected by configure [3]
|
||||
o select: with winsock, avoid passing unsupported arguments to select() [4]
|
||||
o gnutls: don't use deprecated type names anymore
|
||||
o gnutls: allow building with nghttp2 but without ALPN support
|
||||
o tests: Fix portability issue with the tftpd server
|
||||
o curl_sasl_sspi: Fixed corrupt hostname in DIGEST-MD5 SPN
|
||||
o curl_sasl: extended native DIGEST-MD5 cnonce to be a 32-byte hex string
|
||||
o random: use Curl_rand() for proper random data [5]
|
||||
o Curl_ossl_init: call OPENSSL_config for initing engines [6]
|
||||
o config-win32.h: Updated for VC12 [7]
|
||||
o winbuild: Don't USE_WINSSL when WITH_SSL is being used
|
||||
o getinfo: HTTP CONNECT code not reset between transfers [8]
|
||||
o Curl_rand: Use a fake entropy for debug builds when CURL_ENTROPY set
|
||||
o http2: avoid segfault when using the plain-text http2
|
||||
o conncache: move the connection counter to the cache struct
|
||||
o http2: better return code error checking
|
||||
o curlbuild: fix GCC build on SPARC systems without configure script
|
||||
o tool_metalink: Support polarssl as digest provider
|
||||
o curl.h: reverse the enum/define setup for old symbols
|
||||
o curl.h: moved two really old deprecated symbols
|
||||
o curl.h: renamed CURLOPT_DEPRECATEDx to CURLOPT_OBSOLETEx
|
||||
o buildconf: do not search tools in current directory.
|
||||
o OS400: make it compilable again. Make RPG binding up to date
|
||||
o nss: do not abort on connection failure (failing tests 305 and 404)
|
||||
o nss: make the fallback to SSLv3 work again
|
||||
o tool: prevent valgrind from reporting possibly lost memory (nss only)
|
||||
o progress callback: skip last callback update on errors [9]
|
||||
o nss: fix a memory leak when CURLOPT_CRLFILE is used
|
||||
o compiler warnings: potentially uninitialized variables [10]
|
||||
o url.c: Fixed memory leak on OOM
|
||||
o gnutls: ignore invalid certificate dates with VERIFYPEER disabled
|
||||
o gnutls: fix SRP support with versions of GnuTLS from 2.99.0
|
||||
o gnutls: fixed a couple of uninitialized variable references
|
||||
o gnutls: fixed compilation against versions < 2.12.0
|
||||
o build: Fixed overridden compiler PDB settings in VC7 to VC12
|
||||
o ntlm_wb: Fixed buffer size not being large enough for NTLMv2 sessions [11]
|
||||
o netrc: don't abort if home dir cannot be found
|
||||
o netrc: fixed thread safety problem by using getpwuid_r if available
|
||||
o cookie: avoid mutex deadlock [12]
|
||||
o configure: respect host tool prefix for krb5-config
|
||||
o gnutls: handle IP address in cert name check
|
||||
o CVE-2014-3613: cookie leak with IP address as domain [25]
|
||||
o CVE-2014-3620: cookie leak for TLDs [26]
|
||||
|
||||
o fix a build failure on Debian when NSS support is enabled [1]
|
||||
o HTTP/2: fixed compiler warnings when built disabled [2]
|
||||
o cyassl: return the correct error code on no CA cert
|
||||
o http: Deprecate GSS-Negotiate macros due to bad naming
|
||||
o http: Fixed Negotiate: authentication
|
||||
o multi: Improve proxy CONNECT performance (regression) [3]
|
||||
o ntlm_wb: Avoid invoking ntlm_auth helper with empty username
|
||||
o ntlm_wb: Fix hard-coded limit on NTLM auth packet size
|
||||
o url.c: use the preferred symbol name: *READDATA [4]
|
||||
o smtp: fixed a segfault during test 1320 torture test
|
||||
o cyassl: made it compile with version 2.0.6 again
|
||||
o nss: do not check the version of NSS at run time
|
||||
o c-ares: fix build without IPv6 support [5]
|
||||
o HTTP/2: use base64url encoding [6]
|
||||
o SSPI Negotiate: Fix 3 memory leaks
|
||||
o libtest: fixed duplicated line in Makefile [7]
|
||||
o conncache: fix compiler warning [8]
|
||||
o openssl: make ossl_send return CURLE_OK better
|
||||
o HTTP/2: Support expect: 100-continue
|
||||
o HTTP/2: Fix infinite loop in readwrite_data()
|
||||
o parsedate: fix the return code for an overflow edge condition
|
||||
o darwinssl: don't use strtok()
|
||||
o http_negotiate_sspi: Fixed specific username and password not working [9]
|
||||
o openssl: replace call to OPENSSL_config [10]
|
||||
o http2: show the received header for better debugging
|
||||
o HTTP/2: Move :authority before non-pseudo header fields
|
||||
o HTTP/2: Reset promised stream, not its associated stream
|
||||
o HTTP/2: added some more logging for debugging stream problems
|
||||
o ntlm: Added support for SSPI package info query
|
||||
o ntlm: Fixed hard coded buffer for SSPI based auth packet generation
|
||||
o sasl_sspi: Fixed memory leak with not releasing Package Info struct
|
||||
o sasl_sspi: Fixed SPN not being converted to wchar under Unicode builds
|
||||
o sasl: Use a dynamic buffer for DIGEST-MD5 SPN generation
|
||||
o http_negotiate_sspi: Use a dynamic buffer for SPN generation
|
||||
o sasl_sspi: Fixed missing free of challenge buffer on SPN failure
|
||||
o sasl_sspi: Fixed hard coded buffer for response generation
|
||||
o Curl_poll + Curl_wait_ms: fix timeout return value
|
||||
o docs/SSLCERTS: update the section about NSS database
|
||||
o create_conn: prune dead connections [11]
|
||||
o openssl: fix version report for the 0.9.8 branch
|
||||
o mk-ca-bundle.pl: switched to using hg.mozilla.org [12]
|
||||
o http: fix the Content-Range: parser [13]
|
||||
o Curl_disconnect: don't free the URL [14]
|
||||
o win32: Fixed WinSock 2 #if [15]
|
||||
o NTLM: ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth
|
||||
o curl.1: clarify --limit-rate's effect on both directions [16]
|
||||
o disconnect: don't touch easy-related state on disconnects [17]
|
||||
o Cmake: big cleanup and numerous fixes
|
||||
o HTTP/2: supports draft-14 - moved :headers before the non-psuedo headers
|
||||
o HTTP/2: Reset promised stream, not its associated stream
|
||||
o configure.ac: Add support for recent GSS-API implementations for HP-UX
|
||||
o CONNECT: close proxy connections that fail [18]
|
||||
o CURLOPT_NOBODY.3: clarify this option is for downloads [19]
|
||||
o darwinssl: fix CA certificate checking using PEM format [20]
|
||||
o resolve: cache lookup for async resolvers [21]
|
||||
o low-speed-limit: avoid timeout flood [22]
|
||||
o polarssl: implement CURLOPT_SSLVERSION [23]
|
||||
o multi: convert CURLM_STATE_CONNECT_PEND handling to a list [24]
|
||||
o curl_multi_cleanup: remove superfluous NULL assigns
|
||||
o polarssl: support CURLOPT_CAPATH / --capath
|
||||
o progress: size_dl/size_ul are always >= 0, and clear "KNOWN" properly
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -70,26 +95,43 @@ 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:
|
||||
|
||||
Alessandro Ghedini, Brad Spencer, Chris Young, Colin Hogben, Dan Fandrich,
|
||||
Daniel Stenberg, David Woodhouse, Dimitrios Siganos, Fabian Frank,
|
||||
Glen A Johnson Jr., Hubert Kario, Jeff Pohlmeyer, Jonathan Cardoso Machado,
|
||||
Kamil Dudka, Lindley French, Marcel Raad, Michał Górny, Nick Zitzmann,
|
||||
Patrick Monnerat, Ray Satiro, Steve Holme, Tatsuhiro Tsujikawa,
|
||||
Vilmos Nebehaj, Yousuke Kimoto, Dmitry Falko
|
||||
Alessandro Ghedini, Andre Heinecke, Anthon Pang, Askar Safin, Brandon Casey,
|
||||
Catalin Patulea, Dan Fandrich, Daniel Stenberg, Dave Reisner, David Meyer,
|
||||
David Shaw, David Woodhouse, Dimitrios Siganos, Ed Morley, Fabian Keil,
|
||||
Florian Weimer, Frank Gevaerts, Frank Meier, Haris Okanovic, Jakub Zakrzewski,
|
||||
Jan Ehrhardt, John Coffey, Jonatan Vela, Jose Alf, Kamil Dudka,
|
||||
Leonardo Rosati, Marcel Raad, Michael Osipov, Michael Wallner, Paras S,
|
||||
Patrick Monnerat, Paul Saab, Peter Wang, Rafaël Carré, Sergey Nikulov,
|
||||
Spork Schivago, Steve Holme, Tatsuhiro Tsujikawa, Tim Ruehsen, Toby Peterson,
|
||||
Vilmos Nebehaj,
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
References to bug reports and discussions on issues:
|
||||
|
||||
[1] = http://curl.haxx.se/bug/view.cgi?id=1375
|
||||
[2] = http://curl.haxx.se/mail/lib-2014-05/0235.html
|
||||
[3] = http://curl.haxx.se/mail/lib-2014-05/0260.html
|
||||
[4] = http://curl.haxx.se/mail/lib-2014-05/0278.html
|
||||
[5] = http://curl.haxx.se/mail/lib-2014-06/0001.html
|
||||
[6] = http://curl.haxx.se/mail/lib-2014-06/0003.html
|
||||
[7] = http://curl.haxx.se/bug/view.cgi?id=1378
|
||||
[8] = http://curl.haxx.se/bug/view.cgi?id=1380
|
||||
[9] = http://curl.haxx.se/mail/lib-2014-06/0062.html
|
||||
[10] = http://curl.haxx.se/bug/view.cgi?id=1391
|
||||
[11] = http://curl.haxx.se/mail/lib-2014-07/0103.html
|
||||
[12] = http://curl.haxx.se/mail/lib-2014-02/0184.html
|
||||
[1] = http://curl.haxx.se/mail/lib-2014-07/0209.html
|
||||
[2] = http://curl.haxx.se/mail/lib-2014-07/0202.html
|
||||
[3] = http://curl.haxx.se/bug/view.cgi?id=1397
|
||||
[4] = http://curl.haxx.se/bug/view.cgi?id=1398
|
||||
[5] = http://curl.haxx.se/mail/lib-2014-07/0337.html
|
||||
[6] = https://github.com/tatsuhiro-t/nghttp2/issues/62
|
||||
[7] = https://github.com/bagder/curl/pull/105
|
||||
[8] = http://curl.haxx.se/bug/view.cgi?id=1399
|
||||
[9] = http://curl.haxx.se/mail/lib-2014-06/0224.html
|
||||
[10] = http://curl.haxx.se/bug/view.cgi?id=1401
|
||||
[11] = http://curl.haxx.se/mail/lib-2014-06/0189.html
|
||||
[12] = http://curl.haxx.se/bug/view.cgi?id=1409
|
||||
[13] = http://curl.haxx.se/mail/lib-2014-06/0221.html
|
||||
[14] = http://curl.haxx.se/mail/lib-2014-08/0148.html
|
||||
[15] = http://curl.haxx.se/mail/lib-2014-08/0155.html
|
||||
[16] = http://curl.haxx.se/bug/view.cgi?id=1414
|
||||
[17] = http://curl.haxx.se/mail/lib-2014-08/0148.html
|
||||
[18] = http://curl.haxx.se/bug/view.cgi?id=1381
|
||||
[19] = http://curl.haxx.se/mail/lib-2014-08/0236.html
|
||||
[20] = https://github.com/bagder/curl/pull/115
|
||||
[21] = https://github.com/bagder/curl/pull/112
|
||||
[22] = http://curl.haxx.se/mail/lib-2014-06/0235.html
|
||||
[23] = http://curl.haxx.se/bug/view.cgi?id=1419
|
||||
[24] = http://curl.haxx.se/mail/lib-2014-07/0206.html
|
||||
[25] = http://curl.haxx.se/docs/adv_20140910A.html
|
||||
[26] = http://curl.haxx.se/docs/adv_20140910B.html
|
||||
|
88
configure.ac
88
configure.ac
@@ -151,7 +151,6 @@ dnl initialize all the info variables
|
||||
curl_ssh_msg="no (--with-libssh2)"
|
||||
curl_zlib_msg="no (--with-zlib)"
|
||||
curl_gss_msg="no (--with-gssapi)"
|
||||
curl_spnego_msg="no (--with-spnego)"
|
||||
curl_tls_srp_msg="no (--enable-tls-srp)"
|
||||
curl_res_msg="default (--enable-ares / --enable-threaded-resolver)"
|
||||
curl_ipv6_msg="no (--enable-ipv6)"
|
||||
@@ -1134,41 +1133,6 @@ no)
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for FBopenssl(SPNEGO) libraries
|
||||
dnl **********************************************************************
|
||||
|
||||
AC_ARG_WITH(spnego,
|
||||
AC_HELP_STRING([--with-spnego=DIR],
|
||||
[Specify location of SPNEGO library fbopenssl]), [
|
||||
SPNEGO_ROOT="$withval"
|
||||
if test x"$SPNEGO_ROOT" != xno; then
|
||||
want_spnego="yes"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([if SPNEGO support is requested])
|
||||
if test x"$want_spnego" = xyes; then
|
||||
|
||||
if test X"$SPNEGO_ROOT" = Xyes; then
|
||||
AC_MSG_ERROR([FBOpenSSL libs and/or directories were not found where specified!])
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
if test -z "$SPNEGO_LIB_DIR"; then
|
||||
LDFLAGS="$LDFLAGS -L$SPNEGO_ROOT -lfbopenssl"
|
||||
else
|
||||
LDFLAGS="$LDFLAGS $SPNEGO_LIB_DIR"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SPNEGO, 1,
|
||||
[Define this if you have the SPNEGO library fbopenssl])
|
||||
curl_spnego_msg="enabled"
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for GSS-API libraries
|
||||
dnl **********************************************************************
|
||||
@@ -1284,7 +1248,7 @@ else
|
||||
fi
|
||||
if test x"$want_gss" = xyes; then
|
||||
AC_DEFINE(HAVE_GSSAPI, 1, [if you have GSS-API libraries])
|
||||
|
||||
HAVE_GSSAPI=1
|
||||
curl_gss_msg="enabled (MIT Kerberos/Heimdal)"
|
||||
|
||||
if test -n "$gnu_gss"; then
|
||||
@@ -1296,12 +1260,6 @@ if test x"$want_gss" = xyes; then
|
||||
*-*-darwin*)
|
||||
LIBS="-lgssapi_krb5 -lresolv $LIBS"
|
||||
;;
|
||||
*-hp-hpux*)
|
||||
if test "$GSSAPI_ROOT" != "yes"; then
|
||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
|
||||
fi
|
||||
LIBS="-lgss $LIBS"
|
||||
;;
|
||||
*)
|
||||
if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then
|
||||
dnl krb5-config doesn't have --libs-only-L or similar, put everything
|
||||
@@ -1313,11 +1271,22 @@ if test x"$want_gss" = xyes; then
|
||||
dnl into LIBS
|
||||
gss_libs=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
|
||||
LIBS="$gss_libs $LIBS"
|
||||
elif test "$GSSAPI_ROOT" != "yes"; then
|
||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
|
||||
LIBS="-lgssapi $LIBS"
|
||||
else
|
||||
LIBS="-lgssapi $LIBS"
|
||||
case $host in
|
||||
*-hp-hpux*)
|
||||
gss_libname="gss"
|
||||
;;
|
||||
*)
|
||||
gss_libname="gssapi"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$GSSAPI_ROOT" != "yes"; then
|
||||
LDFLAGS="$LDFLAGS -L$GSSAPI_ROOT/lib$libsuff"
|
||||
LIBS="-l$gss_libname $LIBS"
|
||||
else
|
||||
LIBS="-l$gss_libname $LIBS"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -2114,6 +2083,10 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
||||
if test "x$USE_NSS" = "xyes"; then
|
||||
AC_MSG_NOTICE([detected NSS version $version])
|
||||
|
||||
dnl needed when linking the curl tool without USE_EXPLICIT_LIB_DEPS
|
||||
NSS_LIBS=$addlib
|
||||
AC_SUBST([NSS_LIBS])
|
||||
|
||||
dnl when shared libs were found in a path that the run-time
|
||||
dnl linker doesn't search through, we need to add it to
|
||||
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
|
||||
@@ -2787,7 +2760,7 @@ if test X"$want_h2" != Xno; then
|
||||
CPPFLAGS="$CPPFLAGS $CPP_H2"
|
||||
LIBS="$LIB_H2 $LIBS"
|
||||
|
||||
AC_CHECK_LIB(nghttp2, nghttp2_session_client_new,
|
||||
AC_CHECK_LIB(nghttp2, nghttp2_session_callbacks_set_send_callback,
|
||||
[
|
||||
AC_CHECK_HEADERS(nghttp2/nghttp2.h,
|
||||
curl_h2_msg="enabled (nghttp2)"
|
||||
@@ -3388,8 +3361,18 @@ fi
|
||||
if test "x$USE_WINDOWS_SSPI" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES SSPI"
|
||||
fi
|
||||
|
||||
if test "x$HAVE_GSSAPI" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API"
|
||||
fi
|
||||
|
||||
if test "x$CURL_DISABLE_CRYPTO_AUTH" != "x1" -a \
|
||||
\( "x$HAVE_GSSAPI" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \); then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO"
|
||||
fi
|
||||
|
||||
if test "x$CURL_DISABLE_HTTP" != "x1" -a \
|
||||
"x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then
|
||||
"x$CURL_DISABLE_CRYPTO_AUTH" != "x1"; then
|
||||
if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
|
||||
-o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1" \
|
||||
-o "x$DARWINSSL_ENABLED" = "x1"; then
|
||||
@@ -3406,12 +3389,6 @@ fi
|
||||
if test "x$USE_NGHTTP2" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES HTTP2"
|
||||
fi
|
||||
if test "x$curl_spnego_msg" = "xenabled"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES SPNEGO"
|
||||
fi
|
||||
if test "x$want_gss" = "xyes"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES GSS-API"
|
||||
fi
|
||||
|
||||
AC_SUBST(SUPPORT_FEATURES)
|
||||
|
||||
@@ -3560,7 +3537,6 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||
SSH support: ${curl_ssh_msg}
|
||||
zlib support: ${curl_zlib_msg}
|
||||
GSS-API support: ${curl_gss_msg}
|
||||
SPNEGO support: ${curl_spnego_msg}
|
||||
TLS-SRP support: ${curl_tls_srp_msg}
|
||||
resolver: ${curl_res_msg}
|
||||
ipv6 support: ${curl_ipv6_msg}
|
||||
|
@@ -39,12 +39,12 @@ fi
|
||||
# sort all unique names
|
||||
# awk them into RELEASE-NOTES format
|
||||
git log $start..HEAD | \
|
||||
egrep '(Author|Commit|by):' | \
|
||||
egrep -i '(Author|Commit|by):' | \
|
||||
cut -d: -f2- | \
|
||||
cut '-d<' -f1 | \
|
||||
sed -e 's/^ //' -e 's/ $//g' | \
|
||||
grep ' ' | \
|
||||
sort -u |
|
||||
sort -fu |
|
||||
awk '{
|
||||
num++;
|
||||
n = sprintf("%s%s%s,", n, length(n)?" ":"", $0);
|
||||
|
39
docs/FAQ
39
docs/FAQ
@@ -80,6 +80,7 @@ FAQ
|
||||
4.17 Non-functional connect timeouts on Windows
|
||||
4.18 file:// URLs containing drive letters (Windows, NetWare)
|
||||
4.19 Why doesn't cURL return an error when the network cable is unplugged?
|
||||
4.20 curl doesn't return error for HTTP non-200 responses!
|
||||
|
||||
5. libcurl Issues
|
||||
5.1 Is libcurl thread-safe?
|
||||
@@ -136,11 +137,11 @@ FAQ
|
||||
POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP.
|
||||
|
||||
libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading,
|
||||
kerberos, HTTP form based upload, proxies, cookies, user+password
|
||||
Kerberos, SPNEGO, HTTP form based upload, proxies, cookies, user+password
|
||||
authentication, file transfer resume, http proxy tunneling and more!
|
||||
|
||||
libcurl is highly portable, it builds and works identically on numerous
|
||||
platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX,
|
||||
platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HP-UX,
|
||||
IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOS, Mac
|
||||
OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS, Symbian, OSF,
|
||||
Android, Minix, IBM TPF and more...
|
||||
@@ -238,10 +239,10 @@ FAQ
|
||||
1.6 What do you get for making curl?
|
||||
|
||||
Project cURL is entirely free and open. No person gets paid for developing
|
||||
(lib)curl on full or even part time. We do this voluntarily on our spare
|
||||
time. Occasionally companies pay individual developers to work on curl, but
|
||||
that's up to each company and developer. It is not controlled by nor
|
||||
supervised in any way by the project.
|
||||
curl on full time. We do this voluntarily, mostly on spare time.
|
||||
Occasionally companies pay individual developers to work on curl, but that's
|
||||
up to each company and developer. It is not controlled by nor supervised in
|
||||
any way by the project.
|
||||
|
||||
We still get help from companies. Haxx provides web site, bandwidth, mailing
|
||||
lists etc, sourceforge.net hosts project services we take advantage from,
|
||||
@@ -1086,7 +1087,31 @@ FAQ
|
||||
immediately if its lone network connection goes down. That can be achieved
|
||||
by having the application monitor the network connection on its own using an
|
||||
OS-specific mechanism, then signalling libcurl to abort (see also item 5.13).
|
||||
|
||||
|
||||
4.20 curl doesn't return error for HTTP non-200 responses!
|
||||
|
||||
Correct. Unless you use -f (--fail).
|
||||
|
||||
When doing HTTP transfers, curl will perform exactly what you're asking it
|
||||
to do and if successful it will not return an error. You can use curl to
|
||||
test your web server's "file not found" page (that gets 404 back), you can
|
||||
use it to check your authentication protected web pages (that get a 401
|
||||
back) and so on.
|
||||
|
||||
The specific HTTP response code does not constitute a problem or error for
|
||||
curl. It simply sends and delivers HTTP as you asked and if that worked,
|
||||
everything is fine and dandy. The response code is generally providing more
|
||||
higher level error information that curl doesn't care about. The error was
|
||||
not in the HTTP transfer.
|
||||
|
||||
If you want your command line to treat error codes in the 400 and up range
|
||||
as errors and thus return a non-zero value and possibly show an error
|
||||
message, curl has a dedicated option for that: -f (CURLOPT_FAILONERROR in
|
||||
libcurl speak).
|
||||
|
||||
You can also use the -w option and the variable %{response_code} to extract
|
||||
the exact response code that was return in the response.
|
||||
|
||||
|
||||
5. libcurl Issues
|
||||
|
||||
|
@@ -28,7 +28,7 @@ libcurl
|
||||
- selectable network interface for outgoing traffic
|
||||
- IPv6 support on unix and Windows
|
||||
- persistent connections
|
||||
- socks5 support
|
||||
- socks 4 + 5 support, with or without local name resolving
|
||||
- supports user name and password in proxy environment variables
|
||||
- operations through proxy "tunnel" (using CONNECT)
|
||||
- support for large files (>2GB and >4GB) during upload and download
|
||||
@@ -45,8 +45,8 @@ HTTP
|
||||
- POST
|
||||
- Pipelining
|
||||
- multipart formpost (RFC1867-style)
|
||||
- authentication: Basic, Digest, NTLM (*9), GSS-Negotiate/Negotiate (*3) and
|
||||
SPNEGO (*4) to server and proxy
|
||||
- authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3)
|
||||
to server and proxy
|
||||
- resume (both GET and PUT)
|
||||
- follow redirects
|
||||
- maximum amount of redirects to follow
|
||||
@@ -64,6 +64,7 @@ HTTP
|
||||
- Content-Encoding support for deflate and gzip
|
||||
- "Transfer-Encoding: chunked" support in uploads
|
||||
- data compression (*12)
|
||||
- HTTP/2 (*4)
|
||||
|
||||
HTTPS (*1)
|
||||
- (all the HTTP features)
|
||||
@@ -77,7 +78,7 @@ FTP
|
||||
- download
|
||||
- authentication
|
||||
- kerberos4 (*5)
|
||||
- kerberos5 (*3)
|
||||
- Kerberos 5 (*14)
|
||||
- active/passive using PORT, EPRT, PASV or EPSV
|
||||
- single file size information (compare to HTTP HEAD)
|
||||
- 'type=' URL support
|
||||
@@ -179,8 +180,9 @@ FOOTNOTES
|
||||
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native
|
||||
Windows), Secure Transport (native iOS/OS X) or qssl (native IBM i)
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar
|
||||
*4 = requires FBopenssl
|
||||
*3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
|
||||
SSPI (native Windows)
|
||||
*4 = requires nghttp2 and possibly a recent TLS library
|
||||
*5 = requires a krb4 library, such as the MIT one or similar
|
||||
*6 = requires c-ares
|
||||
*7 = requires OpenSSL, NSS, qssl, WinSSL or Secure Transport; GnuTLS, for
|
||||
@@ -194,3 +196,4 @@ FOOTNOTES
|
||||
*12 = requires libz
|
||||
*13 = requires libmetalink, and either an Apple or Microsoft operating
|
||||
system, or OpenSSL, or GnuTLS, or NSS
|
||||
*14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos)
|
||||
|
253
docs/HISTORY
253
docs/HISTORY
@@ -4,23 +4,31 @@
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
How cURL Became Like This
|
||||
How cURL Became Like This
|
||||
=========================
|
||||
|
||||
|
||||
Towards the end of 1996, Daniel Stenberg came up with the idea to make
|
||||
Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot
|
||||
for an Amiga related channel on EFnet. He then came up with the idea to make
|
||||
currency-exchange calculations available to Internet Relay Chat (IRC)
|
||||
users. All the necessary data are published on the Web; he just needed to
|
||||
automate their retrieval.
|
||||
|
||||
Daniel simply adopted an existing command-line open-source tool, httpget, that
|
||||
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
|
||||
a few minor adjustments, it did just what he needed. HttpGet 1.0 was released
|
||||
on April 8th 1997 with brand new HTTP proxy support.
|
||||
a few minor adjustments, it did just what he needed.
|
||||
|
||||
1997
|
||||
----
|
||||
|
||||
HttpGet 1.0 was released on April 8th 1997 with brand new HTTP proxy support.
|
||||
|
||||
We soon found and fixed support for getting currencies over GOPHER. Once FTP
|
||||
download support was added, the name of the project was changed and urlget 2.0
|
||||
was released in August 1997. The http-only days were already passed.
|
||||
|
||||
1998
|
||||
----
|
||||
|
||||
The project slowly grew bigger. When upload capabilities were added and the
|
||||
name once again was misleading, a second name change was made and on March 20,
|
||||
1998 curl 4 was released. (The version numbering from the previous names was
|
||||
@@ -33,33 +41,39 @@ was revealed to us much later.)
|
||||
|
||||
SSL support was added, powered by the SSLeay library.
|
||||
|
||||
August 1998, first announcement of curl on freshmeat.net.
|
||||
August, first announcement of curl on freshmeat.net.
|
||||
|
||||
October 1998, with the curl 4.9 release and the introduction of cookie
|
||||
support, curl was no longer released under the GPL license. Now we're at 4000
|
||||
lines of code, we switched over to the MPL license to restrict the effects of
|
||||
October, with the curl 4.9 release and the introduction of cookie support,
|
||||
curl was no longer released under the GPL license. Now we're at 4000 lines of
|
||||
code, we switched over to the MPL license to restrict the effects of
|
||||
"copyleft".
|
||||
|
||||
November 1998, configure script and reported successful compiles on several
|
||||
November, configure script and reported successful compiles on several
|
||||
major operating systems. The never-quite-understood -F option was added and
|
||||
curl could now simulate quite a lot of a browser. TELNET support was added.
|
||||
|
||||
Curl 5 was released in December 1998 and introduced the first ever curl man
|
||||
page. People started making Linux RPM packages out of it.
|
||||
|
||||
January 1999, DICT support added.
|
||||
1999
|
||||
----
|
||||
|
||||
January, DICT support added.
|
||||
|
||||
OpenSSL took over where SSLeay was abandoned.
|
||||
|
||||
May 1999, first Debian package.
|
||||
May, first Debian package.
|
||||
|
||||
August 1999, LDAP:// and FILE:// support added. The curl web site gets 1300
|
||||
visits weekly.
|
||||
August, LDAP:// and FILE:// support added. The curl web site gets 1300 visits
|
||||
weekly.
|
||||
|
||||
Released curl 6.0 in September. 15000 lines of code.
|
||||
|
||||
December 28 1999, added the project on Sourceforge and started using its
|
||||
services for managing the project.
|
||||
December 28, added the project on Sourceforge and started using its services
|
||||
for managing the project.
|
||||
|
||||
2000
|
||||
----
|
||||
|
||||
Spring 2000, major internal overhaul to provide a suitable library interface.
|
||||
The first non-beta release was named 7.1 and arrived in August. This offered
|
||||
@@ -67,19 +81,22 @@ the easy interface and turned out to be the beginning of actually getting
|
||||
other software and programs to get based on and powered by libcurl. Almost
|
||||
20000 lines of code.
|
||||
|
||||
August 2000, the curl web site gets 4000 visits weekly.
|
||||
August, the curl web site gets 4000 visits weekly.
|
||||
|
||||
The PHP guys adopted libcurl already the same month, when the first ever third
|
||||
party libcurl binding showed up. CURL has been a supported module in PHP since
|
||||
the release of PHP 4.0.2. This would soon get followers. More than 16
|
||||
different bindings exist at the time of this writing.
|
||||
|
||||
September 2000, kerberos4 support was added.
|
||||
September, kerberos4 support was added.
|
||||
|
||||
In November 2000 started the work on a test suite for curl. It was later
|
||||
re-written from scratch again. The libcurl major SONAME number was set to 1.
|
||||
In November started the work on a test suite for curl. It was later re-written
|
||||
from scratch again. The libcurl major SONAME number was set to 1.
|
||||
|
||||
January 2001, Daniel released curl 7.5.2 under a new license again: MIT (or
|
||||
2001
|
||||
----
|
||||
|
||||
January, Daniel released curl 7.5.2 under a new license again: MIT (or
|
||||
MPL). The MIT license is extremely liberal and can be used combined with GPL
|
||||
in other projects. This would finally put an end to the "complaints" from
|
||||
people involved in GPLed projects that previously were prohibited from using
|
||||
@@ -92,17 +109,20 @@ code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
|
||||
|
||||
The first experimental ftps:// support was added in March 2001.
|
||||
|
||||
August 2001. curl is bundled in Mac OS X, 10.1. It was already becoming more
|
||||
and more of a standard utility of Linux distributions and a regular in the BSD
|
||||
August. curl is bundled in Mac OS X, 10.1. It was already becoming more and
|
||||
more of a standard utility of Linux distributions and a regular in the BSD
|
||||
ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
|
||||
contacted Daniel to discuss "the name issue". After Daniel's reply, they have
|
||||
never since got in touch again.
|
||||
|
||||
September 2001, libcurl 7.9 introduces cookie jar and curl_formadd(). During
|
||||
the forthcoming 7.9.x releases, we introduced the multi interface slowly and
|
||||
September, libcurl 7.9 introduces cookie jar and curl_formadd(). During the
|
||||
forthcoming 7.9.x releases, we introduced the multi interface slowly and
|
||||
without much whistles.
|
||||
|
||||
June 2002, the curl web site gets 13000 visits weekly. curl and libcurl is
|
||||
2002
|
||||
----
|
||||
|
||||
June, the curl web site gets 13000 visits weekly. curl and libcurl is
|
||||
35000 lines of code. Reported successful compiles on more than 40 combinations
|
||||
of CPUs and operating systems.
|
||||
|
||||
@@ -111,134 +131,145 @@ impossible. Around 5000 downloaded packages each week from the main site gives
|
||||
a hint, but the packages are mirrored extensively, bundled with numerous OS
|
||||
distributions and otherwise retrieved as part of other software.
|
||||
|
||||
September 2002, with the release of curl 7.10 it is released under the MIT
|
||||
license only.
|
||||
September, with the release of curl 7.10 it is released under the MIT license
|
||||
only.
|
||||
|
||||
January 2003. Started working on the distributed curl tests. The autobuilds.
|
||||
2003
|
||||
----
|
||||
|
||||
February 2003, the curl site averages at 20000 visits weekly. At any given
|
||||
moment, there's an average of 3 people browsing the curl.haxx.se site.
|
||||
January. Started working on the distributed curl tests. The autobuilds.
|
||||
|
||||
February, the curl site averages at 20000 visits weekly. At any given moment,
|
||||
there's an average of 3 people browsing the curl.haxx.se site.
|
||||
|
||||
Multiple new authentication schemes are supported: Digest (May), NTLM (June)
|
||||
and Negotiate (June).
|
||||
|
||||
November 2003: curl 7.10.8 is released. 45000 lines of code. ~55000 unique
|
||||
visitors to the curl.haxx.se site. Five official web mirrors.
|
||||
November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors
|
||||
to the curl.haxx.se site. Five official web mirrors.
|
||||
|
||||
December 2003, full-fledged SSL for FTP is supported.
|
||||
December, full-fledged SSL for FTP is supported.
|
||||
|
||||
January 2004: curl 7.11.0 introduced large file support.
|
||||
2004
|
||||
----
|
||||
|
||||
June 2004:
|
||||
January: curl 7.11.0 introduced large file support.
|
||||
|
||||
curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
June: curl 7.12.0 introduced IDN support. 10 official web mirrors.
|
||||
|
||||
This release bumped the major SONAME to 3 due to the removal of the
|
||||
curl_formparse() function
|
||||
This release bumped the major SONAME to 3 due to the removal of the
|
||||
curl_formparse() function
|
||||
|
||||
August 2004:
|
||||
Curl and libcurl 7.12.1
|
||||
August: Curl and libcurl 7.12.1
|
||||
|
||||
Public curl release number: 82
|
||||
Releases counted from the very beginning: 109
|
||||
Available command line options: 96
|
||||
Available curl_easy_setopt() options: 120
|
||||
Number of public functions in libcurl: 36
|
||||
Amount of public web site mirrors: 12
|
||||
Number of known libcurl bindings: 26
|
||||
Public curl release number: 82
|
||||
Releases counted from the very beginning: 109
|
||||
Available command line options: 96
|
||||
Available curl_easy_setopt() options: 120
|
||||
Number of public functions in libcurl: 36
|
||||
Amount of public web site mirrors: 12
|
||||
Number of known libcurl bindings: 26
|
||||
|
||||
April 2005:
|
||||
2005
|
||||
----
|
||||
|
||||
GnuTLS can now optionally be used for the secure layer when curl is built.
|
||||
April. GnuTLS can now optionally be used for the secure layer when curl is
|
||||
built.
|
||||
|
||||
September 2005:
|
||||
September: TFTP support was added.
|
||||
|
||||
TFTP support was added.
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
|
||||
More than 100,000 unique visitors of the curl web site. 25 mirrors.
|
||||
December: security vulnerability: libcurl URL Buffer Overflow
|
||||
|
||||
December 2005:
|
||||
2006
|
||||
----
|
||||
|
||||
security vulnerability: libcurl URL Buffer Overflow
|
||||
January. We dropped support for Gopher. We found bugs in the implementation
|
||||
that turned out having been introduced years ago, so with the conclusion that
|
||||
nobody had found out in all this time we removed it instead of fixing it.
|
||||
|
||||
January 2006:
|
||||
March: security vulnerability: libcurl TFTP Packet Buffer Overflow
|
||||
|
||||
We dropped support for Gopher. We found bugs in the implementation that
|
||||
turned out having been introduced years ago, so with the conclusion that
|
||||
nobody had found out in all this time we removed it instead of fixing it.
|
||||
April: Added the multi_socket() API
|
||||
|
||||
March 2006:
|
||||
September: The major SONAME number for libcurl was bumped to 4 due to the
|
||||
removal of ftp third party transfer support.
|
||||
|
||||
security vulnerability: libcurl TFTP Packet Buffer Overflow
|
||||
November: Added SCP and SFTP support
|
||||
|
||||
April 2006:
|
||||
2007
|
||||
----
|
||||
|
||||
Added the multi_socket() API
|
||||
February: Added support for the Mozilla NSS library to do the SSL/TLS stuff
|
||||
|
||||
September 2006:
|
||||
July: security vulnerability: libcurl GnuTLS insufficient cert verification
|
||||
|
||||
The major SONAME number for libcurl was bumped to 4 due to the removal of
|
||||
ftp third party transfer support.
|
||||
2008
|
||||
----
|
||||
|
||||
November 2006:
|
||||
November:
|
||||
|
||||
Added SCP and SFTP support
|
||||
|
||||
February 2007:
|
||||
|
||||
Added support for the Mozilla NSS library to do the SSL/TLS stuff
|
||||
|
||||
July 2007:
|
||||
|
||||
security vulnerability: libcurl GnuTLS insufficient cert verification
|
||||
|
||||
November 2008:
|
||||
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 683
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 158
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 37
|
||||
Contributors: 683
|
||||
|
||||
145,000 unique visitors. >100 GB downloaded.
|
||||
|
||||
March 2009:
|
||||
2009
|
||||
----
|
||||
|
||||
security vulnerability: libcurl Arbitrary File Access
|
||||
March: security vulnerability: libcurl Arbitrary File Access
|
||||
|
||||
August 2009:
|
||||
August: security vulnerability: libcurl embedded zero in cert name
|
||||
|
||||
security vulnerability: libcurl embedded zero in cert name
|
||||
December: Added support for IMAP, POP3 and SMTP
|
||||
|
||||
December 2009:
|
||||
2010
|
||||
----
|
||||
|
||||
Added support for IMAP, POP3 and SMTP
|
||||
January: Added support for RTSP
|
||||
|
||||
January 2010:
|
||||
February: security vulnerability: libcurl data callback excessive length
|
||||
|
||||
Added support for RTSP
|
||||
March: The project switched over to use git (hosted by github) instead of CVS
|
||||
for source code control
|
||||
|
||||
February 2010:
|
||||
May: Added support for RTMP
|
||||
|
||||
security vulnerability: libcurl data callback excessive length
|
||||
Added support for PolarSSL to do the SSL/TLS stuff
|
||||
|
||||
March 2010:
|
||||
August:
|
||||
|
||||
The project switched over to use git instead of CVS for source code control
|
||||
|
||||
May 2010:
|
||||
|
||||
Added support for RTMP
|
||||
|
||||
Added support for PolarSSL to do the SSL/TLS stuff
|
||||
|
||||
August 2010:
|
||||
|
||||
Public curl releases: 117
|
||||
Command line options: 138
|
||||
curl_easy_setopt() options: 180
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 808
|
||||
Public curl releases: 117
|
||||
Command line options: 138
|
||||
curl_easy_setopt() options: 180
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 808
|
||||
|
||||
Gopher support added (re-added actually)
|
||||
|
||||
2012
|
||||
----
|
||||
|
||||
July: Added support for Schannel (native Windows TLS backend) and Darwin SSL
|
||||
(Native Mac OS X and iOS TLS backend).
|
||||
|
||||
Supports metalink
|
||||
|
||||
October: SSH-agent support.
|
||||
|
||||
2013
|
||||
----
|
||||
|
||||
February: Cleaned up internals to always uses the "multi" non-blocking
|
||||
approach internally and only expose the blocking API with a wrapper.
|
||||
|
||||
September: First small steps on supporting HTTP/2 with nghttp2.
|
||||
|
||||
October: Removed krb4 support.
|
||||
|
||||
December: Happy eyeballs.
|
||||
|
@@ -47,6 +47,7 @@ Portability
|
||||
axTLS 1.2.7
|
||||
PolarSSL 1.3.0
|
||||
Heimdal ?
|
||||
nghttp2 0.6.0
|
||||
|
||||
On systems where configure runs, we aim at working on them all - if they have
|
||||
a suitable C compiler. On systems that don't run configure, we strive to keep
|
||||
|
@@ -51,10 +51,6 @@ may have been fixed since this was written!
|
||||
any file at all. Like when using FTP.
|
||||
http://curl.haxx.se/bug/view.cgi?id=1063
|
||||
|
||||
77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
|
||||
"abuses" the underlying connection re-use system and if connections are
|
||||
forced to close they break the NTLM support.
|
||||
|
||||
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
|
||||
that platform), and long is only 32 bits. It makes it impossible for
|
||||
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
|
||||
@@ -216,9 +212,9 @@ may have been fixed since this was written!
|
||||
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
|
||||
phase).
|
||||
|
||||
10. To get HTTP Negotiate authentication to work fine, you need to provide a
|
||||
(fake) user name (this concerns both curl and the lib) because the code
|
||||
wrongly only considers authentication if there's a user name provided.
|
||||
10. To get HTTP Negotiate (SPNEGO) authentication to work fine, you need to
|
||||
provide a (fake) user name (this concerns both curl and the lib) because the
|
||||
code wrongly only considers authentication if there's a user name provided.
|
||||
http://curl.haxx.se/bug/view.cgi?id=440 How?
|
||||
http://curl.haxx.se/mail/lib-2004-08/0182.html
|
||||
|
||||
|
@@ -94,12 +94,6 @@ GNU GSS http://www.gnu.org/software/gss/
|
||||
may not distribute binary curl packages that uses this if you build
|
||||
curl to also link and use any Original BSD licensed libraries!
|
||||
|
||||
fbopenssl
|
||||
|
||||
(Used for SPNEGO support) Unclear license. Based on its name, I assume
|
||||
that it uses the OpenSSL license and thus shares the same issues as
|
||||
described for OpenSSL above.
|
||||
|
||||
libidn http://josefsson.org/libidn/
|
||||
|
||||
(Used for IDNA support) Uses the GNU Lesser General Public
|
||||
|
@@ -14,6 +14,7 @@ MAIL ETIQUETTE
|
||||
1.5 Moderation of new posters
|
||||
1.6 Handling trolls and spam
|
||||
1.7 How to unsubscribe
|
||||
1.8 I posted, now what?
|
||||
|
||||
2. Sending mail
|
||||
2.1 Reply or New Mail
|
||||
@@ -125,6 +126,42 @@ MAIL ETIQUETTE
|
||||
You NEVER EVER email the mailing list requesting someone else to get you off
|
||||
the list.
|
||||
|
||||
1.8 I posted, now what?
|
||||
|
||||
If you aren't subscribed with the exact same email address that you used to
|
||||
send the email, your post will just be silently discarded.
|
||||
|
||||
If you posted for the first time to the mailing list, you first need to wait
|
||||
for an administrator to allow your email to go through. This normally
|
||||
happens very quickly but in case we're asleep, you may have to wait a few
|
||||
hours.
|
||||
|
||||
Once your email goes through it is sent out to several hundred or even
|
||||
thousand recipients. Your email may cover an area that not that many people
|
||||
know about or are interested in. Or possibly the person who knows about it
|
||||
is on vacation or under a very heavy work load right now. You have to wait
|
||||
for a response and you must not expect to get a response at all, but
|
||||
hopefully you get an answer within a couple of days.
|
||||
|
||||
You do yourself and all of us a service when you include as many details as
|
||||
possible already in your first email. Mention your operating system and
|
||||
environment. Tell us which curl version you're using and tell us what you
|
||||
did, what happened and what you expected would happen. Preferably, show us
|
||||
what you did in details enough to allow others to help point out the problem
|
||||
or repeat the same steps in their places.
|
||||
|
||||
Failing to include details will only delay responses and make people respond
|
||||
and ask for the details and you have to send a follow-up email that includes
|
||||
them.
|
||||
|
||||
Expect the responses to primarily help YOU debug the issue, or ask you
|
||||
questions that can lead you or others towards a solution or explanation to
|
||||
whatever you experience.
|
||||
|
||||
If you are a repeat offender to the guidelines outlined in this document,
|
||||
chances are that people will ignore you at will and your chances to get
|
||||
responses will greatly diminish.
|
||||
|
||||
|
||||
2. Sending mail
|
||||
|
||||
|
@@ -108,10 +108,10 @@ USING PASSWORDS
|
||||
curl -u name:passwd http://machine.domain/full/path/to/file
|
||||
|
||||
HTTP offers many different methods of authentication and curl supports
|
||||
several: Basic, Digest, NTLM and Negotiate. Without telling which method to
|
||||
use, curl defaults to Basic. You can also ask curl to pick the most secure
|
||||
ones out of the ones that the server accepts for the given URL, by using
|
||||
--anyauth.
|
||||
several: Basic, Digest, NTLM and Negotiate (SPNEGO). Without telling which
|
||||
method to use, curl defaults to Basic. You can also ask curl to pick the
|
||||
most secure ones out of the ones that the server accepts for the given URL,
|
||||
by using --anyauth.
|
||||
|
||||
NOTE! According to the URL specification, HTTP URLs can not contain a user
|
||||
and password, so that style will not work when using curl via a proxy, even
|
||||
|
@@ -89,3 +89,15 @@ announcement.
|
||||
mentioned.
|
||||
|
||||
[1] = http://oss-security.openwall.org/wiki/mailing-lists/distros
|
||||
|
||||
CURL-SECURITY (at haxx dot se)
|
||||
|
||||
Who is on this list? There are a couple of criteria you must meet, and then we
|
||||
might ask you to join the list or you can ask to join it. It really isn't very
|
||||
formal. We basically only require that you have a long-term presence in the
|
||||
curl project and you have shown an understanding for the project and its way
|
||||
of working. You must've been around for a good while and you should have no
|
||||
plans in vanishing in the near future.
|
||||
|
||||
We do not make the list of partipants public mostly because it tends to vary
|
||||
somewhat over time and a list somewhere will only risk getting outdated.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Peer SSL Certificate Verification
|
||||
=================================
|
||||
Peer SSL Certificate Verification
|
||||
=================================
|
||||
|
||||
(NOTE: If libcurl was built with Schannel or Secure Transport support, then
|
||||
this does not apply to you. Scroll down for details on how the OS-native
|
||||
@@ -26,13 +26,13 @@ impersonating your favorite site, and you want to transfer files from this
|
||||
server, do one of the following:
|
||||
|
||||
1. Tell libcurl to *not* verify the peer. With libcurl you disable this with
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
`curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);`
|
||||
|
||||
With the curl command line tool, you disable this with -k/--insecure.
|
||||
|
||||
2. Get a CA certificate that can verify the remote server and use the proper
|
||||
option to point out this CA cert for verification when connecting. For
|
||||
libcurl hackers: curl_easy_setopt(curl, CURLOPT_CAPATH, capath);
|
||||
libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);`
|
||||
|
||||
With the curl command line tool: --cacert [file]
|
||||
|
||||
@@ -46,32 +46,32 @@ server, do one of the following:
|
||||
If you use Internet Explorer, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
o View the certificate by double-clicking the padlock
|
||||
o Find out where the CA certificate is kept (Certificate>
|
||||
- View the certificate by double-clicking the padlock
|
||||
- Find out where the CA certificate is kept (Certificate>
|
||||
Authority Information Access>URL)
|
||||
o Get a copy of the crt file using curl
|
||||
o Convert it from crt to PEM using the openssl tool:
|
||||
- Get a copy of the crt file using curl
|
||||
- Convert it from crt to PEM using the openssl tool:
|
||||
openssl x509 -inform DES -in yourdownloaded.crt \
|
||||
-out outcert.pem -text
|
||||
o Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
||||
- Append the 'outcert.pem' to the CA cert bundle or use it stand-alone
|
||||
as described below.
|
||||
|
||||
If you use the 'openssl' tool, this is one way to get extract the CA cert
|
||||
for a particular server:
|
||||
|
||||
o openssl s_client -connect xxxxx.com:443 |tee logfile
|
||||
o type "QUIT", followed by the "ENTER" key
|
||||
o The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
|
||||
- `openssl s_client -connect xxxxx.com:443 |tee logfile`
|
||||
- type "QUIT", followed by the "ENTER" key
|
||||
- The certificate will have "BEGIN CERTIFICATE" and "END CERTIFICATE"
|
||||
markers.
|
||||
o If you want to see the data in the certificate, you can do: "openssl
|
||||
- If you want to see the data in the certificate, you can do: "openssl
|
||||
x509 -inform PEM -in certfile -text -out certdata" where certfile is
|
||||
the cert you extracted from logfile. Look in certdata.
|
||||
o If you want to trust the certificate, you can append it to your
|
||||
cert_bundle or use it stand-alone as described. Just remember that the
|
||||
- If you want to trust the certificate, you can append it to your
|
||||
cert bundle or use it stand-alone as described. Just remember that the
|
||||
security is no better than the way you obtained the certificate.
|
||||
|
||||
4. If you're using the curl command line tool, you can specify your own CA
|
||||
cert path by setting the environment variable CURL_CA_BUNDLE to the path
|
||||
cert path by setting the environment variable `CURL_CA_BUNDLE` to the path
|
||||
of your choice.
|
||||
|
||||
If you're using the curl command line tool on Windows, curl will search
|
||||
@@ -86,9 +86,7 @@ server, do one of the following:
|
||||
5. Get a better/different/newer CA cert bundle! One option is to extract the
|
||||
one a recent Firefox browser uses by running 'make ca-bundle' in the curl
|
||||
build tree root, or possibly download a version that was generated this
|
||||
way for you:
|
||||
|
||||
http://curl.haxx.se/docs/caextract.html
|
||||
way for you: [CA Extract](http://curl.haxx.se/docs/caextract.html)
|
||||
|
||||
Neglecting to use one of the above methods when dealing with a server using a
|
||||
certificate that isn't signed by one of the certificates in the installed CA
|
||||
@@ -96,32 +94,26 @@ cert bundle, will cause SSL to report an error ("certificate verify failed")
|
||||
during the handshake and SSL will then refuse further communication with that
|
||||
server.
|
||||
|
||||
Peer SSL Certificate Verification with NSS
|
||||
==========================================
|
||||
Peer SSL Certificate Verification with NSS
|
||||
==========================================
|
||||
|
||||
If libcurl was built with NSS support, then depending on the OS distribution,
|
||||
it is probably required to take some additional steps to use the system-wide CA
|
||||
cert db. RedHat ships with an additional module, libnsspem.so, which enables
|
||||
NSS to read the OpenSSL PEM CA bundle. This library is missing in OpenSuSE, and
|
||||
without it, NSS can only work with its own internal formats. NSS also has a new
|
||||
database format: https://wiki.mozilla.org/NSS_Shared_DB
|
||||
[database format](https://wiki.mozilla.org/NSS_Shared_DB).
|
||||
|
||||
Starting with version 7.19.7, libcurl will check for the NSS version it runs,
|
||||
and automatically add the 'sql:' prefix to the certdb directory (either the
|
||||
hardcoded default /etc/pki/nssdb or the directory configured with SSL_DIR
|
||||
environment variable) if version 3.12.0 or later is detected. To check which
|
||||
certdb format your distribution provides, examine the default
|
||||
certdb location: /etc/pki/nssdb; the new certdb format can be identified by
|
||||
the filenames cert9.db, key4.db, pkcs11.txt; filenames of older versions are
|
||||
cert8.db, key3.db, modsec.db.
|
||||
Starting with version 7.19.7, libcurl automatically adds the 'sql:' prefix to
|
||||
the certdb directory (either the hardcoded default /etc/pki/nssdb or the
|
||||
directory configured with SSL_DIR environment variable). To check which certdb
|
||||
format your distribution provides, examine the default certdb location:
|
||||
/etc/pki/nssdb; the new certdb format can be identified by the filenames
|
||||
cert9.db, key4.db, pkcs11.txt; filenames of older versions are cert8.db,
|
||||
key3.db, secmod.db.
|
||||
|
||||
Usually these cert databases are empty, but NSS also has built-in CAs which are
|
||||
provided through a shared library, libnssckbi.so; if you want to use these
|
||||
built-in CAs, then create a symlink to libnssckbi.so in /etc/pki/nssdb:
|
||||
ln -s /usr/lib[64]/libnssckbi.so /etc/pki/nssdb/libnssckbi.so
|
||||
|
||||
Peer SSL Certificate Verification with Schannel and Secure Transport
|
||||
====================================================================
|
||||
Peer SSL Certificate Verification with Schannel and Secure Transport
|
||||
====================================================================
|
||||
|
||||
If libcurl was built with Schannel (Microsoft's TLS/SSL engine) or Secure
|
||||
Transport (Apple's TLS/SSL engine) support, then libcurl will still perform
|
||||
|
74
docs/THANKS
74
docs/THANKS
@@ -22,7 +22,7 @@ Alan Pinstein
|
||||
Albert Chin-A-Young
|
||||
Albert Choy
|
||||
Ale Vesely
|
||||
Alejandro Alvarez
|
||||
Alejandro Alvarez Ayllon
|
||||
Aleksandar Milivojevic
|
||||
Aleksey Tulinov
|
||||
Alessandro Ghedini
|
||||
@@ -48,6 +48,7 @@ Alexey Zakhlestin
|
||||
Alexis Carvalho
|
||||
Alfred Gebert
|
||||
Allen Pulsifer
|
||||
Alona Rossen
|
||||
Amol Pattekar
|
||||
Amr Shahin
|
||||
Anatoli Tubman
|
||||
@@ -55,6 +56,7 @@ Anders Gustafsson
|
||||
Anders Havn
|
||||
Andi Jahja
|
||||
Andre Guibert de Bruet
|
||||
Andre Heinecke
|
||||
Andreas Damm
|
||||
Andreas Faerber
|
||||
Andreas Farber
|
||||
@@ -66,6 +68,7 @@ Andreas Schuldei
|
||||
Andreas Wurf
|
||||
Andrei Benea
|
||||
Andrei Cipu
|
||||
Andrei Kurushin
|
||||
Andrej E Baranov
|
||||
Andres Garcia
|
||||
Andrew Benham
|
||||
@@ -83,6 +86,7 @@ Andy Cedilnik
|
||||
Andy Serpa
|
||||
Andy Tsouladze
|
||||
Angus Mackay
|
||||
Anthon Pang
|
||||
Anthony Bryan
|
||||
Anthony G. Basile
|
||||
Antoine Calando
|
||||
@@ -97,6 +101,8 @@ Arnaud Ebalard
|
||||
Arthur Murray
|
||||
Arve Knudsen
|
||||
Arvid Norberg
|
||||
Ask Bjørn Hansen
|
||||
Askar Safin
|
||||
Ates Goral
|
||||
Augustus Saunders
|
||||
Avery Fay
|
||||
@@ -116,6 +122,7 @@ Benbuck Nason
|
||||
Benjamin Gerard
|
||||
Benjamin Gilbert
|
||||
Benjamin Johnson
|
||||
Benoit Neil
|
||||
Benoit Sigoure
|
||||
Bernard Leak
|
||||
Bernhard Reutner-Fischer
|
||||
@@ -138,6 +145,7 @@ Brad Hards
|
||||
Brad King
|
||||
Brad Spencer
|
||||
Bradford Bruce
|
||||
Brandon Casey
|
||||
Brandon Wang
|
||||
Brendan Jurd
|
||||
Brent Beardsley
|
||||
@@ -157,6 +165,7 @@ Camille Moncelier
|
||||
Caolan McNamara
|
||||
Carsten Lange
|
||||
Casey O'Donnell
|
||||
Catalin Patulea
|
||||
Cedric Deltheil
|
||||
Chad Monroe
|
||||
Chandrakant Bagul
|
||||
@@ -173,6 +182,7 @@ Chris Gaukroger
|
||||
Chris Maltby
|
||||
Chris Mumford
|
||||
Chris Smowton
|
||||
Chris Young
|
||||
Christian Grothoff
|
||||
Christian Hägele
|
||||
Christian Krause
|
||||
@@ -195,6 +205,7 @@ Clifford Wolf
|
||||
Cody Jones
|
||||
Cody Mack
|
||||
Colby Ranger
|
||||
Colin Blair
|
||||
Colin Hogben
|
||||
Colin Watson
|
||||
Colm Buckley
|
||||
@@ -254,6 +265,7 @@ David Kimdon
|
||||
David Lang
|
||||
David LeBlanc
|
||||
David McCreedy
|
||||
David Meyer
|
||||
David Odin
|
||||
David Phillips
|
||||
David Rosenstrauch
|
||||
@@ -267,6 +279,7 @@ David Woodhouse
|
||||
David Wright
|
||||
David Yan
|
||||
Dengminwen
|
||||
Dennis Clarke
|
||||
Derek Higgins
|
||||
Detlef Schmier
|
||||
Didier Brisebourg
|
||||
@@ -275,6 +288,7 @@ Dilyan Palauzov
|
||||
Dima Barsky
|
||||
Dima Tisnek
|
||||
Dimitre Dimitrov
|
||||
Dimitrios Siganos
|
||||
Dimitris Sarris
|
||||
Dinar
|
||||
Dirk Eddelbuettel
|
||||
@@ -282,6 +296,7 @@ Dirk Manske
|
||||
Dmitri Shubin
|
||||
Dmitriy Sergeyev
|
||||
Dmitry Bartsevich
|
||||
Dmitry Falko
|
||||
Dmitry Kurochkin
|
||||
Dmitry Popov
|
||||
Dmitry Rechkin
|
||||
@@ -297,13 +312,13 @@ Douglas R. Horner
|
||||
Douglas Steinwand
|
||||
Dov Murik
|
||||
Duane Cathey
|
||||
Duncan
|
||||
Duncan Mac-Vicar Prett
|
||||
Dustin Boswell
|
||||
Dylan Ellicott
|
||||
Dylan Salisbury
|
||||
Early Ehlinger
|
||||
Ebenezer Ikonne
|
||||
Ed Morley
|
||||
Edin Kadribasic
|
||||
Eduard Bloch
|
||||
Edward Rudd
|
||||
@@ -333,8 +348,10 @@ Eric Wong
|
||||
Eric Young
|
||||
Erick Nuwendam
|
||||
Erik Johansson
|
||||
Ernest Beinrohr
|
||||
Erwan Legrand
|
||||
Erwin Authried
|
||||
Ethan Glasser Camp
|
||||
Eugene Kotlyarov
|
||||
Evan Jordan
|
||||
Evgeny Turnaev
|
||||
@@ -348,6 +365,7 @@ Felix Yan
|
||||
Felix von Leitner
|
||||
Feng Tu
|
||||
Florian Schoppmann
|
||||
Florian Weimer
|
||||
Forrest Cahoon
|
||||
Francois Charlier
|
||||
Frank Hempel
|
||||
@@ -357,6 +375,7 @@ Frank Meier
|
||||
Frank Ticheler
|
||||
Frank Van Uffelen
|
||||
František Kučera
|
||||
François Charlier
|
||||
Fred Machado
|
||||
Fred New
|
||||
Fred Noz
|
||||
@@ -390,6 +409,7 @@ Gilles Blanc
|
||||
Gisle Vanem
|
||||
Giuseppe Attardi
|
||||
Giuseppe D'Ambrosio
|
||||
Glen A Johnson Jr.
|
||||
Glen Nakamura
|
||||
Glen Scott
|
||||
Glenn Sheridan
|
||||
@@ -400,14 +420,17 @@ Grant Erickson
|
||||
Greg Hewgill
|
||||
Greg Morse
|
||||
Greg Onufer
|
||||
Greg Pratt
|
||||
Greg Zavertnik
|
||||
Grigory Entin
|
||||
Guenole Bescon
|
||||
Guenter Knauf
|
||||
Guido Berhoerster
|
||||
Guillaume Arluison
|
||||
Gunter Knauf
|
||||
Gustaf Hui
|
||||
Gwenole Beauchesne
|
||||
Gökhan Şengün
|
||||
Götz Babin-Ebell
|
||||
Hamish Mackenzie
|
||||
Hang Kin Lau
|
||||
@@ -416,12 +439,14 @@ Hanno Kranzhoff
|
||||
Hans Steegers
|
||||
Hans-Jurgen May
|
||||
Hardeep Singh
|
||||
Haris Okanovic
|
||||
Harshal Pradhan
|
||||
Hauke Duden
|
||||
He Qin
|
||||
Heikki Korpela
|
||||
Heinrich Ko
|
||||
Heinrich Schaefer
|
||||
Helwing Lutz
|
||||
Hendrik Visage
|
||||
Henrik Storner
|
||||
Henry Ludemann
|
||||
@@ -457,6 +482,7 @@ Jacky Lam
|
||||
Jacob Meuser
|
||||
Jacob Moshenko
|
||||
Jad Chamcham
|
||||
Jakub Zakrzewski
|
||||
James Bursa
|
||||
James Cheng
|
||||
James Clancy
|
||||
@@ -476,6 +502,7 @@ Jan Schaumann
|
||||
Jan Van Boghout
|
||||
Jared Jennings
|
||||
Jared Lundell
|
||||
Jari Aalto
|
||||
Jari Sundell
|
||||
Jason Glasgow
|
||||
Jason Liu
|
||||
@@ -490,7 +517,7 @@ Jean-Claude Chauve
|
||||
Jean-Francois Bertrand
|
||||
Jean-Louis Lemaire
|
||||
Jean-Marc Ranger
|
||||
Jean-Noel Rouvignac
|
||||
Jean-Noël Rouvignac
|
||||
Jean-Philippe Barrette-LaPierre
|
||||
Jeff Connelly
|
||||
Jeff Hodges
|
||||
@@ -500,11 +527,11 @@ Jeff Lawson
|
||||
Jeff Phillips
|
||||
Jeff Pohlmeyer
|
||||
Jeff Weber
|
||||
Jeffrey Pohlmeyer
|
||||
Jeremy Friesner
|
||||
Jeremy Huddleston
|
||||
Jeroen Koekkoek
|
||||
Jerome Muffat-Meridol
|
||||
Jerome Robert
|
||||
Jerome Vouillon
|
||||
Jerry Krinock
|
||||
Jerry Wu
|
||||
@@ -529,7 +556,9 @@ Johan Anderson
|
||||
Johan Nilsson
|
||||
Johan van Selst
|
||||
Johannes Bauer
|
||||
Johannes Ernst
|
||||
John Bradshaw
|
||||
John Coffey
|
||||
John Crow
|
||||
John Dennis
|
||||
John Dunn
|
||||
@@ -540,6 +569,7 @@ John Joseph Bachir
|
||||
John Kelly
|
||||
John Lask
|
||||
John Lightsey
|
||||
John Malmberg
|
||||
John Marino
|
||||
John McGowan
|
||||
John P. McCaskey
|
||||
@@ -556,9 +586,12 @@ Jon Turner
|
||||
Jonas Forsman
|
||||
Jonas Schnelli
|
||||
Jonatan Lander
|
||||
Jonatan Vela
|
||||
Jonathan Cardoso Machado
|
||||
Jonathan Hseu
|
||||
Jonathan Nieder
|
||||
Jongki Suwandi
|
||||
Jose Alf
|
||||
Jose Kahan
|
||||
Josef Wolf
|
||||
Josh Kapell
|
||||
@@ -624,6 +657,7 @@ Lachlan O'Dea
|
||||
Larry Campbell
|
||||
Larry Fahnoe
|
||||
Larry Lin
|
||||
Larry Stone
|
||||
Lars Buitinck
|
||||
Lars Gustafsson
|
||||
Lars J. Aas
|
||||
@@ -639,9 +673,11 @@ Len Krause
|
||||
Lenaic Lefever
|
||||
Lenny Rachitsky
|
||||
Leon Winter
|
||||
Leonardo Rosati
|
||||
Liam Healy
|
||||
Lijo Antony
|
||||
Linas Vepstas
|
||||
Lindley French
|
||||
Ling Thio
|
||||
Linus Nielsen Feltzing
|
||||
Lisa Xu
|
||||
@@ -652,12 +688,14 @@ Loren Kirkby
|
||||
Luca Altea
|
||||
Luca Alteas
|
||||
Lucas Adamski
|
||||
Ludek Finstrle
|
||||
Ludovico Cavedon
|
||||
Lukasz Czekierda
|
||||
Luke Amery
|
||||
Luke Call
|
||||
Luke Dashjr
|
||||
Luong Dinh Dung
|
||||
Lyndon Hill
|
||||
Maciej Karpiuk
|
||||
Maciej Puzio
|
||||
Maciej W. Rozycki
|
||||
@@ -713,6 +751,7 @@ Mateusz Loskot
|
||||
Mathias Axelsson
|
||||
Mats Lidell
|
||||
Matt Arsenault
|
||||
Matt Ford
|
||||
Matt Kraai
|
||||
Matt Veenstra
|
||||
Matt Witherspoon
|
||||
@@ -748,10 +787,12 @@ Michael Stillwell
|
||||
Michael Wallner
|
||||
Michal Bonino
|
||||
Michal Gorny
|
||||
Michal Kowalczyk
|
||||
Michal Marek
|
||||
Michał Górny
|
||||
Michał Kowalczyk
|
||||
Michele Bini
|
||||
Miguel Angel
|
||||
Miguel Diaz
|
||||
Mihai Ionescu
|
||||
Mikael Johansson
|
||||
Mikael Sennerholm
|
||||
@@ -760,12 +801,14 @@ Mike Crowe
|
||||
Mike Dobbs
|
||||
Mike Giancola
|
||||
Mike Hasselberg
|
||||
Mike Henshaw
|
||||
Mike Hommey
|
||||
Mike Mio
|
||||
Mike Power
|
||||
Mike Protts
|
||||
Mike Revi
|
||||
Miklos Nemeth
|
||||
Miroslav Spousta
|
||||
Mitz Wark
|
||||
Mohamed Lrhazi
|
||||
Mohammad AlSaleh
|
||||
@@ -803,11 +846,12 @@ Nodak Sodak
|
||||
Norbert Frese
|
||||
Norbert Novotny
|
||||
Ofer
|
||||
Ola Mork
|
||||
Olaf Flebbe
|
||||
Olaf Stueben
|
||||
Olaf Stüben
|
||||
Oliver Gondža
|
||||
Oliver Kuckertz
|
||||
Oliver Schindler
|
||||
Olivier Berger
|
||||
Oren Tirosh
|
||||
Ori Avtalion
|
||||
@@ -818,10 +862,12 @@ Paolo Piacentini
|
||||
Paras Sethia
|
||||
Pascal Terjan
|
||||
Pasha Kuznetsov
|
||||
Pasi Karkkainen
|
||||
Pat Ray
|
||||
Patrice Guerin
|
||||
Patricia Muscalu
|
||||
Patrick Bihan-Faou
|
||||
Patrick McManus
|
||||
Patrick Monnerat
|
||||
Patrick Scott
|
||||
Patrick Smith
|
||||
@@ -836,6 +882,7 @@ Paul Marquis
|
||||
Paul Moore
|
||||
Paul Nolan
|
||||
Paul Querna
|
||||
Paul Saab
|
||||
Pavel Cenek
|
||||
Pavel Orehov
|
||||
Pavel Raiskup
|
||||
@@ -858,6 +905,7 @@ Peter Su
|
||||
Peter Sylvester
|
||||
Peter Todd
|
||||
Peter Verhas
|
||||
Peter Wang
|
||||
Peter Wullinger
|
||||
Peteris Krumins
|
||||
Petr Bahula
|
||||
@@ -889,6 +937,7 @@ Quinn Slack
|
||||
Radu Simionescu
|
||||
Rafa Muyo
|
||||
Rafael Sagula
|
||||
Rafaël Carré
|
||||
Rainer Canavan
|
||||
Rainer Jung
|
||||
Rainer Koenig
|
||||
@@ -901,6 +950,7 @@ Randy McMurchy
|
||||
Ravi Pratap
|
||||
Ray Dassen
|
||||
Ray Pekowski
|
||||
Ray Satiro
|
||||
Reinout van Schouwen
|
||||
Remi Gacogne
|
||||
Renato Botelho
|
||||
@@ -921,6 +971,7 @@ Richard Clayton
|
||||
Richard Cooper
|
||||
Richard Gorton
|
||||
Richard Michael
|
||||
Richard Moore
|
||||
Richard Prescott
|
||||
Richard Silverman
|
||||
Rick Jones
|
||||
@@ -944,6 +995,7 @@ Robin Johnson
|
||||
Robin Kay
|
||||
Robson Braga Araujo
|
||||
Rodney Simmons
|
||||
Rodric Glaser
|
||||
Rodrigo Silva
|
||||
Roland Blom
|
||||
Roland Krikava
|
||||
@@ -952,6 +1004,7 @@ Rolland Dudemaine
|
||||
Roman Koifman
|
||||
Roman Mamedov
|
||||
Romulo A. Ceccon
|
||||
Ron Parker
|
||||
Ron Zapp
|
||||
Rosimildo da Silva
|
||||
Roy Shan
|
||||
@@ -978,6 +1031,7 @@ Santhana Todatry
|
||||
Saqib Ali
|
||||
Sara Golemon
|
||||
Saran Neti
|
||||
Sascha Swiercy
|
||||
Saul good
|
||||
Scott Bailey
|
||||
Scott Barrett
|
||||
@@ -1008,6 +1062,7 @@ Song Ma
|
||||
Sonia Subramanian
|
||||
Spacen Jasset
|
||||
Spiridonoff A.V
|
||||
Spork Schivago
|
||||
Stadler Stephan
|
||||
Stan van de Burgt
|
||||
Stanislav Ivochkin
|
||||
@@ -1017,6 +1072,7 @@ Stefan Neis
|
||||
Stefan Teleman
|
||||
Stefan Tomanek
|
||||
Stefan Ulrich
|
||||
Steinar H. Gunderson
|
||||
Stephan Bergmann
|
||||
Stephen Collyer
|
||||
Stephen Kick
|
||||
@@ -1036,6 +1092,7 @@ Steven Gu
|
||||
Steven M. Schweda
|
||||
Steven Parkes
|
||||
Stoned Elipot
|
||||
Sune Ahlgren
|
||||
Sven Anders
|
||||
Sven Neuhaus
|
||||
Sven Wegener
|
||||
@@ -1064,6 +1121,7 @@ Tim Harder
|
||||
Tim Heckman
|
||||
Tim Newsome
|
||||
Tim Sneddon
|
||||
Tim Starling
|
||||
Timo Sirainen
|
||||
Tinus van den Berg
|
||||
Tobias Markus
|
||||
@@ -1136,6 +1194,7 @@ Wez Furlong
|
||||
Wilfredo Sanchez
|
||||
Will Dietz
|
||||
Willem Sparreboom
|
||||
William Ahern
|
||||
Wojciech Zwiefka
|
||||
Wouter Van Rooy
|
||||
Wu Yongzheng
|
||||
@@ -1144,10 +1203,12 @@ Yaakov Selkowitz
|
||||
Yamada Yasuharu
|
||||
Yang Tse
|
||||
Yarram Sunil
|
||||
Yasuharu Yamada
|
||||
Yehezkel Horowitz
|
||||
Yehoshua Hershberg
|
||||
Yi Huang
|
||||
Yingwei Liu
|
||||
Yousuke Kimoto
|
||||
Yukihiro Kawada
|
||||
Yuriy Sosov
|
||||
Yves Arrouye
|
||||
@@ -1159,3 +1220,4 @@ Zvi Har'El
|
||||
nk
|
||||
swalkaus at yahoo.com
|
||||
tommink[at]post.pl
|
||||
Никита Дорохин
|
||||
|
23
docs/TODO
23
docs/TODO
@@ -33,6 +33,7 @@
|
||||
4.3 Earlier bad letter detection
|
||||
4.4 REST for large files
|
||||
4.5 ASCII support
|
||||
4.6 GSSAPI via Windows SSPI
|
||||
|
||||
5. HTTP
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
@@ -40,6 +41,7 @@
|
||||
5.3 Rearrange request header order
|
||||
5.4 SPDY
|
||||
5.5 auth= in URLs
|
||||
5.6 Digest via Windows SSPI
|
||||
|
||||
6. TELNET
|
||||
6.1 ditch stdin
|
||||
@@ -80,6 +82,7 @@
|
||||
|
||||
14. SASL
|
||||
14.1 Other authentication mechanisms
|
||||
14.2 GSSAPI via GSS-API libraries
|
||||
|
||||
15. Client
|
||||
15.1 sync
|
||||
@@ -251,6 +254,12 @@
|
||||
FTP ASCII transfers do not follow RFC959. They don't convert the data
|
||||
accordingly.
|
||||
|
||||
4.6 GSSAPI via Windows SSPI
|
||||
|
||||
In addition to currently supporting the SASL GSSAPI mechanism (Kerberos V5)
|
||||
via third-party GSS-API libraries, such as Heimdal or MIT Kerberos, also add
|
||||
support for GSSAPI authentication via Windows SSPI.
|
||||
|
||||
5. HTTP
|
||||
|
||||
5.1 Better persistency for HTTP 1.0
|
||||
@@ -296,6 +305,12 @@
|
||||
|
||||
Additionally this should be implemented for proxy base URLs as well.
|
||||
|
||||
5.6 Digest via Windows SSPI
|
||||
|
||||
libcurl already supports HTTP Digest Authentication via native routines as well
|
||||
as SASL Digest via both Windows SSPI and native routines. In addition to this
|
||||
libcurl should also support HTTP Digest Authentication via Windows SSPI.
|
||||
|
||||
6. TELNET
|
||||
|
||||
6.1 ditch stdin
|
||||
@@ -440,7 +455,13 @@ to provide the data to send.
|
||||
|
||||
14.1 Other authentication mechanisms
|
||||
|
||||
Add support for GSSAPI to SMTP, POP3 and IMAP.
|
||||
Add support for other authentication mechanisms such as EXTERNAL, OLP,
|
||||
GSS-SPNEGO and others.
|
||||
|
||||
14.2 GSSAPI via GSS-API libraries
|
||||
|
||||
Add support for GSSAPI authentication via third-party GSS-API libraries, such
|
||||
as Heimdal and MIT Kerberos.
|
||||
|
||||
15. Client
|
||||
|
||||
|
76
docs/curl.1
76
docs/curl.1
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "27 July 2012" "Curl 7.27.0" "Curl Manual"
|
||||
.TH curl 1 "2 Aug 2014" "Curl 7.38.0" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -699,6 +699,10 @@ See also the \fI-A, --user-agent\fP and \fI-e, --referer\fP options.
|
||||
Starting in 7.37.0, you need \fI--proxy-header\fP to send custom headers
|
||||
intended for a proxy.
|
||||
|
||||
Example:
|
||||
|
||||
\&# curl -H "X-First-Name: Joe" http://192.168.0.1/
|
||||
|
||||
This option can be used multiple times to add/replace/remove multiple headers.
|
||||
.IP "--hostpubmd5 <md5>"
|
||||
(SCP/SFTP) Pass a string containing 32 hexadecimal digits. The string should
|
||||
@@ -827,9 +831,8 @@ If this option is used several times, the last one will be used.
|
||||
should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use
|
||||
a level that is not one of these, 'private' will instead be used.
|
||||
|
||||
This option requires a library built with kerberos4 or GSSAPI
|
||||
(GSS-Negotiate) support. This is not very common. Use \fI-V, --version\fP to
|
||||
see if your curl supports it.
|
||||
This option requires a library built with kerberos4 support. This is not
|
||||
very common. Use \fI-V, --version\fP to see if your curl supports it.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-l, --list-only"
|
||||
@@ -866,6 +869,10 @@ When curl follows a redirect and the request is not a plain GET (for example
|
||||
POST or PUT), it will do the following request with a GET if the HTTP response
|
||||
was 301, 302, or 303. If the response code was any other 3xx code, curl will
|
||||
re-send the following request using the same unmodified method.
|
||||
|
||||
You can tell curl to not change the non-GET request method to GET after a 30x
|
||||
response by using the dedicated options for that: \fI--post301\fP,
|
||||
\fI--post302\fP and \fI-post303\fP.
|
||||
.IP "--libcurl <file>"
|
||||
Append this option to any ordinary curl command line, and you will get a
|
||||
libcurl-using C source code written to the file that does the equivalent
|
||||
@@ -874,9 +881,10 @@ of what your command-line operation does!
|
||||
If this option is used several times, the last given file name will be
|
||||
used. (Added in 7.16.1)
|
||||
.IP "--limit-rate <speed>"
|
||||
Specify the maximum transfer rate you want curl to use. This feature is useful
|
||||
if you have a limited pipe and you'd like your transfer not to use your entire
|
||||
bandwidth.
|
||||
Specify the maximum transfer rate you want curl to use - for both downloads
|
||||
and uploads. This feature is useful if you have a limited pipe and you'd like
|
||||
your transfer not to use your entire bandwidth. To make it slower than it
|
||||
otherwise would be.
|
||||
|
||||
The given speed is measured in bytes/second, unless a suffix is appended.
|
||||
Appending 'k' or 'K' will count the number as kilobytes, 'm' or M' makes it
|
||||
@@ -1024,18 +1032,13 @@ Very similar to \fI--netrc\fP, but this option makes the .netrc usage
|
||||
\fBoptional\fP and not mandatory as the \fI--netrc\fP option does.
|
||||
|
||||
.IP "--negotiate"
|
||||
(HTTP) Enables GSS-Negotiate authentication. The GSS-Negotiate method was
|
||||
designed by Microsoft and is used in their web applications. It is primarily
|
||||
meant as a support for Kerberos5 authentication but may be also used along
|
||||
with another authentication method. For more information see IETF draft
|
||||
draft-brezak-spnego-http-04.txt.
|
||||
(HTTP) Enables Negotiate (SPNEGO) authentication.
|
||||
|
||||
If you want to enable Negotiate for your proxy authentication, then use
|
||||
If you want to enable Negotiate (SPNEGO) for proxy authentication, then use
|
||||
\fI--proxy-negotiate\fP.
|
||||
|
||||
This option requires a library built with GSSAPI support. This is
|
||||
not very common. Use \fI-V, --version\fP to see if your version supports
|
||||
GSS-Negotiate.
|
||||
This option requires a library built with GSS-API or SSPI support. Use \fI-V,
|
||||
--version\fP to see if your curl supports GSS-API/SSPI and SPNEGO.
|
||||
|
||||
When using this option, you must also provide a fake \fI-u, --user\fP option to
|
||||
activate the authentication code properly. Sending a '-u :' is enough as the
|
||||
@@ -1254,8 +1257,8 @@ the default authentication method curl uses with proxies.
|
||||
Tells curl to use HTTP Digest authentication when communicating with the given
|
||||
proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.
|
||||
.IP "--proxy-negotiate"
|
||||
Tells curl to use HTTP Negotiate authentication when communicating
|
||||
with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate
|
||||
Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating
|
||||
with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate (SPNEGO)
|
||||
with a remote host. (Added in 7.17.1)
|
||||
.IP "--proxy-ntlm"
|
||||
Tells curl to use HTTP NTLM authentication when communicating with the given
|
||||
@@ -1518,7 +1521,7 @@ sockd/proxy-name --socks5 proxy-name \fI--socks5-gssapi-service\fP
|
||||
sockd/real-name would use sockd/real-name for cases where the proxy-name does
|
||||
not match the principal name. (Added in 7.19.4).
|
||||
.IP "--socks5-gssapi-nec"
|
||||
As part of the gssapi negotiation a protection mode is negotiated. RFC 1961
|
||||
As part of the GSS-API negotiation a protection mode is negotiated. RFC 1961
|
||||
says in section 4.3/4.4 it should be protected, but the NEC reference
|
||||
implementation does not. The option \fI--socks5-gssapi-nec\fP allows the
|
||||
unprotected exchange of the protection mode negotiation. (Added in 7.19.4).
|
||||
@@ -1633,17 +1636,31 @@ The user name and passwords are split up on the first colon, which makes it
|
||||
impossible to use a colon in the user name with this option. The password can,
|
||||
still.
|
||||
|
||||
If you use an SSPI-enabled curl binary and perform NTLM authentication, you
|
||||
can force curl to select the user name and password from your environment by
|
||||
specifying a single colon with this option: "-u :".
|
||||
When using Kerberos V5 with a Windows based server you should include the
|
||||
Windows domain name in the user name, in order for the server to succesfully
|
||||
obtain a Kerberos Ticket. If you don't then the initial authentication
|
||||
handshake may fail.
|
||||
|
||||
When using NTLM, the user name can be specified simply as the user name,
|
||||
without the domain, if there is a single domain and forest in your setup
|
||||
for example.
|
||||
|
||||
To specify the domain name use either Down-Level Logon Name or UPN (User
|
||||
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
|
||||
respectively.
|
||||
|
||||
If you use a Windows SSPI-enabled curl binary and perform Kerberos V5,
|
||||
Negotiate or NTLM authentication then you can tell curl to select the user
|
||||
name and password from your environment by specifying a single colon with this
|
||||
option: "-u :".
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-U, --proxy-user <user:password>"
|
||||
Specify the user name and password to use for proxy authentication.
|
||||
|
||||
If you use an SSPI-enabled curl binary and do NTLM authentication, you can
|
||||
force curl to pick up the user name and password from your environment by
|
||||
simply specifying a single colon with this option: "-U :".
|
||||
If you use a Windows SSPI-enabled curl binary and do either Negotiate or NTLM
|
||||
authentication then you can tell curl to select the user name and password
|
||||
from your environment by specifying a single colon with this option: "-U :".
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--url <URL>"
|
||||
@@ -1917,22 +1934,21 @@ HTTPS and FTPS are supported.
|
||||
Automatic decompression of compressed files over HTTP is supported.
|
||||
.IP "NTLM"
|
||||
NTLM authentication is supported.
|
||||
.IP "GSS-Negotiate"
|
||||
Negotiate authentication and krb5 for FTP is supported.
|
||||
.IP "Debug"
|
||||
This curl uses a libcurl built with Debug. This enables more error-tracking
|
||||
and memory debugging etc. For curl-developers only!
|
||||
.IP "AsynchDNS"
|
||||
This curl uses asynchronous name resolves.
|
||||
.IP "SPNEGO"
|
||||
SPNEGO Negotiate authentication is supported.
|
||||
SPNEGO authentication is supported.
|
||||
.IP "Largefile"
|
||||
This curl supports transfers of large files, files larger than 2GB.
|
||||
.IP "IDN"
|
||||
This curl supports IDN - international domain names.
|
||||
.IP "GSS-API"
|
||||
GSS-API is supported.
|
||||
.IP "SSPI"
|
||||
SSPI is supported. If you use NTLM and set a blank user name, curl will
|
||||
authenticate with your current user and password.
|
||||
SSPI is supported.
|
||||
.IP "TLS-SRP"
|
||||
SRP (Secure Remote Password) authentication is supported for TLS.
|
||||
.IP "Metalink"
|
||||
|
@@ -148,9 +148,6 @@ 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
|
||||
@@ -230,9 +227,6 @@ ifdef SSPI
|
||||
CFLAGS += -DUSE_SCHANNEL
|
||||
endif
|
||||
endif
|
||||
ifdef SPNEGO
|
||||
CFLAGS += -DHAVE_SPNEGO
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6 -D_WIN32_WINNT=0x0501
|
||||
endif
|
||||
|
@@ -211,9 +211,6 @@ endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
WITH_SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
@@ -247,10 +244,6 @@ ifdef WITH_SSL
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
ifdef WITH_SPNEGO
|
||||
# INCLUDES += -I$(FBOPENSSL_PATH)/include
|
||||
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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,9 +26,9 @@ struct callback_data {
|
||||
FILE *output;
|
||||
};
|
||||
|
||||
static long file_is_comming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains);
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains);
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data);
|
||||
|
||||
@@ -61,7 +61,7 @@ int main(int argc, char **argv)
|
||||
curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
||||
|
||||
/* callback is called before download of concrete file started */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming);
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
|
||||
|
||||
/* callback is called after data from the file have been transferred */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
|
||||
@@ -89,9 +89,9 @@ int main(int argc, char **argv)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long file_is_comming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains)
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains)
|
||||
{
|
||||
printf("%3d %40s %10luB ", remains, finfo->filename,
|
||||
(unsigned long)finfo->size);
|
||||
|
@@ -225,10 +225,10 @@ content is for the specific named data. See also the certinfo.c example. NOTE:
|
||||
this option is only available in libcurl built with OpenSSL, NSS, GSKit or
|
||||
QsoSSL support. (Added in 7.19.1)
|
||||
.IP CURLINFO_TLS_SESSION
|
||||
Pass a pointer to a 'struct curl_tlsinfo *'. The pointer will be initialized
|
||||
to refer to a 'struct curl_tlsinfo *' that will contain an enum indicating the
|
||||
SSL library used for the handshake and the respective internal TLS session
|
||||
structure of this underlying SSL library.
|
||||
Pass a pointer to a 'struct curl_tlssessioninfo *'. The pointer will be
|
||||
initialized to refer to a 'struct curl_tlssessioninfo *' that will contain an
|
||||
enum indicating the SSL library used for the handshake and the respective
|
||||
internal TLS session structure of this underlying SSL library.
|
||||
|
||||
This may then be used to extract certificate information in a format
|
||||
convenient for further processing, such as manual validation. NOTE: this
|
||||
|
@@ -86,6 +86,10 @@ you must set its length with \fBCURLFORM_CONTENTSLENGTH\fP.
|
||||
.IP CURLFORM_CONTENTSLENGTH
|
||||
followed by a long giving the length of the contents. Note that for
|
||||
\fICURLFORM_STREAM\fP contents, this option is mandatory.
|
||||
|
||||
If you pass a 0 (zero) for this option, libcurl will instead do a strlen() on
|
||||
the contents to figure out the size. If you really want to send a zero byte
|
||||
content then you must make sure strlen() on the data pointer returns zero.
|
||||
.IP CURLFORM_FILECONTENT
|
||||
followed by a filename, causes that file to be read and its contents used
|
||||
as data in this part. This part does \fInot\fP automatically become a file
|
||||
|
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl_version_info 3 "18 Feb 2014" "libcurl 7.33.0" "libcurl Manual"
|
||||
.TH curl_version_info 3 "2 Aug 2014" "libcurl 7.38.0" "libcurl Manual"
|
||||
.SH NAME
|
||||
curl_version_info - returns run-time libcurl version info
|
||||
.SH SYNOPSIS
|
||||
@@ -124,9 +124,14 @@ libcurl was built with support for IDNA, domain names with international
|
||||
letters. (Added in 7.12.0)
|
||||
.IP CURL_VERSION_SSPI
|
||||
libcurl was built with support for SSPI. This is only available on Windows and
|
||||
makes libcurl use Windows-provided functions for NTLM authentication. It also
|
||||
allows libcurl to use the current user and the current user's password without
|
||||
makes libcurl use Windows-provided functions for NTLM, SPNEGO and SASL DIGEST-MD5
|
||||
authentication. It also allows libcurl to use the current user credentials without
|
||||
the app having to pass them on. (Added in 7.13.2)
|
||||
.IP CURL_VERSION_GSSAPI
|
||||
libcurl was built with support for GSS-API. This makes libcurl use provided
|
||||
functions for Kerberos and SPNEGO authentication. It also allows libcurl
|
||||
to use the current user credentials without the app having to pass them on.
|
||||
(Added in 7.38.0)
|
||||
.IP CURL_VERSION_CONV
|
||||
libcurl was built with support for character conversions, as provided by the
|
||||
CURLOPT_CONV_* callbacks. (Added in 7.15.4)
|
||||
@@ -142,8 +147,7 @@ libcurl was built with support for HTTP2.
|
||||
\fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl
|
||||
has no SSL support, this is NULL.
|
||||
|
||||
\fIssl_version_num\fP is the numerical OpenSSL version value as defined by the
|
||||
OpenSSL project. If libcurl has no SSL support, this is 0.
|
||||
\fIssl_version_num\fP is always 0.
|
||||
|
||||
\fIlibz_version\fP is an ASCII string (there is no numerical version). If
|
||||
libcurl has no libz support, this is NULL.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
An overview of the six time values available from curl_easy_getinfo()
|
||||
|
||||
curk_easy_perform()
|
||||
curl_easy_perform()
|
||||
|
|
||||
|--NT
|
||||
|--|--CT
|
||||
|
@@ -83,6 +83,9 @@ FTP servers return a 227-line as a response to a PASV command. If libcurl
|
||||
fails to parse that line, this return code is passed back.
|
||||
.IP "CURLE_FTP_CANT_GET_HOST (15)"
|
||||
An internal failure to lookup the host used for the new connection.
|
||||
.IP "CURLE_HTTP2 (16)"
|
||||
A problem was detected in the HTTP2 framing layer. This is somewhat generic
|
||||
and can be one out of several problems, see the error buffer for details.
|
||||
.IP "CURLE_FTP_COULDNT_SET_TYPE (17)"
|
||||
Received an error when trying to set the transfer mode to binary or ASCII.
|
||||
.IP "CURLE_PARTIAL_FILE (18)"
|
||||
|
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH libcurl-tutorial 3 "4 Mar 2009" "libcurl" "libcurl programming"
|
||||
.TH libcurl-tutorial 3 "2 Aug 2014" "libcurl" "libcurl programming"
|
||||
.SH NAME
|
||||
libcurl-tutorial \- libcurl programming tutorial
|
||||
.SH "Objective"
|
||||
@@ -442,7 +442,7 @@ authentication method is called 'Basic', which is sending the name and
|
||||
password in clear-text in the HTTP request, base64-encoded. This is insecure.
|
||||
|
||||
At the time of this writing, libcurl can be built to use: Basic, Digest, NTLM,
|
||||
Negotiate, GSS-Negotiate and SPNEGO. You can tell libcurl which one to use
|
||||
Negotiate (SPNEGO). You can tell libcurl which one to use
|
||||
with \fICURLOPT_HTTPAUTH(3)\fP as in:
|
||||
|
||||
curl_easy_setopt(easyhandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
|
@@ -40,7 +40,7 @@ details.
|
||||
|
||||
To transfer files, you create an "easy handle" using \fIcurl_easy_init(3)\fP
|
||||
for a single individual transfer (in either direction). You then set your
|
||||
desired set of options in that handle with \fIcurk_easy_setopt(3)\fP. Options
|
||||
desired set of options in that handle with \fIcurl_easy_setopt(3)\fP. Options
|
||||
you set with \fIcurl_easy_setopt(3)\fP stick. They will be used on every
|
||||
repeated use of this handle until you either change the option, or you reset
|
||||
them all with \fIcurl_easy_reset(3)\fP.
|
||||
|
@@ -1,3 +1,24 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 2006, David Shaw <dshaw@jabberwocky.com>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
###########################################################################
|
||||
# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION],
|
||||
# [ACTION-IF-YES], [ACTION-IF-NO])
|
||||
# ----------------------------------------------------------
|
||||
|
@@ -52,4 +52,5 @@ If built TLS enabled
|
||||
Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
|
||||
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
||||
.SH "SEE ALSO"
|
||||
.BR CURLOPT_CAPATH "(3), "
|
||||
.BR CURLOPT_SSL_VERIFYPEER "(3), " CURLOPT_SSL_VERIFYHOST "(3), "
|
||||
|
@@ -32,10 +32,10 @@ Pass a char * to a zero terminated string naming a directory holding multiple
|
||||
CA certificates to verify the peer with. If libcurl is built against OpenSSL,
|
||||
the certificate directory must be prepared using the openssl c_rehash utility.
|
||||
This makes sense only when used in combination with the
|
||||
\fICURLOPT_SSL_VERIFYPEER(3)\fP option. If \fICURLOPT_SSL_VERIFYPEER(3)\fP is
|
||||
zero, \fICURLOPT_CAPATH(3)\fP need not even indicate an accessible path. The
|
||||
\fICURLOPT_CAPATH(3)\fP function apparently does not work in Windows due to
|
||||
some limitation in openssl.
|
||||
\fICURLOPT_SSL_VERIFYPEER(3)\fP option.
|
||||
|
||||
The \fICURLOPT_CAPATH(3)\fP function apparently does not work in Windows due
|
||||
to some limitation in openssl.
|
||||
.SH DEFAULT
|
||||
NULL
|
||||
.SH PROTOCOLS
|
||||
@@ -50,4 +50,5 @@ compatibility.
|
||||
Returns CURLE_OK if TLS enabled, and CURLE_UNKNOWN_OPTION if not, or
|
||||
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
||||
.SH "SEE ALSO"
|
||||
.BR CURLOPT_CAINFO "(3), "
|
||||
.BR CURLOPT_STDERR "(3), " CURLOPT_DEBUGFUNCTION "(3), "
|
||||
|
@@ -40,7 +40,7 @@ This callback function gets called by libcurl before a part of the stream is
|
||||
going to be transferred (if the transfer supports chunks).
|
||||
|
||||
The \fItransfer_info\fP pointer will point to a struct curl_fileinfo with
|
||||
details about the file that is about to get transfered.
|
||||
details about the file that is about to get transferred.
|
||||
|
||||
This callback makes sense only when using the \fICURLOPT_WILDCARDMATCH(3)\fP
|
||||
option for now.
|
||||
|
@@ -22,7 +22,7 @@
|
||||
.\"
|
||||
.TH CURLOPT_FTPSSLAUTH 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_FTPSSLAUTH \- set order to attemp TSL vs SSL when using FTP
|
||||
CURLOPT_FTPSSLAUTH \- set order in which to attempt TLS vs SSL when using FTP
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -41,7 +41,7 @@ sent to a server and not to a proxy. Proxy headers must be set with
|
||||
\fICURLOPT_PROXYHEADER(3)\fP to get used. Note that if a non-CONNECT request
|
||||
is sent to a proxy, libcurl will send both server headers and proxy
|
||||
headers. When doing CONNECT, libcurl will send \fICURLOPT_PROXYHEADER(3)\fP
|
||||
headers only do the proxy and then \fICURLOPT_HTTPHEADER(3)\fP headers only to
|
||||
headers only to the proxy and then \fICURLOPT_HTTPHEADER(3)\fP headers only to
|
||||
the server.
|
||||
.SH DEFAULT
|
||||
CURLHEADER_UNIFIED
|
||||
|
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH CURLOPT_HTTPAUTH 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
|
||||
.TH CURLOPT_HTTPAUTH 3 "2 Aug 2014" "libcurl 7.38.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_HTTPAUTH \- set HTTP server authentication methods to try
|
||||
.SH SYNOPSIS
|
||||
@@ -56,14 +56,12 @@ defined in RFC2617 and is a more secure way to do authentication over public
|
||||
networks than the regular old-fashioned Basic method. The IE flavor is simply
|
||||
that libcurl will use a special "quirk" that IE is known to have used before
|
||||
version 7 and that some servers require the client to use.
|
||||
.IP CURLAUTH_GSSNEGOTIATE
|
||||
HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain
|
||||
\&"Negotiate") method was designed by Microsoft and is used in their web
|
||||
applications. It is primarily meant as a support for Kerberos5 authentication
|
||||
but may also be used along with other authentication methods. For more
|
||||
information see IETF draft draft-brezak-spnego-http-04.txt.
|
||||
.IP CURLAUTH_NEGOTIATE
|
||||
HTTP Negotiate (SPNEGO) authentication. Negotiate authentication is defined
|
||||
in RFC 4559 and is the most secure way to perform authentication over HTTP.
|
||||
|
||||
You need to build libcurl with a suitable GSS-API library for this to work.
|
||||
You need to build libcurl with a suitable GSS-API library or SSPI on Windows
|
||||
for this to work.
|
||||
.IP CURLAUTH_NTLM
|
||||
HTTP NTLM authentication. A proprietary protocol invented and used by
|
||||
Microsoft. It uses a challenge-response and hash concept similar to Digest, to
|
||||
|
@@ -57,7 +57,7 @@ The callback MUST return \fICURLIOE_UNKNOWNCMD\fP if the input \fIcmd\fP is
|
||||
not \fICURLIOCMD_RESTARTREAD\fP.
|
||||
|
||||
The \fIclientp\fP argument to the callback is set with the
|
||||
\fUICURLOPT_IOCTLDATA(3)\fP option.
|
||||
\fICURLOPT_IOCTLDATA(3)\fP option.
|
||||
|
||||
This option is deprecated! Do not use it. Use \fICURLOPT_SEEKFUNCTION(3)\fP
|
||||
instead to provide seeking! If \fICURLOPT_SEEKFUNCTION(3)\fP is set, this
|
||||
|
@@ -22,15 +22,18 @@
|
||||
.\"
|
||||
.TH CURLOPT_NOBODY 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_NOBODY \- do the request without getting the body
|
||||
CURLOPT_NOBODY \- do the download request without getting the body
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOBODY, long opt);
|
||||
.SH DESCRIPTION
|
||||
A long parameter set to 1 tells libcurl to not include the body-part in the
|
||||
output. For HTTP(S), this makes libcurl do a HEAD request. For most other
|
||||
protocols ie means just not asking for transferring the body data.
|
||||
output when doing what would otherwise be a download. For HTTP(S), this makes
|
||||
libcurl do a HEAD request. For most other protocols it means just not asking
|
||||
to transfer the body data.
|
||||
|
||||
Enabling this option means asking for a download but without a body.
|
||||
.SH DEFAULT
|
||||
0, the body is transferred
|
||||
.SH PROTOCOLS
|
||||
|
@@ -32,7 +32,7 @@ A parameter set to 1 tells the library to use HTTP PUT to transfer data. The
|
||||
data should be set with \fICURLOPT_READDATA(3)\fP and
|
||||
\fICURLOPT_INFILESIZE(3)\fP.
|
||||
|
||||
This option is \dBdeprecated\fP since version 7.12.1. Use
|
||||
This option is \fBdeprecated\fP since version 7.12.1. Use
|
||||
\fICURLOPT_UPLOAD(3)\fP!
|
||||
.SH DEFAULT
|
||||
0, disabled
|
||||
|
@@ -41,7 +41,7 @@ All
|
||||
.SH EXAMPLE
|
||||
TODO
|
||||
.SH AVAILABILITY
|
||||
Added in 7.19.4, before then it would follow all protcols.
|
||||
Added in 7.19.4, before then it would follow all protocols.
|
||||
.SH RETURN VALUE
|
||||
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
|
||||
.SH "SEE ALSO"
|
||||
|
@@ -22,7 +22,7 @@
|
||||
.\"
|
||||
.TH CURLOPT_SSH_KEYDATA 3 "19 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_SSH_KEYDATA \- pointer to apss to the SSH key callback
|
||||
CURLOPT_SSH_KEYDATA \- pointer to pass to the SSH key callback
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -51,6 +51,12 @@ typically also want to ensure that the server is the server you mean to be
|
||||
talking to. Use \fICURLOPT_SSL_VERIFYHOST(3)\fP for that. The check that the
|
||||
host name in the certificate is valid for the host name you're connecting to
|
||||
is done independently of the \fICURLOPT_SSL_VERIFYPEER(3)\fP option.
|
||||
|
||||
WARNING: disabling verification of the certificate allows bad guys to
|
||||
man-in-the-middle the communication without you knowing it. Disabling
|
||||
verification makes the communication insecure. Just having encryption on a
|
||||
transfer is not enough as you cannot be sure that you are communicating with
|
||||
the correct end-point.
|
||||
.SH DEFAULT
|
||||
By default, curl assumes a value of 1.
|
||||
.SH PROTOCOLS
|
||||
|
@@ -22,7 +22,7 @@
|
||||
.\"
|
||||
.TH CURLOPT_URL 3 "17 Jun 2014" "libcurl 7.37.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_URL \- provide the URL to use in the reqest
|
||||
CURLOPT_URL \- provide the URL to use in the request
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
@@ -37,6 +37,22 @@ user name to use for the transfer.
|
||||
authentication. You should not use this option together with the (older)
|
||||
\fICURLOPT_USERPWD(3)\fP option.
|
||||
|
||||
When using Kerberos V5 authentication with a Windows based server, you should
|
||||
include the domain name in order for the server to successfully obtain a
|
||||
Kerberos Ticket. If you don't then the initial part of the authentication
|
||||
handshake may fail.
|
||||
|
||||
When using NTLM, the user name can be specified simply as the user name
|
||||
without the domain name should the server be part of a single domain and
|
||||
forest.
|
||||
|
||||
To include the domain name use either Down-Level Logon Name or UPN (User
|
||||
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
|
||||
respectively.
|
||||
|
||||
Some HTTP servers (on Windows) support inclusion of the domain for Basic
|
||||
authentication as well.
|
||||
|
||||
To specify the password and login options, along with the user name, use the
|
||||
\fICURLOPT_PASSWORD(3)\fP and \fICURLOPT_LOGIN_OPTIONS(3)\fP options.
|
||||
.SH DEFAULT
|
||||
|
@@ -31,10 +31,21 @@ CURLcode curl_easy_setopt(CURL *handle, CURLOPT_USERPWD, char *userpwd);
|
||||
Pass a char * as parameter, pointing to a zero terminated login details string
|
||||
for the connection. The format of which is: [user name]:[password].
|
||||
|
||||
When using NTLM, you can set the domain by prepending it to the user name and
|
||||
separating the domain and name with a forward (/) or backward slash (\\). Like
|
||||
this: "domain/user:password" or "domain\\user:password". Some HTTP servers (on
|
||||
Windows) support this style even for Basic authentication.
|
||||
When using Kerberos V5 authentication with a Windows based server, you should
|
||||
specify the user name part with the domain name in order for the server to
|
||||
successfully obtain a Kerberos Ticket. If you don't then the initial part of
|
||||
the authentication handshake may fail.
|
||||
|
||||
When using NTLM, the user name can be specified simply as the user name
|
||||
without the domain name should the server be part of a single domain and
|
||||
forest.
|
||||
|
||||
To specify the domain name use either Down-Level Logon Name or UPN (User
|
||||
Principal Name) formats. For example, EXAMPLE\\user and user@example.com
|
||||
respectively.
|
||||
|
||||
Some HTTP servers (on Windows) support inclusion of the domain for Basic
|
||||
authentication as well.
|
||||
|
||||
When using HTTP and \fICURLOPT_FOLLOWLOCATION(3)\fP, libcurl might perform
|
||||
several requests to possibly different hosts. libcurl will only send this user
|
||||
|
@@ -17,7 +17,8 @@ CURLAUTH_ANYSAFE 7.10.6
|
||||
CURLAUTH_BASIC 7.10.6
|
||||
CURLAUTH_DIGEST 7.10.6
|
||||
CURLAUTH_DIGEST_IE 7.19.3
|
||||
CURLAUTH_GSSNEGOTIATE 7.10.6
|
||||
CURLAUTH_GSSNEGOTIATE 7.10.6 7.38.0
|
||||
CURLAUTH_NEGOTIATE 7.38.0
|
||||
CURLAUTH_NONE 7.10.6
|
||||
CURLAUTH_NTLM 7.10.6
|
||||
CURLAUTH_NTLM_WB 7.22.0
|
||||
@@ -78,6 +79,7 @@ CURLE_HTTP_PORT_FAILED 7.3 7.12.0
|
||||
CURLE_HTTP_POST_ERROR 7.1
|
||||
CURLE_HTTP_RANGE_ERROR 7.1 7.17.0
|
||||
CURLE_HTTP_RETURNED_ERROR 7.10.3
|
||||
CURLE_HTTP2 7.38.0
|
||||
CURLE_INTERFACE_FAILED 7.12.0
|
||||
CURLE_LDAP_CANNOT_BIND 7.1
|
||||
CURLE_LDAP_INVALID_URL 7.10.8
|
||||
@@ -602,6 +604,7 @@ CURLSSH_AUTH_KEYBOARD 7.16.1
|
||||
CURLSSH_AUTH_NONE 7.16.1
|
||||
CURLSSH_AUTH_PASSWORD 7.16.1
|
||||
CURLSSH_AUTH_PUBLICKEY 7.16.1
|
||||
CURLSSLBACKEND_AXTLS 7.38.0
|
||||
CURLSSLBACKEND_CYASSL 7.34.0
|
||||
CURLSSLBACKEND_DARWINSSL 7.34.0
|
||||
CURLSSLBACKEND_GNUTLS 7.34.0
|
||||
@@ -727,7 +730,8 @@ CURL_VERSION_ASYNCHDNS 7.10.7
|
||||
CURL_VERSION_CONV 7.15.4
|
||||
CURL_VERSION_CURLDEBUG 7.19.6
|
||||
CURL_VERSION_DEBUG 7.10.6
|
||||
CURL_VERSION_GSSNEGOTIATE 7.10.6
|
||||
CURL_VERSION_GSSAPI 7.38.0
|
||||
CURL_VERSION_GSSNEGOTIATE 7.10.6 7.38.0
|
||||
CURL_VERSION_HTTP2 7.33.0
|
||||
CURL_VERSION_IDN 7.12.0
|
||||
CURL_VERSION_IPV6 7.10
|
||||
|
@@ -423,7 +423,9 @@ typedef enum {
|
||||
CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */
|
||||
CURLE_FTP_WEIRD_227_FORMAT, /* 14 */
|
||||
CURLE_FTP_CANT_GET_HOST, /* 15 */
|
||||
CURLE_OBSOLETE16, /* 16 - NOT USED */
|
||||
CURLE_HTTP2, /* 16 - A problem in the http2 framing layer.
|
||||
[was obsoleted in August 2007 for 7.17.0,
|
||||
reused in July 2014 for 7.38.0] */
|
||||
CURLE_FTP_COULDNT_SET_TYPE, /* 17 */
|
||||
CURLE_PARTIAL_FILE, /* 18 */
|
||||
CURLE_FTP_COULDNT_RETR_FILE, /* 19 */
|
||||
@@ -525,7 +527,10 @@ typedef enum {
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
/* Previously obsoletes error codes re-used in 7.24.0 */
|
||||
/* Previously obsolete error code re-used in 7.38.0 */
|
||||
#define CURLE_OBSOLETE16 CURLE_HTTP2
|
||||
|
||||
/* Previously obsolete error codes re-used in 7.24.0 */
|
||||
#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
|
||||
#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
|
||||
|
||||
@@ -619,7 +624,8 @@ typedef enum {
|
||||
* CURLAUTH_NONE - No HTTP authentication
|
||||
* CURLAUTH_BASIC - HTTP Basic authentication (default)
|
||||
* CURLAUTH_DIGEST - HTTP Digest authentication
|
||||
* CURLAUTH_GSSNEGOTIATE - HTTP GSS-Negotiate authentication
|
||||
* CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication
|
||||
* CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
|
||||
* CURLAUTH_NTLM - HTTP NTLM authentication
|
||||
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
|
||||
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
|
||||
@@ -632,7 +638,9 @@ typedef enum {
|
||||
#define CURLAUTH_NONE ((unsigned long)0)
|
||||
#define CURLAUTH_BASIC (((unsigned long)1)<<0)
|
||||
#define CURLAUTH_DIGEST (((unsigned long)1)<<1)
|
||||
#define CURLAUTH_GSSNEGOTIATE (((unsigned long)1)<<2)
|
||||
#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
|
||||
/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
|
||||
#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
|
||||
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
||||
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
||||
@@ -2025,7 +2033,8 @@ typedef enum {
|
||||
CURLSSLBACKEND_POLARSSL = 6,
|
||||
CURLSSLBACKEND_CYASSL = 7,
|
||||
CURLSSLBACKEND_SCHANNEL = 8,
|
||||
CURLSSLBACKEND_DARWINSSL = 9
|
||||
CURLSSLBACKEND_DARWINSSL = 9,
|
||||
CURLSSLBACKEND_AXTLS = 10
|
||||
} curl_sslbackend;
|
||||
|
||||
/* Information about the SSL library used and the respective internal SSL
|
||||
@@ -2231,10 +2240,11 @@ typedef struct {
|
||||
#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
|
||||
#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
|
||||
#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support
|
||||
(deprecated) */
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||
#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
|
||||
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */
|
||||
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
|
||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
||||
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
||||
@@ -2243,6 +2253,7 @@ typedef struct {
|
||||
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
|
||||
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
|
||||
#define CURL_VERSION_GSSAPI (1<<17) /* GSS-API is supported */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
14
install-sh
14
install-sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2011-01-19.21; # UTC
|
||||
scriptversion=2011-11-20.07; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -35,7 +35,7 @@ scriptversion=2011-01-19.21; # UTC
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
@@ -156,7 +156,7 @@ while test $# -ne 0; do
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
@@ -190,7 +190,7 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
@@ -202,7 +202,7 @@ if test $# -eq 0; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
@@ -240,7 +240,7 @@ fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for `test' and other utilities.
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
@@ -354,7 +354,7 @@ do
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
|
@@ -60,7 +60,7 @@ SYS_INCL = -I"$(%watcom)/h/nt" -I"$(%watcom)/h"
|
||||
|
||||
CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm &
|
||||
-wcd=201 -bt=nt -d+ -dWIN32 -dCURL_WANTS_CA_BUNDLE_ENV &
|
||||
-dBUILDING_LIBCURL -dHAVE_SPNEGO=1 -I. -I"../include" $(SYS_INCL)
|
||||
-dBUILDING_LIBCURL -I. -I"../include" $(SYS_INCL)
|
||||
|
||||
!ifdef %debug
|
||||
DEBUG = -dDEBUG=1 -dDEBUGBUILD
|
||||
@@ -248,4 +248,4 @@ $(RESOURCE): libcurl.rc
|
||||
|
||||
.c{$(OBJ_STAT)}.obj:
|
||||
$(CC) $(CFLAGS) -DCURL_STATICLIB $[@ -fo=$^@
|
||||
|
||||
|
||||
|
@@ -137,9 +137,6 @@ 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
|
||||
|
@@ -217,9 +217,6 @@ endif
|
||||
ifeq ($(findstring -idn,$(CFG)),-idn)
|
||||
WITH_IDN = 1
|
||||
endif
|
||||
ifeq ($(findstring -spnego,$(CFG)),-spnego)
|
||||
WITH_SPNEGO = 1
|
||||
endif
|
||||
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
|
||||
ENABLE_IPV6 = 1
|
||||
endif
|
||||
@@ -247,10 +244,6 @@ ifdef WITH_SSL
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
INSTDEP += ca-bundle.crt
|
||||
ifdef WITH_SPNEGO
|
||||
INCLUDES += -I$(FBOPENSSL_PATH)/include
|
||||
LDLIBS += $(FBOPENSSL_PATH)/nw/fbopenssl.$(LIBEXT)
|
||||
endif
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
|
@@ -235,7 +235,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||
if(milli == 0)
|
||||
milli += 10;
|
||||
Curl_expire(conn->data, milli);
|
||||
Curl_expire_latest(conn->data, milli);
|
||||
|
||||
return max;
|
||||
}
|
||||
@@ -669,7 +669,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
#if (ARES_VERSION >= 0x010704)
|
||||
#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
|
||||
unsigned char a6[INET6_ADDRSTRLEN];
|
||||
|
||||
if((!local_ip6) || (local_ip6[0] == 0)) {
|
||||
|
@@ -166,6 +166,7 @@ struct thread_sync_data {
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
struct thread_data *td; /* for thread-self cleanup */
|
||||
};
|
||||
|
||||
struct thread_data {
|
||||
@@ -202,13 +203,16 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
|
||||
/* Initialize resolver thread synchronization data */
|
||||
static
|
||||
int init_thread_sync_data(struct thread_sync_data * tsd,
|
||||
int init_thread_sync_data(struct thread_data * td,
|
||||
const char * hostname,
|
||||
int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct thread_sync_data *tsd = &td->tsd;
|
||||
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
|
||||
tsd->td = td;
|
||||
tsd->port = port;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
DEBUGASSERT(hints);
|
||||
@@ -266,6 +270,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
|
||||
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
char service[12];
|
||||
int rc;
|
||||
|
||||
@@ -280,8 +285,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -294,6 +307,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
|
||||
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
||||
|
||||
@@ -304,8 +318,16 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -317,21 +339,37 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
*/
|
||||
static void destroy_async_data (struct Curl_async *async)
|
||||
{
|
||||
if(async->os_specific) {
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
int done;
|
||||
|
||||
/*
|
||||
* if the thread is still blocking in the resolve syscall, detach it and
|
||||
* let the thread do the cleanup...
|
||||
*/
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
td->tsd.done = 1;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if(!done) {
|
||||
Curl_thread_destroy(td->thread_hnd);
|
||||
}
|
||||
else {
|
||||
if(td->thread_hnd != curl_thread_t_null)
|
||||
Curl_thread_join(&td->thread_hnd);
|
||||
|
||||
destroy_thread_sync_data(&td->tsd);
|
||||
|
||||
free(async->os_specific);
|
||||
}
|
||||
}
|
||||
async->os_specific = NULL;
|
||||
|
||||
if(async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if(async->os_specific) {
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
|
||||
if(td->thread_hnd != curl_thread_t_null)
|
||||
Curl_thread_join(&td->thread_hnd);
|
||||
|
||||
destroy_thread_sync_data(&td->tsd);
|
||||
|
||||
free(async->os_specific);
|
||||
}
|
||||
async->hostname = NULL;
|
||||
async->os_specific = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -357,7 +395,7 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
conn->async.dns = NULL;
|
||||
td->thread_hnd = curl_thread_t_null;
|
||||
|
||||
if(!init_thread_sync_data(&td->tsd, hostname, port, hints))
|
||||
if(!init_thread_sync_data(td, hostname, port, hints))
|
||||
goto err_exit;
|
||||
|
||||
Curl_safefree(conn->async.hostname);
|
||||
@@ -503,7 +541,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
td->poll_interval = 250;
|
||||
|
||||
td->interval_end = elapsed + td->poll_interval;
|
||||
Curl_expire(conn->data, td->poll_interval);
|
||||
Curl_expire_latest(conn->data, td->poll_interval);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
83
lib/base64.c
83
lib/base64.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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,9 +37,14 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
static const char table64[]=
|
||||
static const char base64[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
|
||||
section 5 */
|
||||
static const char base64url[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
|
||||
static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||
{
|
||||
size_t padding = 0;
|
||||
@@ -54,7 +59,7 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||
padding++;
|
||||
}
|
||||
else {
|
||||
p = table64;
|
||||
p = base64;
|
||||
|
||||
while(*p && (*p != *s)) {
|
||||
v++;
|
||||
@@ -167,26 +172,10 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64_encode()
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode error;
|
||||
unsigned char ibuf[3];
|
||||
@@ -274,4 +263,52 @@ CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64_encode()
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_base64url_encode()
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
|
||||
}
|
||||
/* ---- End of Base64 Encoding ---- */
|
||||
|
@@ -69,7 +69,6 @@
|
||||
#define HAVE_SETMODE 1
|
||||
#define HAVE_SIGNAL 1
|
||||
#define HAVE_SOCKET 1
|
||||
#define HAVE_SPNEGO 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRICMP 1
|
||||
#define HAVE_STRTOLL 1
|
||||
|
@@ -175,6 +175,15 @@
|
||||
/* Define if you have GSS API. */
|
||||
#define HAVE_GSSAPI
|
||||
|
||||
/* Define if you have the GNU gssapi libraries */
|
||||
#undef HAVE_GSSGNU
|
||||
|
||||
/* Define if you have the Heimdal gssapi libraries */
|
||||
#define HAVE_GSSHEIMDAL
|
||||
|
||||
/* Define if you have the MIT gssapi libraries */
|
||||
#undef HAVE_GSSMIT
|
||||
|
||||
/* Define if you have the `ucb' library (-lucb). */
|
||||
#undef HAVE_LIBUCB
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -260,7 +260,8 @@
|
||||
/* Define to 1 if you have the IoctlSocket camel case function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL */
|
||||
|
||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */
|
||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
|
||||
function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
@@ -480,9 +481,6 @@
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
/* #undef HAVE_SPNEGO */
|
||||
|
||||
/* Define to 1 if you have the `SSL_get_shutdown' function. */
|
||||
/*#define HAVE_SSL_GET_SHUTDOWN 1*/
|
||||
|
||||
@@ -659,7 +657,8 @@
|
||||
/*#define PACKAGE "curl"*/
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
/*#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"*/
|
||||
/*#define PACKAGE_BUGREPORT \
|
||||
"a suitable curl mailing list => http://curl.haxx.se/mail/"*/
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
/*#define PACKAGE_NAME "curl"*/
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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
|
||||
@@ -246,7 +246,8 @@
|
||||
/* Define to 1 if you have the IoctlSocket camel case function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL */
|
||||
|
||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */
|
||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
|
||||
function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
@@ -436,9 +437,6 @@
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
/* #undef HAVE_SPNEGO */
|
||||
|
||||
/* Define to 1 if you have the <ssl.h> header file. */
|
||||
/* #undef HAVE_SSL_H */
|
||||
#define HAVE_SSL_H 1
|
||||
@@ -581,7 +579,8 @@
|
||||
#define PACKAGE "curl"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "a suitable curl mailing list => http://curl.haxx.se/mail/"
|
||||
#define PACKAGE_BUGREPORT \
|
||||
"a suitable curl mailing list => http://curl.haxx.se/mail/"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "curl"
|
||||
|
@@ -547,9 +547,6 @@
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define this if you have the SPNEGO library fbopenssl */
|
||||
/* #undef HAVE_SPNEGO */
|
||||
|
||||
/* Define to 1 if you have the `SSL_get_shutdown' function. */
|
||||
#define HAVE_SSL_GET_SHUTDOWN 1
|
||||
|
||||
|
@@ -202,6 +202,7 @@ void Curl_conncache_foreach(struct conncache *connc,
|
||||
struct connectdata *conn;
|
||||
|
||||
bundle = he->ptr;
|
||||
he = Curl_hash_next_element(&iter);
|
||||
|
||||
curr = bundle->conn_list->head;
|
||||
while(curr) {
|
||||
@@ -213,8 +214,6 @@ void Curl_conncache_foreach(struct conncache *connc,
|
||||
if(1 == func(conn, param))
|
||||
return;
|
||||
}
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, 2013, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -25,7 +25,8 @@
|
||||
struct conncache {
|
||||
struct curl_hash *hash;
|
||||
size_t num_connections;
|
||||
size_t next_connection_id;
|
||||
long next_connection_id;
|
||||
struct timeval last_cleanup;
|
||||
};
|
||||
|
||||
struct conncache *Curl_conncache_init(int size);
|
||||
|
@@ -94,7 +94,7 @@ static bool verifyconnect(curl_socket_t sockfd, int *error);
|
||||
#define KEEPALIVE_FACTOR(x)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WINSOCK_H) && !defined(SIO_KEEPALIVE_VALS)
|
||||
#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
|
||||
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
|
||||
|
||||
struct tcp_keepalive {
|
||||
@@ -1054,7 +1054,7 @@ singleipconnect(struct connectdata *conn,
|
||||
|
||||
conn->connecttime = Curl_tvnow();
|
||||
if(conn->num_addr > 1)
|
||||
Curl_expire(data, conn->timeoutms_per_addr);
|
||||
Curl_expire_latest(data, conn->timeoutms_per_addr);
|
||||
|
||||
/* Connect TCP sockets, bind UDP */
|
||||
if(!isconnected && (conn->socktype == SOCK_STREAM)) {
|
||||
|
56
lib/cookie.c
56
lib/cookie.c
@@ -95,6 +95,7 @@ Example set of cookies:
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@@ -319,6 +320,28 @@ static void remove_expired(struct CookieInfo *cookies)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the given string is an IP(v4|v6) address.
|
||||
*/
|
||||
static bool isip(const char *domain)
|
||||
{
|
||||
struct in_addr addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
|
||||
if(Curl_inet_pton(AF_INET, domain, &addr)
|
||||
#ifdef ENABLE_IPV6
|
||||
|| Curl_inet_pton(AF_INET6, domain, &addr6)
|
||||
#endif
|
||||
) {
|
||||
/* domain name given as IP address */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Curl_cookie_add()
|
||||
@@ -439,24 +462,33 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("domain", name)) {
|
||||
bool is_ip;
|
||||
const char *dotp;
|
||||
|
||||
/* 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 */
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
|
||||
/* check for more dots */
|
||||
dotp = strchr(whatptr, '.');
|
||||
if(!dotp)
|
||||
domain=":";
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strcmp(whatptr, domain))
|
||||
|| (!is_ip && tailmatch(whatptr, domain))) {
|
||||
strstore(&co->domain, whatptr);
|
||||
if(!co->domain) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
co->tailmatch=TRUE; /* we always do that if the domain name was
|
||||
given */
|
||||
if(!is_ip)
|
||||
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
|
||||
@@ -968,6 +1000,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
time_t now = time(NULL);
|
||||
struct Cookie *mainco=NULL;
|
||||
size_t matches = 0;
|
||||
bool is_ip;
|
||||
|
||||
if(!c || !c->cookies)
|
||||
return NULL; /* no cookie struct or no cookies in the struct */
|
||||
@@ -975,6 +1008,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(c);
|
||||
|
||||
/* check if host is an IP(v4|v6) address */
|
||||
is_ip = isip(host);
|
||||
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
@@ -986,8 +1022,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && tailmatch(co->domain, host)) ||
|
||||
(!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
|
||||
(co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
|
||||
((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
|
||||
/* the right part of the host matches the domain stuff in the
|
||||
cookie data */
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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
|
||||
@@ -25,6 +25,9 @@
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
CURLcode Curl_base64_decode(const char *src,
|
||||
unsigned char **outptr, size_t *outlen);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -27,15 +27,21 @@
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
|
||||
static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
gss_OID mech_type,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags)
|
||||
OM_uint32 *ret_flags)
|
||||
{
|
||||
OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
|
||||
|
||||
@@ -55,7 +61,7 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
context,
|
||||
target_name,
|
||||
GSS_C_NO_OID, /* mech_type */
|
||||
mech_type,
|
||||
req_flags,
|
||||
0, /* time_req */
|
||||
input_chan_bindings,
|
||||
|
@@ -39,18 +39,21 @@
|
||||
# include <gssapi.h>
|
||||
#endif
|
||||
|
||||
extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
/* Common method for using gss api */
|
||||
/* 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,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
gss_OID mech_type,
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags);
|
||||
OM_uint32 *ret_flags);
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
|
@@ -353,6 +353,9 @@ void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
||||
ntlm->has_handles = 0;
|
||||
}
|
||||
|
||||
ntlm->max_token_length = 0;
|
||||
Curl_safefree(ntlm->output_token);
|
||||
|
||||
Curl_sspi_free_identity(ntlm->p_identity);
|
||||
ntlm->p_identity = NULL;
|
||||
}
|
||||
@@ -409,11 +412,11 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SecBuffer type_1_buf;
|
||||
SecBufferDesc type_1_desc;
|
||||
SECURITY_STATUS status;
|
||||
@@ -422,6 +425,22 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
/* Query the security package for NTLM */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("NTLM"),
|
||||
&SecurityPackage);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
|
||||
ntlm->max_token_length = SecurityPackage->cbMaxToken;
|
||||
|
||||
/* Release the package buffer as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
|
||||
/* Allocate our output buffer */
|
||||
ntlm->output_token = malloc(ntlm->max_token_length);
|
||||
if(!ntlm->output_token)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(userp && *userp) {
|
||||
CURLcode result;
|
||||
|
||||
@@ -450,9 +469,9 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
type_1_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_1_desc.cBuffers = 1;
|
||||
type_1_desc.pBuffers = &type_1_buf;
|
||||
type_1_buf.cbBuffer = NTLM_BUFSIZE;
|
||||
type_1_buf.BufferType = SECBUFFER_TOKEN;
|
||||
type_1_buf.pvBuffer = ntlmbuf;
|
||||
type_1_buf.pvBuffer = ntlm->output_token;
|
||||
type_1_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
|
||||
|
||||
/* Generate our type-1 message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
|
||||
@@ -478,6 +497,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
|
||||
#else
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
const char *host = ""; /* empty */
|
||||
const char *domain = ""; /* empty */
|
||||
size_t hostlen = 0;
|
||||
@@ -555,7 +575,12 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
});
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
return Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
|
||||
outptr, outlen);
|
||||
#else
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -602,10 +627,10 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
CURLcode result = CURLE_OK;
|
||||
SecBuffer type_2_buf;
|
||||
SecBuffer type_3_buf;
|
||||
SecBufferDesc type_2_desc;
|
||||
@@ -631,8 +656,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
type_3_desc.cBuffers = 1;
|
||||
type_3_desc.pBuffers = &type_3_buf;
|
||||
type_3_buf.BufferType = SECBUFFER_TOKEN;
|
||||
type_3_buf.pvBuffer = ntlmbuf;
|
||||
type_3_buf.cbBuffer = NTLM_BUFSIZE;
|
||||
type_3_buf.pvBuffer = ntlm->output_token;
|
||||
type_3_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
|
||||
|
||||
/* Generate our type-3 message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle,
|
||||
@@ -651,9 +676,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
|
||||
size = type_3_buf.cbBuffer;
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
result = Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
|
||||
outptr, outlen);
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
int lmrespoff;
|
||||
unsigned char lmresp[24]; /* fixed-size */
|
||||
#if USE_NTRESPONSES
|
||||
@@ -969,10 +1002,9 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
if(res)
|
||||
return CURLE_CONV_FAILED;
|
||||
|
||||
#endif
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
@@ -39,6 +39,9 @@
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@@ -117,6 +120,10 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
char *slash, *domain = NULL;
|
||||
const char *ntlm_auth = NULL;
|
||||
char *ntlm_auth_alloc = NULL;
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
|
||||
struct passwd pw, *pw_res;
|
||||
char pwbuf[1024];
|
||||
#endif
|
||||
int error;
|
||||
|
||||
/* Return if communication with ntlm_auth already set up */
|
||||
@@ -125,6 +132,30 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
return CURLE_OK;
|
||||
|
||||
username = userp;
|
||||
/* The real ntlm_auth really doesn't like being invoked with an
|
||||
empty username. It won't make inferences for itself, and expects
|
||||
the client to do so (mostly because it's really designed for
|
||||
servers like squid to use for auth, and client support is an
|
||||
afterthought for it). So try hard to provide a suitable username
|
||||
if we don't already have one. But if we can't, provide the
|
||||
empty one anyway. Perhaps they have an implementation of the
|
||||
ntlm_auth helper which *doesn't* need it so we might as well try */
|
||||
if(!username || !username[0]) {
|
||||
username = getenv("NTLMUSER");
|
||||
if(!username || !username[0])
|
||||
username = getenv("LOGNAME");
|
||||
if(!username || !username[0])
|
||||
username = getenv("USER");
|
||||
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
|
||||
if((!username || !username[0]) &&
|
||||
!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
|
||||
pw_res) {
|
||||
username = pw.pw_name;
|
||||
}
|
||||
#endif
|
||||
if(!username || !username[0])
|
||||
username = userp;
|
||||
}
|
||||
slash = strpbrk(username, "\\/");
|
||||
if(slash) {
|
||||
if((domain = strdup(username)) == NULL)
|
||||
@@ -227,11 +258,11 @@ done:
|
||||
static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
const char *input, curlntlm state)
|
||||
{
|
||||
ssize_t size;
|
||||
char buf[NTLM_BUFSIZE];
|
||||
char *tmpbuf = buf;
|
||||
size_t len_in = strlen(input);
|
||||
size_t len_out = sizeof(buf);
|
||||
char *buf = malloc(NTLM_BUFSIZE);
|
||||
size_t len_in = strlen(input), len_out = 0;
|
||||
|
||||
if(!buf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
while(len_in > 0) {
|
||||
ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
|
||||
@@ -246,8 +277,11 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
len_in -= written;
|
||||
}
|
||||
/* Read one line */
|
||||
while(len_out > 0) {
|
||||
size = sread(conn->ntlm_auth_hlpr_socket, tmpbuf, len_out);
|
||||
while(1) {
|
||||
ssize_t size;
|
||||
char *newbuf;
|
||||
|
||||
size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
|
||||
if(size == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
@@ -255,22 +289,28 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
}
|
||||
else if(size == 0)
|
||||
goto done;
|
||||
else if(tmpbuf[size - 1] == '\n') {
|
||||
tmpbuf[size - 1] = '\0';
|
||||
|
||||
len_out += size;
|
||||
if(buf[len_out - 1] == '\n') {
|
||||
buf[len_out - 1] = '\0';
|
||||
goto wrfinish;
|
||||
}
|
||||
tmpbuf += size;
|
||||
len_out -= size;
|
||||
newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf) {
|
||||
free(buf);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
buf = newbuf;
|
||||
}
|
||||
goto done;
|
||||
wrfinish:
|
||||
/* Samba/winbind installed but not configured */
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
size == 3 &&
|
||||
len_out == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
/* invalid response */
|
||||
if(size < 4)
|
||||
if(len_out < 4)
|
||||
goto done;
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
(buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
|
||||
@@ -280,9 +320,11 @@ wrfinish:
|
||||
(buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
|
||||
goto done;
|
||||
|
||||
conn->response_header = aprintf("NTLM %.*s", size - 4, buf + 3);
|
||||
conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
|
||||
free(buf);
|
||||
return CURLE_OK;
|
||||
done:
|
||||
free(buf);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
@@ -53,6 +53,10 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
extern void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
|
||||
#define DIGEST_QOP_VALUE_AUTH (1 << 0)
|
||||
#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1)
|
||||
@@ -120,6 +124,26 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
/*
|
||||
* Curl_sasl_build_spn()
|
||||
*
|
||||
* This is used to build a SPN string in the format service/host.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* serivce [in] - The service type such as www, smtp, pop or imap.
|
||||
* instance [in] - The instance name such as the host nme or realm.
|
||||
*
|
||||
* Returns a pointer to the newly allocated SPN.
|
||||
*/
|
||||
char *Curl_sasl_build_spn(const char *service, const char *host)
|
||||
{
|
||||
/* Generate and return our SPN */
|
||||
return aprintf("%s/%s", service, host);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_sasl_create_plain_message()
|
||||
*
|
||||
@@ -421,7 +445,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
char nonceCount[] = "00000001";
|
||||
char method[] = "AUTHENTICATE";
|
||||
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
|
||||
char uri[128];
|
||||
char *spn = NULL;
|
||||
|
||||
/* Decode the challange message */
|
||||
result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||
@@ -486,19 +510,24 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
|
||||
|
||||
/* Prepare the URL string */
|
||||
snprintf(uri, sizeof(uri), "%s/%s", service, realm);
|
||||
/* Generate our SPN */
|
||||
spn = Curl_sasl_build_spn(service, realm);
|
||||
if(!spn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Calculate H(A2) */
|
||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||
if(!ctxt)
|
||||
if(!ctxt) {
|
||||
Curl_safefree(spn);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) method,
|
||||
curlx_uztoui(strlen(method)));
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) uri,
|
||||
curlx_uztoui(strlen(uri)));
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) spn,
|
||||
curlx_uztoui(strlen(spn)));
|
||||
Curl_MD5_final(ctxt, digest);
|
||||
|
||||
for(i = 0; i < MD5_DIGEST_LEN; i++)
|
||||
@@ -506,8 +535,11 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
|
||||
/* Now calculate the response hash */
|
||||
ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
|
||||
if(!ctxt)
|
||||
if(!ctxt) {
|
||||
Curl_safefree(spn);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN);
|
||||
Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
|
||||
@@ -536,17 +568,19 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
"cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s,"
|
||||
"qop=%s",
|
||||
userp, realm, nonce,
|
||||
cnonce, nonceCount, uri, resp_hash_hex, qop);
|
||||
cnonce, nonceCount, spn, resp_hash_hex, qop);
|
||||
Curl_safefree(spn);
|
||||
if(!response)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Base64 encode the response */
|
||||
result = Curl_base64_encode(data, response, 0, outptr, outlen);
|
||||
|
||||
free(response);
|
||||
Curl_safefree(response);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
#endif /* !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
@@ -688,12 +722,17 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
|
||||
*/
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
|
||||
{
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
/* Cleanup the gssapi structure */
|
||||
if(authused == SASL_MECH_GSSAPI) {
|
||||
Curl_sasl_gssapi_cleanup(&conn->krb5);
|
||||
}
|
||||
#ifdef USE_NTLM
|
||||
/* Cleanup the ntlm structure */
|
||||
if(authused == SASL_MECH_NTLM) {
|
||||
else if(authused == SASL_MECH_NTLM) {
|
||||
Curl_ntlm_sspi_cleanup(&conn->ntlm);
|
||||
}
|
||||
(void)conn;
|
||||
#endif
|
||||
#else
|
||||
/* Reserved for future use */
|
||||
(void)conn;
|
||||
|
@@ -28,6 +28,10 @@ struct SessionHandle;
|
||||
struct connectdata;
|
||||
struct ntlmdata;
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
struct kerberos5data;
|
||||
#endif
|
||||
|
||||
/* Authentication mechanism values */
|
||||
#define SASL_AUTH_NONE 0
|
||||
#define SASL_AUTH_ANY ~0U
|
||||
@@ -57,6 +61,13 @@ struct ntlmdata;
|
||||
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \
|
||||
!memcmp(line, mech, wordlen))
|
||||
|
||||
/* This is used to build a SPN string */
|
||||
#if !defined(USE_WINDOWS_SSPI)
|
||||
char *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
#else
|
||||
TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
#endif
|
||||
|
||||
/* This is used to generate a base64 encoded PLAIN authentication message */
|
||||
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
@@ -112,6 +123,27 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
|
||||
message */
|
||||
CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
const char *service,
|
||||
const bool mutual,
|
||||
const char *chlg64,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
|
||||
token message */
|
||||
CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
|
||||
const char *input,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
#endif
|
||||
|
||||
/* This is used to generate a base64 encoded XOAUTH2 authentication message
|
||||
containing the user name and bearer token */
|
||||
CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
|
||||
|
@@ -5,6 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@@ -20,12 +21,13 @@
|
||||
*
|
||||
* RFC2831 DIGEST-MD5 authentication
|
||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -34,6 +36,7 @@
|
||||
#include "curl_base64.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_multibyte.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -41,6 +44,55 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
|
||||
|
||||
/*
|
||||
* Curl_sasl_build_spn()
|
||||
*
|
||||
* This is used to build a SPN string in the format service/host.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* serivce [in] - The service type such as www, smtp, pop or imap.
|
||||
* instance [in] - The instance name such as the host nme or realm.
|
||||
*
|
||||
* Returns a pointer to the newly allocated SPN.
|
||||
*/
|
||||
TCHAR *Curl_sasl_build_spn(const char *service, const char *host)
|
||||
{
|
||||
char *utf8_spn = NULL;
|
||||
TCHAR *tchar_spn = NULL;
|
||||
|
||||
/* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
|
||||
than doing this ourselves but the first is only available in Windows XP
|
||||
and Windows Server 2003 and the latter is only available in Windows 2000
|
||||
but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
|
||||
Client Extensions are installed. As such it is far simpler for us to
|
||||
formulate the SPN instead. */
|
||||
|
||||
/* Allocate our UTF8 based SPN */
|
||||
utf8_spn = aprintf("%s/%s", service, host);
|
||||
if(!utf8_spn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate our TCHAR based SPN */
|
||||
tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
|
||||
if(!tchar_spn) {
|
||||
Curl_safefree(utf8_spn);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Release the UTF8 variant when operating with Unicode */
|
||||
if(utf8_spn != tchar_spn)
|
||||
Curl_safefree(utf8_spn);
|
||||
|
||||
/* Return our newly allocated SPN */
|
||||
return tchar_spn;
|
||||
}
|
||||
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
/*
|
||||
* Curl_sasl_create_digest_md5_message()
|
||||
*
|
||||
@@ -68,10 +120,11 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
char *spn = NULL;
|
||||
TCHAR *spn = NULL;
|
||||
size_t chlglen = 0;
|
||||
size_t resp_max = 0;
|
||||
unsigned char *chlg = NULL;
|
||||
unsigned char resp[1024];
|
||||
unsigned char *resp = NULL;
|
||||
CredHandle handle;
|
||||
CtxtHandle ctx;
|
||||
PSecPkgInfo SecurityPackage;
|
||||
@@ -107,18 +160,37 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
&SecurityPackage);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
/* Calculate our SPN */
|
||||
spn = aprintf("%s/%s", service, data->easy_conn->host.name);
|
||||
if(!spn)
|
||||
resp_max = SecurityPackage->cbMaxToken;
|
||||
|
||||
/* Release the package buffer as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
|
||||
/* Allocate our response buffer */
|
||||
resp = malloc(resp_max);
|
||||
if(!resp) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Generate our SPN */
|
||||
spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
|
||||
if(!spn) {
|
||||
Curl_safefree(resp);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &identity);
|
||||
if(result) {
|
||||
Curl_safefree(spn);
|
||||
Curl_safefree(resp);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return result;
|
||||
@@ -134,6 +206,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_sspi_free_identity(&identity);
|
||||
Curl_safefree(spn);
|
||||
Curl_safefree(resp);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@@ -153,17 +226,12 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
resp_desc.pBuffers = &resp_buf;
|
||||
resp_buf.BufferType = SECBUFFER_TOKEN;
|
||||
resp_buf.pvBuffer = resp;
|
||||
resp_buf.cbBuffer = sizeof(resp);
|
||||
resp_buf.cbBuffer = curlx_uztoul(resp_max);
|
||||
|
||||
/* Generate our challenge-response message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&handle,
|
||||
NULL,
|
||||
(TCHAR *) spn,
|
||||
0, 0, 0,
|
||||
&chlg_desc,
|
||||
0, &ctx,
|
||||
&resp_desc,
|
||||
&attrs, &tsDummy);
|
||||
status = s_pSecFn->InitializeSecurityContext(&handle, NULL, spn, 0, 0, 0,
|
||||
&chlg_desc, 0, &ctx,
|
||||
&resp_desc, &attrs, &tsDummy);
|
||||
|
||||
if(status == SEC_I_COMPLETE_AND_CONTINUE ||
|
||||
status == SEC_I_CONTINUE_NEEDED)
|
||||
@@ -172,6 +240,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
s_pSecFn->FreeCredentialsHandle(&handle);
|
||||
Curl_sspi_free_identity(&identity);
|
||||
Curl_safefree(spn);
|
||||
Curl_safefree(resp);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_RECV_ERROR;
|
||||
@@ -191,10 +260,437 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
/* Free the SPN */
|
||||
Curl_safefree(spn);
|
||||
|
||||
/* Free the response buffer */
|
||||
Curl_safefree(resp);
|
||||
|
||||
/* Free the decoeded challenge message */
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */
|
||||
#endif /* !CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
/*
|
||||
* Curl_sasl_create_gssapi_user_message()
|
||||
*
|
||||
* This is used to generate an already encoded GSSAPI (Kerberos V5) user token
|
||||
* message ready for sending to the recipient.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* userp [in] - The user name.
|
||||
* passdwp [in] - The user's password.
|
||||
* service [in] - The service type such as www, smtp, pop or imap.
|
||||
* mutual_auth [in] - Flag specifing whether or not mutual authentication
|
||||
* is enabled.
|
||||
* chlg64 [in] - Pointer to the optional base64 encoded challenge
|
||||
* message.
|
||||
* krb5 [in/out] - The gssapi data struct being used and modified.
|
||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
const char *service,
|
||||
const bool mutual_auth,
|
||||
const char *chlg64,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t chlglen = 0;
|
||||
unsigned char *chlg = NULL;
|
||||
CtxtHandle context;
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SecBuffer chlg_buf;
|
||||
SecBuffer resp_buf;
|
||||
SecBufferDesc chlg_desc;
|
||||
SecBufferDesc resp_desc;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
if(!krb5->credentials) {
|
||||
/* Query the security package for Kerberos */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Kerberos"),
|
||||
&SecurityPackage);
|
||||
if(status != SEC_E_OK) {
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
}
|
||||
|
||||
krb5->token_max = SecurityPackage->cbMaxToken;
|
||||
|
||||
/* Release the package buffer as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
|
||||
/* Generate our SPN */
|
||||
krb5->spn = Curl_sasl_build_spn(service, data->easy_conn->host.name);
|
||||
if(!krb5->spn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(userp && *userp) {
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
krb5->p_identity = &krb5->identity;
|
||||
|
||||
/* Allocate our response buffer */
|
||||
krb5->output_token = malloc(krb5->token_max);
|
||||
if(!krb5->output_token)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
/* Use the current Windows user */
|
||||
krb5->p_identity = NULL;
|
||||
|
||||
/* Allocate our credentials handle */
|
||||
krb5->credentials = malloc(sizeof(CredHandle));
|
||||
if(!krb5->credentials)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memset(krb5->credentials, 0, sizeof(CredHandle));
|
||||
|
||||
/* Acquire our credientials handle */
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT("Kerberos"),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
krb5->p_identity, NULL, NULL,
|
||||
krb5->credentials, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Allocate our new context handle */
|
||||
krb5->context = malloc(sizeof(CtxtHandle));
|
||||
if(!krb5->context)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memset(krb5->context, 0, sizeof(CtxtHandle));
|
||||
}
|
||||
else {
|
||||
/* Decode the base-64 encoded challenge message */
|
||||
if(strlen(chlg64) && *chlg64 != '=') {
|
||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
/* Setup the challenge "input" security buffer */
|
||||
chlg_desc.ulVersion = SECBUFFER_VERSION;
|
||||
chlg_desc.cBuffers = 1;
|
||||
chlg_desc.pBuffers = &chlg_buf;
|
||||
chlg_buf.BufferType = SECBUFFER_TOKEN;
|
||||
chlg_buf.pvBuffer = chlg;
|
||||
chlg_buf.cbBuffer = curlx_uztoul(chlglen);
|
||||
}
|
||||
|
||||
/* Setup the response "output" security buffer */
|
||||
resp_desc.ulVersion = SECBUFFER_VERSION;
|
||||
resp_desc.cBuffers = 1;
|
||||
resp_desc.pBuffers = &resp_buf;
|
||||
resp_buf.BufferType = SECBUFFER_TOKEN;
|
||||
resp_buf.pvBuffer = krb5->output_token;
|
||||
resp_buf.cbBuffer = curlx_uztoul(krb5->token_max);
|
||||
|
||||
/* Generate our challenge-response message */
|
||||
status = s_pSecFn->InitializeSecurityContext(krb5->credentials,
|
||||
chlg ? krb5->context : NULL,
|
||||
krb5->spn,
|
||||
(mutual_auth ?
|
||||
ISC_REQ_MUTUAL_AUTH : 0),
|
||||
0, SECURITY_NATIVE_DREP,
|
||||
chlg ? &chlg_desc : NULL, 0,
|
||||
&context,
|
||||
&resp_desc, &attrs,
|
||||
&tsDummy);
|
||||
|
||||
if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
if(memcmp(&context, krb5->context, sizeof(context))) {
|
||||
s_pSecFn->DeleteSecurityContext(krb5->context);
|
||||
|
||||
memcpy(krb5->context, &context, sizeof(context));
|
||||
}
|
||||
|
||||
if(resp_buf.cbBuffer) {
|
||||
/* Base64 encode the response */
|
||||
result = Curl_base64_encode(data, (char *)resp_buf.pvBuffer,
|
||||
resp_buf.cbBuffer, outptr, outlen);
|
||||
}
|
||||
|
||||
/* Free the decoded challenge */
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_create_gssapi_security_message()
|
||||
*
|
||||
* This is used to generate an already encoded GSSAPI (Kerberos V5) security
|
||||
* token message ready for sending to the recipient.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* chlg64 [in] - Pointer to the optional base64 encoded challenge message.
|
||||
* krb5 [in/out] - The gssapi data struct being used and modified.
|
||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
|
||||
const char *chlg64,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t offset = 0;
|
||||
size_t chlglen = 0;
|
||||
size_t messagelen = 0;
|
||||
size_t appdatalen = 0;
|
||||
unsigned char *chlg = NULL;
|
||||
unsigned char *trailer = NULL;
|
||||
unsigned char *message = NULL;
|
||||
unsigned char *padding = NULL;
|
||||
unsigned char *appdata = NULL;
|
||||
SecBuffer input_buf[2];
|
||||
SecBuffer wrap_buf[3];
|
||||
SecBufferDesc input_desc;
|
||||
SecBufferDesc wrap_desc;
|
||||
unsigned long indata = 0;
|
||||
unsigned long outdata = 0;
|
||||
unsigned long qop = 0;
|
||||
unsigned long sec_layer = 0;
|
||||
unsigned long max_size = 0;
|
||||
SecPkgContext_Sizes sizes;
|
||||
SecPkgCredentials_Names names;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
/* TODO: Verify the unicodeness of this function */
|
||||
|
||||
/* Decode the base-64 encoded input message */
|
||||
if(strlen(chlg64) && *chlg64 != '=') {
|
||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg)
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
/* Get our response size information */
|
||||
status = s_pSecFn->QueryContextAttributes(krb5->context,
|
||||
SECPKG_ATTR_SIZES,
|
||||
&sizes);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Get the fully qualified username back from the context */
|
||||
status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials,
|
||||
SECPKG_CRED_ATTR_NAMES,
|
||||
&names);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
/* Setup the "input" security buffer */
|
||||
input_desc.ulVersion = SECBUFFER_VERSION;
|
||||
input_desc.cBuffers = 2;
|
||||
input_desc.pBuffers = input_buf;
|
||||
input_buf[0].BufferType = SECBUFFER_STREAM;
|
||||
input_buf[0].pvBuffer = chlg;
|
||||
input_buf[0].cbBuffer = curlx_uztoul(chlglen);
|
||||
input_buf[1].BufferType = SECBUFFER_DATA;
|
||||
input_buf[1].pvBuffer = NULL;
|
||||
input_buf[1].cbBuffer = 0;
|
||||
|
||||
/* Decrypt in the inbound challenge obtaining the qop */
|
||||
status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Not 4 octets long to fail as per RFC4752 Section 3.1 */
|
||||
if(input_buf[1].cbBuffer != 4) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Copy the data out into a coinput_bufnvenient variable and free the SSPI
|
||||
allocated buffer as it is not required anymore */
|
||||
memcpy(&indata, input_buf[1].pvBuffer, 4);
|
||||
s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer);
|
||||
|
||||
/* Extract the security layer */
|
||||
sec_layer = indata & 0x000000FF;
|
||||
if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Extract the maximum message size the server can receive */
|
||||
max_size = ntohl(indata & 0xFFFFFF00);
|
||||
if(max_size > 0) {
|
||||
/* The server has told us it supports a maximum receive buffer, however, as
|
||||
we don't require one unless we are encrypting data we, tell the server
|
||||
our receive buffer is zero. */
|
||||
max_size = 0;
|
||||
}
|
||||
|
||||
outdata = htonl(max_size) | sec_layer;
|
||||
|
||||
/* Allocate the trailer */
|
||||
trailer = malloc(sizes.cbSecurityTrailer);
|
||||
if(!trailer) {
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Allocate our message */
|
||||
messagelen = 4 + strlen(names.sUserName) + 1;
|
||||
message = malloc(messagelen);
|
||||
if(!message) {
|
||||
Curl_safefree(trailer);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the message with the security layer, client supported receive
|
||||
message size and authorization identity including the 0x00 based
|
||||
terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
|
||||
identity is not terminated with the zero-valued (%x00) octet." it seems
|
||||
necessary to include it. */
|
||||
memcpy(message, &outdata, 4);
|
||||
strcpy((char *)message + 4, names.sUserName);
|
||||
|
||||
/* Allocate the padding */
|
||||
padding = malloc(sizes.cbBlockSize);
|
||||
if(!padding) {
|
||||
Curl_safefree(message);
|
||||
Curl_safefree(trailer);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Setup the "authentication data" security buffer */
|
||||
wrap_desc.ulVersion = SECBUFFER_VERSION;
|
||||
wrap_desc.cBuffers = 3;
|
||||
wrap_desc.pBuffers = wrap_buf;
|
||||
wrap_buf[0].BufferType = SECBUFFER_TOKEN;
|
||||
wrap_buf[0].pvBuffer = trailer;
|
||||
wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer;
|
||||
wrap_buf[1].BufferType = SECBUFFER_DATA;
|
||||
wrap_buf[1].pvBuffer = message;
|
||||
wrap_buf[1].cbBuffer = curlx_uztoul(messagelen);
|
||||
wrap_buf[2].BufferType = SECBUFFER_PADDING;
|
||||
wrap_buf[2].pvBuffer = padding;
|
||||
wrap_buf[2].cbBuffer = sizes.cbBlockSize;
|
||||
|
||||
/* Encrypt the data */
|
||||
status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT,
|
||||
&wrap_desc, 0);
|
||||
if(status != SEC_E_OK) {
|
||||
Curl_safefree(padding);
|
||||
Curl_safefree(message);
|
||||
Curl_safefree(trailer);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Allocate the encryption (wrap) buffer */
|
||||
appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer +
|
||||
wrap_buf[2].cbBuffer;
|
||||
appdata = malloc(appdatalen);
|
||||
if(!appdata) {
|
||||
Curl_safefree(padding);
|
||||
Curl_safefree(message);
|
||||
Curl_safefree(trailer);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the encryption buffer */
|
||||
memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer);
|
||||
offset += wrap_buf[0].cbBuffer;
|
||||
memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer);
|
||||
offset += wrap_buf[1].cbBuffer;
|
||||
memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer);
|
||||
|
||||
/* Base64 encode the response */
|
||||
result = Curl_base64_encode(data, (char *)appdata, appdatalen, outptr,
|
||||
outlen);
|
||||
|
||||
/* Free all of our local buffers */
|
||||
Curl_safefree(appdata);
|
||||
Curl_safefree(padding);
|
||||
Curl_safefree(message);
|
||||
Curl_safefree(trailer);
|
||||
Curl_safefree(chlg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
|
||||
{
|
||||
/* Free the context */
|
||||
if(krb5->context) {
|
||||
s_pSecFn->DeleteSecurityContext(krb5->context);
|
||||
free(krb5->context);
|
||||
krb5->context = NULL;
|
||||
}
|
||||
|
||||
/* Free the credientials handle */
|
||||
if(krb5->credentials) {
|
||||
s_pSecFn->FreeCredentialsHandle(krb5->credentials);
|
||||
free(krb5->credentials);
|
||||
krb5->credentials = NULL;
|
||||
}
|
||||
|
||||
/* Free our identity */
|
||||
Curl_sspi_free_identity(krb5->p_identity);
|
||||
krb5->p_identity = NULL;
|
||||
|
||||
/* Free the SPN and output token */
|
||||
Curl_safefree(krb5->spn);
|
||||
Curl_safefree(krb5->output_token);
|
||||
|
||||
/* Reset any variables */
|
||||
krb5->token_max = 0;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
@@ -610,7 +610,7 @@ int netware_init(void);
|
||||
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_HTTP_NEGOTIATE
|
||||
#define USE_SPNEGO
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be done */
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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
|
||||
@@ -304,5 +304,12 @@ extern PSecurityFunctionTable s_pSecFn;
|
||||
(unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions required from ntsecapi.h are directly provided below this point
|
||||
* to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
|
||||
*/
|
||||
#define KERB_WRAP_NO_ENCRYPT 0x80000001
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* HEADER_CURL_SSPI_H */
|
||||
|
@@ -4470,8 +4470,8 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, -1);
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
ftpc->ctl_valid = TRUE; /* starts good */
|
||||
|
||||
|
@@ -285,6 +285,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
struct curl_tlssessioninfo *tsi = &data->tsi;
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
unsigned int sockindex = 0;
|
||||
void *internals = NULL;
|
||||
|
||||
*tsip = tsi;
|
||||
tsi->backend = CURLSSLBACKEND_NONE;
|
||||
@@ -303,25 +304,24 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
|
||||
/* Return the TLS session information from the relevant backend */
|
||||
#ifdef USE_SSLEAY
|
||||
tsi->backend = CURLSSLBACKEND_OPENSSL;
|
||||
tsi->internals = conn->ssl[sockindex].ctx;
|
||||
internals = conn->ssl[sockindex].ctx;
|
||||
#endif
|
||||
#ifdef USE_GNUTLS
|
||||
tsi->backend = CURLSSLBACKEND_GNUTLS;
|
||||
tsi->internals = conn->ssl[sockindex].session;
|
||||
internals = conn->ssl[sockindex].session;
|
||||
#endif
|
||||
#ifdef USE_NSS
|
||||
tsi->backend = CURLSSLBACKEND_NSS;
|
||||
tsi->internals = conn->ssl[sockindex].handle;
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
#ifdef USE_QSOSSL
|
||||
tsi->backend = CURLSSLBACKEND_QSOSSL;
|
||||
tsi->internals = conn->ssl[sockindex].handle;
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
#ifdef USE_GSKIT
|
||||
tsi->backend = CURLSSLBACKEND_GSKIT;
|
||||
tsi->internals = conn->ssl[sockindex].handle;
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
if(internals) {
|
||||
tsi->backend = Curl_ssl_backend();
|
||||
tsi->internals = internals;
|
||||
}
|
||||
/* NOTE: For other SSL backends, it is not immediately clear what data
|
||||
to return from 'struct ssl_connect_data'; thus, for now we keep the
|
||||
backend as CURLSSLBACKEND_NONE in those cases, which should be
|
||||
|
71
lib/hostip.c
71
lib/hostip.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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
|
||||
@@ -318,6 +318,48 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
sigjmp_buf curl_jmpenv;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
|
||||
*
|
||||
* Curl_resolv() checks initially and multi_runsingle() checks each time
|
||||
* it discovers the handle in the state WAITRESOLVE whether the hostname
|
||||
* has already been resolved and the address has already been stored in
|
||||
* the DNS cache. This short circuits waiting for a lot of pending
|
||||
* lookups for the same hostname requested by different handles.
|
||||
*
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port, int *stale)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return dns;
|
||||
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
*stale = remove_entry_if_stale(data, dns);
|
||||
if(*stale)
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
@@ -403,39 +445,22 @@ int Curl_resolv(struct connectdata *conn,
|
||||
int port,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result;
|
||||
int rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
int stale, rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return rc;
|
||||
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
|
||||
dns = Curl_fetch_addr(conn, hostname, port, &stale);
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
infof(data, "Hostname was %sfound in DNS cache\n", dns?"":"NOT ");
|
||||
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
if(remove_entry_if_stale(data, dns)) {
|
||||
infof(data, "Hostname was %sfound in DNS cache\n", dns||stale?"":"NOT ");
|
||||
if(stale)
|
||||
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
}
|
||||
|
||||
|
||||
if(dns) {
|
||||
dns->inuse++; /* we use it! */
|
||||
|
11
lib/hostip.h
11
lib/hostip.h
@@ -171,6 +171,17 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
const char *Curl_printable_address(const Curl_addrinfo *ip,
|
||||
char *buf, size_t bufsize);
|
||||
|
||||
/*
|
||||
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
|
||||
*
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port,
|
||||
int *stale);
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
*
|
||||
|
92
lib/http.c
92
lib/http.c
@@ -328,8 +328,8 @@ static bool pickoneauth(struct auth *pick)
|
||||
|
||||
/* The order of these checks is highly relevant, as this will be the order
|
||||
of preference in case of the existence of multiple accepted types. */
|
||||
if(avail & CURLAUTH_GSSNEGOTIATE)
|
||||
pick->picked = CURLAUTH_GSSNEGOTIATE;
|
||||
if(avail & CURLAUTH_NEGOTIATE)
|
||||
pick->picked = CURLAUTH_NEGOTIATE;
|
||||
else if(avail & CURLAUTH_DIGEST)
|
||||
pick->picked = CURLAUTH_DIGEST;
|
||||
else if(avail & CURLAUTH_NTLM)
|
||||
@@ -557,7 +557,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *auth=NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
#endif
|
||||
@@ -567,11 +567,11 @@ output_auth_headers(struct connectdata *conn,
|
||||
(void)path;
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
#ifdef USE_SPNEGO
|
||||
negdata->state = GSS_AUTHNONE;
|
||||
if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
|
||||
if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
|
||||
negdata->context && !GSS_ERROR(negdata->status)) {
|
||||
auth="GSS-Negotiate";
|
||||
auth="Negotiate";
|
||||
result = Curl_output_negotiate(conn, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
@@ -737,6 +737,10 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
*/
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
#endif
|
||||
unsigned long *availp;
|
||||
struct auth *authp;
|
||||
|
||||
@@ -767,21 +771,14 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
*/
|
||||
|
||||
while(*auth) {
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
if(checkprefix("GSS-Negotiate", auth) ||
|
||||
checkprefix("Negotiate", auth)) {
|
||||
#ifdef USE_SPNEGO
|
||||
if(checkprefix("Negotiate", auth)) {
|
||||
int neg;
|
||||
*availp |= CURLAUTH_GSSNEGOTIATE;
|
||||
authp->avail |= CURLAUTH_GSSNEGOTIATE;
|
||||
*availp |= CURLAUTH_NEGOTIATE;
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
|
||||
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
|
||||
if(data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* if we sent GSS authentication in the outgoing request and we get
|
||||
this back, we're in trouble */
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
else if(data->state.negotiate.state == GSS_AUTHNONE) {
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
|
||||
neg = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(neg == 0) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
@@ -789,8 +786,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received GSS auth info and we dealt with it fine */
|
||||
data->state.negotiate.state = GSS_AUTHRECV;
|
||||
/* we received a GSS auth token and we dealt with it fine */
|
||||
negdata->state = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
@@ -923,14 +920,6 @@ static int http_should_fail(struct connectdata *conn)
|
||||
if(httpcode < 400)
|
||||
return 0;
|
||||
|
||||
if(data->state.resume_from &&
|
||||
(data->set.httpreq==HTTPREQ_GET) &&
|
||||
(httpcode == 416)) {
|
||||
/* "Requested Range Not Satisfiable", just proceed and
|
||||
pretend this is no error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Any code >= 400 that's not 401 or 407 is always
|
||||
** a terminal error
|
||||
@@ -1443,6 +1432,12 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
if(data->state.proxyneg.state == GSS_AUTHSENT ||
|
||||
data->state.negotiate.state == GSS_AUTHSENT)
|
||||
Curl_cleanup_negotiate(data);
|
||||
#endif
|
||||
|
||||
/* set the proper values (possibly modified on POST) */
|
||||
conn->fread_func = data->set.fread_func; /* restore */
|
||||
conn->fread_in = data->set.in; /* restore */
|
||||
@@ -1522,10 +1517,6 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
const char *ptr;
|
||||
data->state.expect100header = FALSE; /* default to false unless it is set
|
||||
to TRUE below */
|
||||
if(conn->httpversion == 20) {
|
||||
/* We don't use Expect in HTTP2 */
|
||||
return CURLE_OK;
|
||||
}
|
||||
if(use_http_1_1plus(data, conn)) {
|
||||
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
|
||||
100-continue to the headers which actually speeds up post operations
|
||||
@@ -1757,8 +1748,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* TODO: add error checking here */
|
||||
Curl_http2_switched(conn);
|
||||
result = Curl_http2_switched(conn);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
case NPN_HTTP1_1:
|
||||
/* continue with HTTP/1.1 when explicitly requested */
|
||||
@@ -1770,7 +1762,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
else {
|
||||
/* prepare for a http2 request */
|
||||
Curl_http2_setup(conn);
|
||||
result = Curl_http2_setup(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
http = data->req.protop;
|
||||
@@ -2357,7 +2351,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
http->postdata = NULL; /* nothing to post at this point */
|
||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||
Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
|
||||
|
||||
/* If 'authdone' is FALSE, we must not set the write socket index to the
|
||||
Curl_transfer() call below, as we're not ready to actually upload any
|
||||
@@ -3004,8 +2998,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
|
||||
/* switch to http2 now */
|
||||
/* TODO: add error checking */
|
||||
Curl_http2_switched(conn);
|
||||
result = Curl_http2_switched(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -3536,23 +3531,30 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
/* Content-Range: bytes [num]-
|
||||
Content-Range: bytes: [num]-
|
||||
Content-Range: [num]-
|
||||
Content-Range: [asterisk]/[total]
|
||||
|
||||
The second format was added since Sun's webserver
|
||||
JavaWebServer/1.1.1 obviously sends the header this way!
|
||||
The third added since some servers use that!
|
||||
The forth means the requested range was unsatisfied.
|
||||
*/
|
||||
|
||||
char *ptr = k->p + 14;
|
||||
|
||||
/* Move forward until first digit */
|
||||
while(*ptr && !ISDIGIT(*ptr))
|
||||
/* Move forward until first digit or asterisk */
|
||||
while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
|
||||
ptr++;
|
||||
|
||||
k->offset = curlx_strtoofft(ptr, NULL, 10);
|
||||
/* if it truly stopped on a digit */
|
||||
if(ISDIGIT(*ptr)) {
|
||||
k->offset = curlx_strtoofft(ptr, NULL, 10);
|
||||
|
||||
if(data->state.resume_from == k->offset)
|
||||
/* we asked for a resume and we got it */
|
||||
k->content_range = TRUE;
|
||||
if(data->state.resume_from == k->offset)
|
||||
/* we asked for a resume and we got it */
|
||||
k->content_range = TRUE;
|
||||
}
|
||||
else
|
||||
data->state.resume_from = 0; /* get everything */
|
||||
}
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
else if(data->cookies &&
|
||||
|
@@ -169,7 +169,9 @@ struct http_conn {
|
||||
sending send_underlying; /* underlying send Curl_send callback */
|
||||
recving recv_underlying; /* underlying recv Curl_recv callback */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
Curl_send_buffer *header_recvbuf; /* store response headers */
|
||||
Curl_send_buffer *header_recvbuf; /* store response headers. We
|
||||
store non-final and final
|
||||
response headers into it. */
|
||||
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf
|
||||
fed into upper layer */
|
||||
int32_t stream_id; /* stream we are interested in */
|
||||
@@ -185,6 +187,7 @@ struct http_conn {
|
||||
const uint8_t *upload_mem; /* points to a buffer to read from */
|
||||
size_t upload_len; /* size of the buffer 'upload_mem' points to */
|
||||
size_t upload_left; /* number of bytes left to upload */
|
||||
int status_code; /* HTTP status code */
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
#endif
|
||||
|
304
lib/http2.c
304
lib/http2.c
@@ -39,7 +39,7 @@
|
||||
/* include memdebug.h last */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if (NGHTTP2_VERSION_NUM < 0x000300)
|
||||
#if (NGHTTP2_VERSION_NUM < 0x000600)
|
||||
#error too old nghttp2 version, upgrade!
|
||||
#endif
|
||||
|
||||
@@ -191,27 +191,80 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
int rv;
|
||||
size_t left, ncopy;
|
||||
|
||||
(void)session;
|
||||
(void)frame;
|
||||
infof(conn->data, "on_frame_recv() was called with header %x\n",
|
||||
frame->hd.type);
|
||||
switch(frame->hd.type) {
|
||||
case NGHTTP2_DATA:
|
||||
/* If body started, then receiving DATA is illegal. */
|
||||
if(!c->bodystarted) {
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NGHTTP2_HEADERS:
|
||||
if(frame->headers.cat != NGHTTP2_HCAT_RESPONSE)
|
||||
if(frame->headers.cat == NGHTTP2_HCAT_REQUEST)
|
||||
break;
|
||||
c->bodystarted = TRUE;
|
||||
|
||||
if(c->bodystarted) {
|
||||
/* Only valid HEADERS after body started is trailer header,
|
||||
which is not fully supported in this code. If HEADERS is not
|
||||
trailer, then it is a PROTOCOL_ERROR. */
|
||||
if((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(c->status_code == -1) {
|
||||
/* No :status header field means PROTOCOL_ERROR. */
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Only final status code signals the end of header */
|
||||
if(c->status_code / 100 != 1) {
|
||||
c->bodystarted = TRUE;
|
||||
}
|
||||
|
||||
c->status_code = -1;
|
||||
|
||||
Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
|
||||
c->nread_header_recvbuf = c->len < c->header_recvbuf->size_used ?
|
||||
c->len : c->header_recvbuf->size_used;
|
||||
|
||||
memcpy(c->mem, c->header_recvbuf->buffer, c->nread_header_recvbuf);
|
||||
left = c->header_recvbuf->size_used - c->nread_header_recvbuf;
|
||||
ncopy = c->len < left ? c->len : left;
|
||||
|
||||
c->mem += c->nread_header_recvbuf;
|
||||
c->len -= c->nread_header_recvbuf;
|
||||
memcpy(c->mem, c->header_recvbuf->buffer + c->nread_header_recvbuf, ncopy);
|
||||
c->nread_header_recvbuf += ncopy;
|
||||
|
||||
c->mem += ncopy;
|
||||
c->len -= ncopy;
|
||||
break;
|
||||
case NGHTTP2_PUSH_PROMISE:
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id, NGHTTP2_CANCEL);
|
||||
frame->push_promise.promised_stream_id,
|
||||
NGHTTP2_CANCEL);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -222,7 +275,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
|
||||
static int on_invalid_frame_recv(nghttp2_session *session,
|
||||
const nghttp2_frame *frame,
|
||||
nghttp2_error_code error_code, void *userp)
|
||||
uint32_t error_code, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
@@ -297,7 +350,7 @@ static int on_frame_not_send(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
nghttp2_error_code error_code, void *userp)
|
||||
uint32_t error_code, void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
@@ -315,20 +368,6 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_unknown_frame_recv(nghttp2_session *session,
|
||||
const uint8_t *head, size_t headlen,
|
||||
const uint8_t *payload, size_t payloadlen,
|
||||
void *userp)
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
(void)session;
|
||||
(void)head;
|
||||
(void)headlen;
|
||||
(void)payload;
|
||||
(void)payloadlen;
|
||||
infof(conn->data, "on_unknown_frame_recv() was called\n");
|
||||
return 0;
|
||||
}
|
||||
static int on_begin_headers(nghttp2_session *session,
|
||||
const nghttp2_frame *frame, void *userp)
|
||||
{
|
||||
@@ -339,6 +378,33 @@ static int on_begin_headers(nghttp2_session *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode HTTP status code. Returns -1 if no valid status code was
|
||||
decoded. */
|
||||
static int decode_status_code(const uint8_t *value, size_t len)
|
||||
{
|
||||
int i;
|
||||
int res;
|
||||
|
||||
if(len != 3) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
for(i = 0; i < 3; ++i) {
|
||||
char c = value[i];
|
||||
|
||||
if(c < '0' || c > '9') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
res *= 10;
|
||||
res += c - '0';
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static const char STATUS[] = ":status";
|
||||
|
||||
/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
|
||||
@@ -350,6 +416,10 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
{
|
||||
struct connectdata *conn = (struct connectdata *)userp;
|
||||
struct http_conn *c = &conn->proto.httpc;
|
||||
int rv;
|
||||
int goodname;
|
||||
int goodheader;
|
||||
|
||||
(void)session;
|
||||
(void)frame;
|
||||
(void)flags;
|
||||
@@ -358,45 +428,83 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(c->bodystarted) {
|
||||
/* Ignore trailer or HEADERS not mapped to HTTP semantics. The
|
||||
consequence is handled in on_frame_recv(). */
|
||||
return 0;
|
||||
}
|
||||
|
||||
goodname = nghttp2_check_header_name(name, namelen);
|
||||
goodheader = nghttp2_check_header_value(value, valuelen);
|
||||
|
||||
if(!goodname || !goodheader) {
|
||||
|
||||
infof(conn->data, "Detected bad incoming header %s%s, reset stream!\n",
|
||||
goodname?"":"name",
|
||||
goodheader?"":"value");
|
||||
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
if(namelen == sizeof(":status") - 1 &&
|
||||
memcmp(STATUS, name, namelen) == 0) {
|
||||
snprintf(c->header_recvbuf->buffer, 13, "HTTP/2.0 %s", value);
|
||||
c->header_recvbuf->buffer[12] = '\r';
|
||||
|
||||
/* :status must appear exactly once. */
|
||||
if(c->status_code != -1 ||
|
||||
(c->status_code = decode_status_code(value, valuelen)) == -1) {
|
||||
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
Curl_add_buffer(c->header_recvbuf, "HTTP/2.0 ", 9);
|
||||
Curl_add_buffer(c->header_recvbuf, value, valuelen);
|
||||
Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
/* Here we are sure that namelen > 0 because of
|
||||
nghttp2_check_header_name(). Pseudo header other than :status
|
||||
is illegal. */
|
||||
if(c->status_code == -1 || name[0] == ':') {
|
||||
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
|
||||
frame->hd.stream_id,
|
||||
NGHTTP2_PROTOCOL_ERROR);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
/* convert to a HTTP1-style header */
|
||||
infof(conn->data, "got header\n");
|
||||
Curl_add_buffer(c->header_recvbuf, name, namelen);
|
||||
Curl_add_buffer(c->header_recvbuf, ":", 1);
|
||||
Curl_add_buffer(c->header_recvbuf, value, valuelen);
|
||||
Curl_add_buffer(c->header_recvbuf, "\r\n", 2);
|
||||
|
||||
infof(conn->data, "got http2 header: %.*s: %.*s\n",
|
||||
namelen, name, valuelen, value);
|
||||
}
|
||||
|
||||
return 0; /* 0 is successful */
|
||||
}
|
||||
|
||||
/*
|
||||
* This is all callbacks nghttp2 calls
|
||||
*/
|
||||
static const nghttp2_session_callbacks callbacks = {
|
||||
send_callback, /* nghttp2_send_callback */
|
||||
NULL, /* nghttp2_recv_callback */
|
||||
on_frame_recv, /* nghttp2_on_frame_recv_callback */
|
||||
on_invalid_frame_recv, /* nghttp2_on_invalid_frame_recv_callback */
|
||||
on_data_chunk_recv, /* nghttp2_on_data_chunk_recv_callback */
|
||||
before_frame_send, /* nghttp2_before_frame_send_callback */
|
||||
on_frame_send, /* nghttp2_on_frame_send_callback */
|
||||
on_frame_not_send, /* nghttp2_on_frame_not_send_callback */
|
||||
on_stream_close, /* nghttp2_on_stream_close_callback */
|
||||
on_unknown_frame_recv, /* nghttp2_on_unknown_frame_recv_callback */
|
||||
on_begin_headers, /* nghttp2_on_begin_headers_callback */
|
||||
on_header /* nghttp2_on_header_callback */
|
||||
#if NGHTTP2_VERSION_NUM >= 0x000400
|
||||
, NULL /* nghttp2_select_padding_callback */
|
||||
#endif
|
||||
};
|
||||
|
||||
static ssize_t data_source_read_callback(nghttp2_session *session,
|
||||
int32_t stream_id,
|
||||
uint8_t *buf, size_t length,
|
||||
@@ -444,13 +552,54 @@ CURLcode Curl_http2_init(struct connectdata *conn)
|
||||
{
|
||||
if(!conn->proto.httpc.h2) {
|
||||
int rc;
|
||||
nghttp2_session_callbacks *callbacks;
|
||||
|
||||
conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
|
||||
if(conn->proto.httpc.inbuf == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
rc = nghttp2_session_callbacks_new(&callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
}
|
||||
|
||||
/* nghttp2_send_callback */
|
||||
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
|
||||
/* nghttp2_on_frame_recv_callback */
|
||||
nghttp2_session_callbacks_set_on_frame_recv_callback
|
||||
(callbacks, on_frame_recv);
|
||||
/* nghttp2_on_invalid_frame_recv_callback */
|
||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
|
||||
(callbacks, on_invalid_frame_recv);
|
||||
/* nghttp2_on_data_chunk_recv_callback */
|
||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback
|
||||
(callbacks, on_data_chunk_recv);
|
||||
/* nghttp2_before_frame_send_callback */
|
||||
nghttp2_session_callbacks_set_before_frame_send_callback
|
||||
(callbacks, before_frame_send);
|
||||
/* nghttp2_on_frame_send_callback */
|
||||
nghttp2_session_callbacks_set_on_frame_send_callback
|
||||
(callbacks, on_frame_send);
|
||||
/* nghttp2_on_frame_not_send_callback */
|
||||
nghttp2_session_callbacks_set_on_frame_not_send_callback
|
||||
(callbacks, on_frame_not_send);
|
||||
/* nghttp2_on_stream_close_callback */
|
||||
nghttp2_session_callbacks_set_on_stream_close_callback
|
||||
(callbacks, on_stream_close);
|
||||
/* nghttp2_on_begin_headers_callback */
|
||||
nghttp2_session_callbacks_set_on_begin_headers_callback
|
||||
(callbacks, on_begin_headers);
|
||||
/* nghttp2_on_header_callback */
|
||||
nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
|
||||
|
||||
/* The nghttp2 session is not yet setup, do it */
|
||||
rc = nghttp2_session_client_new(&conn->proto.httpc.h2,
|
||||
&callbacks, conn);
|
||||
callbacks, conn);
|
||||
|
||||
nghttp2_session_callbacks_del(callbacks);
|
||||
|
||||
if(rc) {
|
||||
failf(conn->data, "Couldn't initialize nghttp2!");
|
||||
return CURLE_OUT_OF_MEMORY; /* most likely at least */
|
||||
@@ -504,8 +653,8 @@ CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
}
|
||||
conn->proto.httpc.binlen = binlen;
|
||||
|
||||
result = Curl_base64_encode(conn->data, (const char *)binsettings, binlen,
|
||||
&base64, &blen);
|
||||
result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
|
||||
&base64, &blen);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@@ -536,6 +685,9 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
(void)sockindex; /* we always do HTTP2 on sockindex 0 */
|
||||
|
||||
if(httpc->closed) {
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data
|
||||
function. */
|
||||
httpc->closed = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -615,12 +767,19 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||
/* If stream is closed, return 0 to signal the http routine to close
|
||||
the connection */
|
||||
if(httpc->closed) {
|
||||
/* Reset to FALSE to prevent infinite loop in readwrite_data
|
||||
function. */
|
||||
httpc->closed = FALSE;
|
||||
return 0;
|
||||
}
|
||||
*err = CURLE_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Index where :authority header field will appear in request header
|
||||
field list. */
|
||||
#define AUTHORITY_DST_IDX 3
|
||||
|
||||
/* return number of received (decrypted) bytes */
|
||||
static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
const void *mem, size_t len, CURLcode *err)
|
||||
@@ -635,6 +794,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
nghttp2_nv *nva;
|
||||
size_t nheader;
|
||||
size_t i;
|
||||
size_t authority_idx;
|
||||
char *hdbuf = (char*)mem;
|
||||
char *end;
|
||||
nghttp2_data_provider data_prd;
|
||||
@@ -705,10 +865,13 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
hdbuf = strchr(hdbuf, 0x0a);
|
||||
++hdbuf;
|
||||
|
||||
authority_idx = 0;
|
||||
|
||||
for(i = 3; i < nheader; ++i) {
|
||||
end = strchr(hdbuf, ':');
|
||||
assert(end);
|
||||
if(end - hdbuf == 4 && Curl_raw_nequal("host", hdbuf, 4)) {
|
||||
authority_idx = i;
|
||||
nva[i].name = (unsigned char *)":authority";
|
||||
nva[i].namelen = (uint16_t)strlen((char *)nva[i].name);
|
||||
}
|
||||
@@ -739,6 +902,15 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
|
||||
}
|
||||
}
|
||||
|
||||
/* :authority must come before non-pseudo header fields */
|
||||
if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
|
||||
nghttp2_nv authority = nva[authority_idx];
|
||||
for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
|
||||
nva[i] = nva[i - 1];
|
||||
}
|
||||
nva[i] = authority;
|
||||
}
|
||||
|
||||
switch(conn->data->set.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
case HTTPREQ_POST_FORM:
|
||||
@@ -803,19 +975,19 @@ CURLcode Curl_http2_setup(struct connectdata *conn)
|
||||
httpc->upload_mem = NULL;
|
||||
httpc->upload_len = 0;
|
||||
httpc->stream_id = -1;
|
||||
httpc->status_code = -1;
|
||||
|
||||
conn->httpversion = 20;
|
||||
|
||||
/* Put place holder for status line */
|
||||
return Curl_add_buffer(httpc->header_recvbuf, "HTTP/2.0 200\r\n", 14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Curl_http2_switched(struct connectdata *conn)
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn)
|
||||
{
|
||||
/* TODO: May get CURLE_AGAIN */
|
||||
CURLcode rc;
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
int rv;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
|
||||
httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
|
||||
@@ -827,7 +999,15 @@ int Curl_http2_switched(struct connectdata *conn)
|
||||
NGHTTP2_CLIENT_CONNECTION_PREFACE,
|
||||
NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN,
|
||||
&rc);
|
||||
assert(rv == 24);
|
||||
if(rc)
|
||||
/* TODO: This may get CURLE_AGAIN */
|
||||
return rc;
|
||||
|
||||
if(rv != 24) {
|
||||
failf(data, "Only sent partial HTTP2 packet");
|
||||
return CURLE_SEND_ERROR;
|
||||
}
|
||||
|
||||
if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
|
||||
/* stream 1 is opened implicitly on upgrade */
|
||||
httpc->stream_id = 1;
|
||||
@@ -835,9 +1015,9 @@ int Curl_http2_switched(struct connectdata *conn)
|
||||
rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
|
||||
httpc->binlen, NULL);
|
||||
if(rv != 0) {
|
||||
failf(conn->data, "nghttp2_session_upgrade() failed: %s(%d)",
|
||||
failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
|
||||
nghttp2_strerror(rv), rv);
|
||||
return -1;
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -845,12 +1025,12 @@ int Curl_http2_switched(struct connectdata *conn)
|
||||
httpc->stream_id = -1;
|
||||
rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||
if(rv != 0) {
|
||||
failf(conn->data, "nghttp2_submit_settings() failed: %s(%d)",
|
||||
failf(data, "nghttp2_submit_settings() failed: %s(%d)",
|
||||
nghttp2_strerror(rv), rv);
|
||||
return -1;
|
||||
return CURLE_HTTP2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -37,13 +37,13 @@ CURLcode Curl_http2_send_request(struct connectdata *conn);
|
||||
CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn);
|
||||
int Curl_http2_switched(struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_switched(x) (-1)
|
||||
#define Curl_http2_switched(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -39,19 +39,6 @@
|
||||
#include "curl_memory.h"
|
||||
#include "url.h"
|
||||
|
||||
#ifdef HAVE_SPNEGO
|
||||
# include <spnegohelp.h>
|
||||
# ifdef USE_SSLEAY
|
||||
# ifdef USE_OPENSSL
|
||||
# include <openssl/objects.h>
|
||||
# else
|
||||
# include <objects.h>
|
||||
# endif
|
||||
# else
|
||||
# error "Can't compile SPNEGO support without OpenSSL."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
@@ -61,24 +48,10 @@
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
OM_uint32 major_status, minor_status;
|
||||
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
|
||||
char name[2048];
|
||||
const char* service;
|
||||
|
||||
/* 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'.
|
||||
Change following lines if you want to use GSI */
|
||||
|
||||
/* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
|
||||
|
||||
if(neg_ctx->gss)
|
||||
service = "KHTTP";
|
||||
else
|
||||
service = "HTTP";
|
||||
const char* service = "HTTP";
|
||||
|
||||
token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
|
||||
conn->host.name) + 1;
|
||||
@@ -141,31 +114,8 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
int ret;
|
||||
size_t len;
|
||||
size_t rawlen = 0;
|
||||
bool gss;
|
||||
const char* protocol;
|
||||
CURLcode error;
|
||||
|
||||
if(checkprefix("GSS-Negotiate", header)) {
|
||||
protocol = "GSS-Negotiate";
|
||||
gss = TRUE;
|
||||
}
|
||||
else if(checkprefix("Negotiate", header)) {
|
||||
protocol = "Negotiate";
|
||||
gss = FALSE;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
if(neg_ctx->context) {
|
||||
if(neg_ctx->gss != gss) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
neg_ctx->protocol = protocol;
|
||||
neg_ctx->gss = gss;
|
||||
}
|
||||
|
||||
if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
|
||||
/* We finished successfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
@@ -178,7 +128,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
(ret = get_gss_name(conn, proxy, &neg_ctx->server_name)))
|
||||
return ret;
|
||||
|
||||
header += strlen(neg_ctx->protocol);
|
||||
header += strlen("Negotiate");
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
@@ -191,59 +141,13 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
input_token.length = rawlen;
|
||||
|
||||
DEBUGASSERT(input_token.value != NULL);
|
||||
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", header)) {
|
||||
unsigned char *spnegoToken = NULL;
|
||||
size_t spnegoTokenLength = 0;
|
||||
gss_buffer_desc mechToken = GSS_C_EMPTY_BUFFER;
|
||||
|
||||
spnegoToken = malloc(input_token.length);
|
||||
if(spnegoToken == NULL) {
|
||||
Curl_safefree(input_token.value);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(spnegoToken, input_token.value, input_token.length);
|
||||
spnegoTokenLength = input_token.length;
|
||||
|
||||
if(!parseSpnegoTargetToken(spnegoToken,
|
||||
spnegoTokenLength,
|
||||
NULL,
|
||||
NULL,
|
||||
(unsigned char**)&mechToken.value,
|
||||
&mechToken.length,
|
||||
NULL,
|
||||
NULL)) {
|
||||
Curl_safefree(spnegoToken);
|
||||
infof(data, "Parse SPNEGO Target Token failed\n");
|
||||
}
|
||||
else if(!mechToken.value || !mechToken.length) {
|
||||
Curl_safefree(spnegoToken);
|
||||
if(mechToken.value)
|
||||
gss_release_buffer(&discard_st, &mechToken);
|
||||
infof(data, "Parse SPNEGO Target Token succeeded (NULL token)\n");
|
||||
}
|
||||
else {
|
||||
Curl_safefree(spnegoToken);
|
||||
Curl_safefree(input_token.value);
|
||||
input_token.value = malloc(mechToken.length);
|
||||
if(input_token.value == NULL) {
|
||||
gss_release_buffer(&discard_st, &mechToken);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(input_token.value, mechToken.value, mechToken.length);
|
||||
input_token.length = mechToken.length;
|
||||
gss_release_buffer(&discard_st, &mechToken);
|
||||
infof(data, "Parse SPNEGO Target Token succeeded\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
major_status = Curl_gss_init_sec_context(data,
|
||||
&minor_status,
|
||||
&neg_ctx->context,
|
||||
neg_ctx->server_name,
|
||||
&Curl_spnego_mech_oid,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
&output_token,
|
||||
@@ -279,52 +183,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
CURLcode error;
|
||||
OM_uint32 discard_st;
|
||||
|
||||
#ifdef HAVE_SPNEGO /* Handle SPNEGO */
|
||||
if(checkprefix("Negotiate", neg_ctx->protocol)) {
|
||||
ASN1_OBJECT *object = NULL;
|
||||
unsigned char *responseToken = NULL;
|
||||
size_t responseTokenLength = 0;
|
||||
gss_buffer_desc spnegoToken = GSS_C_EMPTY_BUFFER;
|
||||
|
||||
responseToken = malloc(neg_ctx->output_token.length);
|
||||
if(responseToken == NULL)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
memcpy(responseToken, neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length);
|
||||
responseTokenLength = neg_ctx->output_token.length;
|
||||
|
||||
object = OBJ_txt2obj("1.2.840.113554.1.2.2", 1);
|
||||
if(!object) {
|
||||
Curl_safefree(responseToken);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!makeSpnegoInitialToken(object,
|
||||
responseToken,
|
||||
responseTokenLength,
|
||||
(unsigned char**)&spnegoToken.value,
|
||||
&spnegoToken.length)) {
|
||||
Curl_safefree(responseToken);
|
||||
ASN1_OBJECT_free(object);
|
||||
infof(conn->data, "Make SPNEGO Initial Token failed\n");
|
||||
}
|
||||
else if(!spnegoToken.value || !spnegoToken.length) {
|
||||
Curl_safefree(responseToken);
|
||||
ASN1_OBJECT_free(object);
|
||||
if(spnegoToken.value)
|
||||
gss_release_buffer(&discard_st, &spnegoToken);
|
||||
infof(conn->data, "Make SPNEGO Initial Token succeeded (NULL token)\n");
|
||||
}
|
||||
else {
|
||||
Curl_safefree(responseToken);
|
||||
ASN1_OBJECT_free(object);
|
||||
gss_release_buffer(&discard_st, &neg_ctx->output_token);
|
||||
neg_ctx->output_token.value = spnegoToken.value;
|
||||
neg_ctx->output_token.length = spnegoToken.length;
|
||||
infof(conn->data, "Make SPNEGO Initial Token succeeded\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
error = Curl_base64_encode(conn->data,
|
||||
neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length,
|
||||
@@ -343,8 +201,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||
neg_ctx->protocol, encoded);
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
encoded);
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
@@ -355,7 +213,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
}
|
||||
|
||||
Curl_safefree(encoded);
|
||||
Curl_cleanup_negotiate(conn->data);
|
||||
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
@@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
#ifdef USE_SPNEGO
|
||||
|
||||
/* this is for Negotiate header input */
|
||||
int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
@@ -37,6 +37,6 @@ void Curl_cleanup_negotiate(struct SessionHandle *data);
|
||||
#define GSS_ERROR(status) (status & 0x80000000)
|
||||
#endif
|
||||
|
||||
#endif /* USE_HTTP_NEGOTIATE */
|
||||
#endif /* USE_SPNEGO */
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
|
||||
|
@@ -24,13 +24,14 @@
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_HTTP_NEGOTIATE)
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_multibyte.h"
|
||||
@@ -41,84 +42,47 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, bool proxy,
|
||||
struct negotiatedata *neg_ctx)
|
||||
{
|
||||
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'.
|
||||
Change following lines if you want to use GSI */
|
||||
|
||||
/* IIS uses the <service>@<fqdn> form but uses 'http' as the service name,
|
||||
and SSPI then generates an NTLM token. When using <service>/<fqdn> a
|
||||
Kerberos token is generated. */
|
||||
|
||||
if(neg_ctx->gss)
|
||||
service = "KHTTP";
|
||||
else
|
||||
service = "HTTP";
|
||||
|
||||
length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
|
||||
conn->host.name) + 1;
|
||||
if(length + 1 > sizeof(neg_ctx->server_name))
|
||||
return EMSGSIZE;
|
||||
|
||||
snprintf(neg_ctx->server_name, sizeof(neg_ctx->server_name), "%s/%s",
|
||||
service, proxy ? conn->proxy.name : conn->host.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returning zero (0) means success, everything else is treated as "failure"
|
||||
with no care exactly what the failure was */
|
||||
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;
|
||||
BYTE *input_token = 0;
|
||||
BYTE *input_token = NULL;
|
||||
SecBufferDesc out_buff_desc;
|
||||
SecBuffer out_sec_buff;
|
||||
SecBufferDesc in_buff_desc;
|
||||
SecBuffer in_sec_buff;
|
||||
unsigned long context_attributes;
|
||||
TimeStamp lifetime;
|
||||
TCHAR *sname;
|
||||
int ret;
|
||||
size_t len = 0, input_token_len = 0;
|
||||
bool gss = FALSE;
|
||||
const char* protocol;
|
||||
CURLcode error;
|
||||
|
||||
if(checkprefix("GSS-Negotiate", header)) {
|
||||
protocol = "GSS-Negotiate";
|
||||
gss = TRUE;
|
||||
}
|
||||
else if(checkprefix("Negotiate", header)) {
|
||||
protocol = "Negotiate";
|
||||
gss = FALSE;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
/* Point to the username and password */
|
||||
const char *userp;
|
||||
const char *passwdp;
|
||||
|
||||
if(neg_ctx->context) {
|
||||
if(neg_ctx->gss != gss) {
|
||||
return -1;
|
||||
}
|
||||
/* Point to the correct struct with this */
|
||||
struct negotiatedata *neg_ctx;
|
||||
|
||||
if(proxy) {
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
neg_ctx = &conn->data->state.proxyneg;
|
||||
}
|
||||
else {
|
||||
neg_ctx->protocol = protocol;
|
||||
neg_ctx->gss = gss;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
neg_ctx = &conn->data->state.negotiate;
|
||||
}
|
||||
|
||||
/* Not set means empty */
|
||||
if(!userp)
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp = "";
|
||||
|
||||
if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
|
||||
/* We finished successfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
@@ -127,10 +91,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(0 == strlen(neg_ctx->server_name)) {
|
||||
ret = get_gss_name(conn, proxy, neg_ctx);
|
||||
if(ret)
|
||||
return ret;
|
||||
if(!neg_ctx->server_name) {
|
||||
/* Check proxy auth requested but no given proxy name */
|
||||
if(proxy && !conn->proxy.name)
|
||||
return -1;
|
||||
|
||||
/* Generate our SPN */
|
||||
neg_ctx->server_name = Curl_sasl_build_spn("HTTP",
|
||||
proxy ? conn->proxy.name :
|
||||
conn->host.name);
|
||||
if(!neg_ctx->server_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!neg_ctx->output_token) {
|
||||
@@ -148,81 +119,91 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
|
||||
/* Obtain the input token, if any */
|
||||
header += strlen(neg_ctx->protocol);
|
||||
header += strlen("Negotiate");
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
if(!len) {
|
||||
/* first call in a new negotation, we have to acquire credentials,
|
||||
and allocate memory for the context */
|
||||
/* Is this the first call in a new negotiation? */
|
||||
if(neg_ctx->context) {
|
||||
/* The server rejected our authentication and hasn't suppled any more
|
||||
negotiation mechanisms */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We have to acquire credentials and allocate memory for the context */
|
||||
neg_ctx->credentials = malloc(sizeof(CredHandle));
|
||||
neg_ctx->context = malloc(sizeof(CtxtHandle));
|
||||
|
||||
if(!neg_ctx->credentials || !neg_ctx->context)
|
||||
return -1;
|
||||
|
||||
if(userp && *userp) {
|
||||
/* Populate our identity structure */
|
||||
error = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
|
||||
if(error)
|
||||
return -1;
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
neg_ctx->p_identity = &neg_ctx->identity;
|
||||
}
|
||||
else
|
||||
/* Use the current Windows user */
|
||||
neg_ctx->p_identity = NULL;
|
||||
|
||||
/* Acquire our credientials handle */
|
||||
neg_ctx->status =
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT("Negotiate"),
|
||||
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
||||
NULL, NULL, neg_ctx->credentials,
|
||||
&lifetime);
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
neg_ctx->p_identity, NULL, NULL,
|
||||
neg_ctx->credentials, &lifetime);
|
||||
if(neg_ctx->status != SEC_E_OK)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
input_token = malloc(neg_ctx->max_token_length);
|
||||
if(!input_token)
|
||||
return -1;
|
||||
|
||||
error = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token,
|
||||
&input_token_len);
|
||||
if(error || input_token_len == 0)
|
||||
if(error || !input_token_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* prepare the output buffers, and input buffers if present */
|
||||
out_buff_desc.ulVersion = 0;
|
||||
/* Setup the "output" security buffer */
|
||||
out_buff_desc.ulVersion = SECBUFFER_VERSION;
|
||||
out_buff_desc.cBuffers = 1;
|
||||
out_buff_desc.pBuffers = &out_sec_buff;
|
||||
|
||||
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
|
||||
out_sec_buff.BufferType = SECBUFFER_TOKEN;
|
||||
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
||||
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
|
||||
|
||||
|
||||
/* Setup the "input" security buffer if present */
|
||||
if(input_token) {
|
||||
in_buff_desc.ulVersion = 0;
|
||||
in_buff_desc.ulVersion = SECBUFFER_VERSION;
|
||||
in_buff_desc.cBuffers = 1;
|
||||
in_buff_desc.pBuffers = &in_sec_buff;
|
||||
|
||||
in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
|
||||
in_sec_buff.BufferType = SECBUFFER_TOKEN;
|
||||
in_sec_buff.pvBuffer = input_token;
|
||||
in_sec_buff.cbBuffer = curlx_uztoul(input_token_len);
|
||||
}
|
||||
|
||||
sname = Curl_convert_UTF8_to_tchar(neg_ctx->server_name);
|
||||
if(!sname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Generate our message */
|
||||
neg_ctx->status = s_pSecFn->InitializeSecurityContext(
|
||||
neg_ctx->credentials,
|
||||
input_token ? neg_ctx->context : 0,
|
||||
sname,
|
||||
input_token ? neg_ctx->context : NULL,
|
||||
neg_ctx->server_name,
|
||||
ISC_REQ_CONFIDENTIALITY,
|
||||
0,
|
||||
SECURITY_NATIVE_DREP,
|
||||
input_token ? &in_buff_desc : 0,
|
||||
input_token ? &in_buff_desc : NULL,
|
||||
0,
|
||||
neg_ctx->context,
|
||||
&out_buff_desc,
|
||||
&context_attributes,
|
||||
&lifetime);
|
||||
|
||||
Curl_unicodefree(sname);
|
||||
Curl_safefree(input_token);
|
||||
|
||||
if(GSS_ERROR(neg_ctx->status))
|
||||
return -1;
|
||||
@@ -257,18 +238,21 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(len == 0)
|
||||
if(!len)
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
|
||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||
neg_ctx->protocol, encoded);
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
encoded);
|
||||
|
||||
if(proxy)
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
else
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
}
|
||||
free(encoded);
|
||||
Curl_cleanup_negotiate (conn->data);
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -277,21 +261,22 @@ static void cleanup(struct negotiatedata *neg_ctx)
|
||||
if(neg_ctx->context) {
|
||||
s_pSecFn->DeleteSecurityContext(neg_ctx->context);
|
||||
free(neg_ctx->context);
|
||||
neg_ctx->context = 0;
|
||||
neg_ctx->context = NULL;
|
||||
}
|
||||
|
||||
if(neg_ctx->credentials) {
|
||||
s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
|
||||
free(neg_ctx->credentials);
|
||||
neg_ctx->credentials = 0;
|
||||
}
|
||||
|
||||
if(neg_ctx->output_token) {
|
||||
free(neg_ctx->output_token);
|
||||
neg_ctx->output_token = 0;
|
||||
neg_ctx->credentials = NULL;
|
||||
}
|
||||
|
||||
neg_ctx->max_token_length = 0;
|
||||
Curl_safefree(neg_ctx->output_token);
|
||||
|
||||
Curl_safefree(neg_ctx->server_name);
|
||||
|
||||
Curl_sspi_free_identity(neg_ctx->p_identity);
|
||||
neg_ctx->p_identity = NULL;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
@@ -300,6 +285,6 @@ void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
cleanup(&data->state.proxyneg);
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_HTTP_NEGOTIATE */
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
@@ -98,8 +98,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result;
|
||||
long timeout =
|
||||
data->set.timeout?data->set.timeout:PROXY_TIMEOUT; /* in milliseconds */
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
curl_off_t cl=0;
|
||||
bool closeConnection = FALSE;
|
||||
@@ -223,14 +221,25 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return result;
|
||||
|
||||
conn->tunnel_state[sockindex] = TUNNEL_CONNECT;
|
||||
|
||||
/* now we've issued the CONNECT and we're waiting to hear back, return
|
||||
and get called again polling-style */
|
||||
return CURLE_OK;
|
||||
|
||||
} /* END CONNECT PHASE */
|
||||
|
||||
{ /* BEGIN NEGOTIATION PHASE */
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
DEBUGF(infof(data,
|
||||
"Read response immediately from proxy CONNECT\n"));
|
||||
}
|
||||
|
||||
/* at this point, the tunnel_connecting phase is over. */
|
||||
|
||||
{ /* READING RESPONSE PHASE */
|
||||
size_t nread; /* total size read */
|
||||
int perline; /* count bytes per line */
|
||||
int keepon=TRUE;
|
||||
@@ -247,9 +256,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||
|
||||
/* if timeout is requested, find out how much remaining time we have */
|
||||
check = timeout - /* timeout time */
|
||||
Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
|
||||
check = Curl_timeleft(data, NULL, TRUE);
|
||||
if(check <= 0) {
|
||||
failf(data, "Proxy CONNECT aborted due to timeout");
|
||||
error = SELECT_TIMEOUT; /* already too little time */
|
||||
@@ -279,6 +286,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* proxy auth was requested and there was proxy auth available,
|
||||
then deem this as "mere" proxy disconnect */
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Proxy CONNECT connection closed");
|
||||
}
|
||||
else {
|
||||
error = SELECT_ERROR;
|
||||
@@ -527,7 +535,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
break;
|
||||
}
|
||||
} /* END NEGOTIATION PHASE */
|
||||
} /* END READING RESPONSE PHASE */
|
||||
|
||||
/* If we are supposed to continue and request a new URL, which basically
|
||||
* means the HTTP authentication is still going on so if the tunnel
|
||||
@@ -542,22 +550,33 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
} while(data->req.newurl);
|
||||
|
||||
if(200 != data->req.httpcode) {
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
|
||||
if(closeConnection && data->req.newurl)
|
||||
if(closeConnection && data->req.newurl) {
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
|
||||
if(data->req.newurl) {
|
||||
/* this won't be used anymore for the CONNECT so free it now */
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
infof(data, "Connect me again please\n");
|
||||
}
|
||||
else {
|
||||
if(data->req.newurl) {
|
||||
/* this won't be used anymore for the CONNECT so free it now */
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
}
|
||||
/* failure, close this connection to avoid re-use */
|
||||
connclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/* to back to init state */
|
||||
conn->tunnel_state[sockindex] = TUNNEL_INIT;
|
||||
|
||||
return CURLE_RECV_ERROR;
|
||||
if(conn->bits.proxy_connect_closed)
|
||||
/* this is not an error, just part of the connection negotiation */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
failf(data, "Received HTTP code %d from proxy after CONNECT",
|
||||
data->req.httpcode);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
|
||||
|
196
lib/imap.c
196
lib/imap.c
@@ -24,6 +24,7 @@
|
||||
* RFC3501 IMAPv4 protocol
|
||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||
* RFC4616 PLAIN authentication
|
||||
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
|
||||
* RFC4959 IMAP Extension for SASL Initial Client Response
|
||||
* RFC5092 IMAP URL Scheme
|
||||
* RFC6749 OAuth 2.0 Authorization Framework
|
||||
@@ -433,6 +434,9 @@ static void state(struct connectdata *conn, imapstate newstate)
|
||||
"AUTHENTICATE_DIGESTMD5_RESP",
|
||||
"AUTHENTICATE_NTLM",
|
||||
"AUTHENTICATE_NTLM_TYPE2MSG",
|
||||
"AUTHENTICATE_GSSAPI",
|
||||
"AUTHENTICATE_GSSAPI_TOKEN",
|
||||
"AUTHENTICATE_GSSAPI_NO_DATA",
|
||||
"AUTHENTICATE_XOAUTH2",
|
||||
"AUTHENTICATE_CANCEL",
|
||||
"AUTHENTICATE_FINAL",
|
||||
@@ -1296,6 +1300,158 @@ static CURLcode imap_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
/* For AUTHENTICATE GSSAPI (without initial response) responses */
|
||||
static CURLcode imap_state_auth_gssapi_resp(struct connectdata *conn,
|
||||
int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
size_t len = 0;
|
||||
char *respmsg = NULL;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != '+') {
|
||||
failf(data, "Access denied: %d", imapcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Create the initial response message */
|
||||
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd, "imap",
|
||||
imapc->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
&respmsg, &len);
|
||||
if(!result && respmsg) {
|
||||
/* Send the message */
|
||||
result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
|
||||
|
||||
if(!result)
|
||||
state(conn, IMAP_AUTHENTICATE_GSSAPI_TOKEN);
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For AUTHENTICATE GSSAPI user token responses */
|
||||
static CURLcode imap_state_auth_gssapi_token_resp(struct connectdata *conn,
|
||||
int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct imap_conn *imapc = &conn->proto.imapc;
|
||||
char *chlgmsg = NULL;
|
||||
char *respmsg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != '+') {
|
||||
failf(data, "Access denied: %d", imapcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Get the challenge message */
|
||||
imap_get_message(data->state.buffer, &chlgmsg);
|
||||
|
||||
if(imapc->mutual_auth)
|
||||
/* Decode the user token challenge and create the optional response
|
||||
message */
|
||||
result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
|
||||
imapc->mutual_auth,
|
||||
chlgmsg, &conn->krb5,
|
||||
&respmsg, &len);
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
|
||||
&conn->krb5,
|
||||
&respmsg, &len);
|
||||
|
||||
if(result) {
|
||||
if(result == CURLE_BAD_CONTENT_ENCODING) {
|
||||
/* Send the cancellation */
|
||||
result = Curl_pp_sendf(&imapc->pp, "%s", "*");
|
||||
|
||||
if(!result)
|
||||
state(conn, IMAP_AUTHENTICATE_CANCEL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Send the response */
|
||||
if(respmsg)
|
||||
result = Curl_pp_sendf(&imapc->pp, "%s", respmsg);
|
||||
else
|
||||
result = Curl_pp_sendf(&imapc->pp, "%s", "");
|
||||
|
||||
if(!result)
|
||||
state(conn, (imapc->mutual_auth ? IMAP_AUTHENTICATE_GSSAPI_NO_DATA :
|
||||
IMAP_AUTHENTICATE_FINAL));
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For AUTHENTICATE GSSAPI no data responses */
|
||||
static CURLcode imap_state_auth_gssapi_no_data_resp(struct connectdata *conn,
|
||||
int imapcode,
|
||||
imapstate instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *chlgmsg = NULL;
|
||||
char *respmsg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != '+') {
|
||||
failf(data, "Access denied: %d", imapcode);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Get the challenge message */
|
||||
imap_get_message(data->state.buffer, &chlgmsg);
|
||||
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
|
||||
&conn->krb5,
|
||||
&respmsg, &len);
|
||||
if(result) {
|
||||
if(result == CURLE_BAD_CONTENT_ENCODING) {
|
||||
/* Send the cancellation */
|
||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
|
||||
|
||||
if(!result)
|
||||
state(conn, IMAP_AUTHENTICATE_CANCEL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Send the response */
|
||||
if(respmsg) {
|
||||
result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", respmsg);
|
||||
|
||||
if(!result)
|
||||
state(conn, IMAP_AUTHENTICATE_FINAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For AUTHENTICATE XOAUTH2 (without initial response) responses */
|
||||
static CURLcode imap_state_auth_xoauth2_resp(struct connectdata *conn,
|
||||
int imapcode,
|
||||
@@ -1506,7 +1662,7 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(imapcode != '*') {
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
state(conn, IMAP_STOP);
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
|
||||
}
|
||||
@@ -1755,6 +1911,21 @@ static CURLcode imap_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
case IMAP_AUTHENTICATE_GSSAPI:
|
||||
result = imap_state_auth_gssapi_resp(conn, imapcode, imapc->state);
|
||||
break;
|
||||
|
||||
case IMAP_AUTHENTICATE_GSSAPI_TOKEN:
|
||||
result = imap_state_auth_gssapi_token_resp(conn, imapcode, imapc->state);
|
||||
break;
|
||||
|
||||
case IMAP_AUTHENTICATE_GSSAPI_NO_DATA:
|
||||
result = imap_state_auth_gssapi_no_data_resp(conn, imapcode,
|
||||
imapc->state);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case IMAP_AUTHENTICATE_XOAUTH2:
|
||||
result = imap_state_auth_xoauth2_resp(conn, imapcode, imapc->state);
|
||||
break;
|
||||
@@ -2165,8 +2336,8 @@ static CURLcode imap_regular_transfer(struct connectdata *conn,
|
||||
/* Set the progress data */
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, -1);
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
/* Carry out the perform */
|
||||
result = imap_perform(conn, &connected, dophase_done);
|
||||
@@ -2632,6 +2803,25 @@ static CURLcode imap_calc_sasl_details(struct connectdata *conn,
|
||||
|
||||
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||
security, as well as the initial response where appropriate */
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
if((imapc->authmechs & SASL_MECH_GSSAPI) &&
|
||||
(imapc->prefmech & SASL_MECH_GSSAPI)) {
|
||||
imapc->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
|
||||
|
||||
*mech = SASL_MECH_STRING_GSSAPI;
|
||||
*state1 = IMAP_AUTHENTICATE_GSSAPI;
|
||||
*state2 = IMAP_AUTHENTICATE_GSSAPI_TOKEN;
|
||||
imapc->authused = SASL_MECH_GSSAPI;
|
||||
|
||||
if(imapc->ir_supported || data->set.sasl_ir)
|
||||
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd, "imap",
|
||||
imapc->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
initresp, len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if((imapc->authmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
(imapc->prefmech & SASL_MECH_DIGEST_MD5)) {
|
||||
|
@@ -43,6 +43,9 @@ typedef enum {
|
||||
IMAP_AUTHENTICATE_DIGESTMD5_RESP,
|
||||
IMAP_AUTHENTICATE_NTLM,
|
||||
IMAP_AUTHENTICATE_NTLM_TYPE2MSG,
|
||||
IMAP_AUTHENTICATE_GSSAPI,
|
||||
IMAP_AUTHENTICATE_GSSAPI_TOKEN,
|
||||
IMAP_AUTHENTICATE_GSSAPI_NO_DATA,
|
||||
IMAP_AUTHENTICATE_XOAUTH2,
|
||||
IMAP_AUTHENTICATE_CANCEL,
|
||||
IMAP_AUTHENTICATE_FINAL,
|
||||
@@ -89,6 +92,7 @@ struct imap_conn {
|
||||
bool tls_supported; /* StartTLS capability supported by server */
|
||||
bool login_disabled; /* LOGIN command disabled by server */
|
||||
bool ir_supported; /* Initial response supported by server */
|
||||
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
|
||||
char *mailbox; /* The last selected mailbox */
|
||||
char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */
|
||||
};
|
||||
|
@@ -236,6 +236,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
|
||||
&min,
|
||||
context,
|
||||
gssname,
|
||||
&Curl_krb5_mech_oid,
|
||||
&chan,
|
||||
gssresp,
|
||||
&output_buffer,
|
||||
|
@@ -40,17 +40,15 @@ use Text::Wrap;
|
||||
|
||||
my %urls = (
|
||||
'nss' =>
|
||||
'http://mxr.mozilla.org/nss/source/lib/ckfw/builtins/certdata.txt?raw=1',
|
||||
'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt',
|
||||
'central' =>
|
||||
'http://mxr.mozilla.org/mozilla-central/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1',
|
||||
'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'aurora' =>
|
||||
'http://mxr.mozilla.org/mozilla-aurora/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1',
|
||||
'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'beta' =>
|
||||
'http://mxr.mozilla.org/mozilla-beta/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1',
|
||||
'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
'release' =>
|
||||
'http://mxr.mozilla.org/mozilla-release/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1',
|
||||
'mozilla' =>
|
||||
'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1'
|
||||
'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt',
|
||||
);
|
||||
|
||||
$opt_d = 'release';
|
||||
@@ -58,7 +56,7 @@ $opt_d = 'release';
|
||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||
my $openssl = 'openssl';
|
||||
|
||||
my $version = '1.21';
|
||||
my $version = '1.22';
|
||||
|
||||
$opt_w = 76; # default base64 encoded lines length
|
||||
|
||||
@@ -209,6 +207,28 @@ sub PARSE_CSV_PARAM($$@) {
|
||||
return @values;
|
||||
}
|
||||
|
||||
sub sha1 {
|
||||
my ($txt)=@_;
|
||||
my $sha1 = `$openssl dgst -sha1 $txt | cut '-d ' -f2`;
|
||||
chomp $sha1;
|
||||
return $sha1;
|
||||
}
|
||||
|
||||
sub oldsha1 {
|
||||
my ($crt)=@_;
|
||||
my $sha1="";
|
||||
open(C, "<$crt");
|
||||
while(<C>) {
|
||||
chomp;
|
||||
if($_ =~ /^\#\# SHA1: (.*)/) {
|
||||
$sha1 = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(C);
|
||||
return $sha1;
|
||||
}
|
||||
|
||||
if ( $opt_p !~ m/:/ ) {
|
||||
print "Error: Mozilla trust identifier list must include both purposes and levels\n";
|
||||
HELP_MESSAGE();
|
||||
@@ -238,6 +258,10 @@ my $stdout = $crt eq '-';
|
||||
my $resp;
|
||||
my $fetched;
|
||||
|
||||
my $oldsha1= oldsha1($crt);
|
||||
|
||||
print STDERR "SHA1 of old file: $oldsha1\n";
|
||||
|
||||
unless ($opt_n and -e $txt) {
|
||||
print STDERR "Downloading '$txt' ...\n" if (!$opt_q);
|
||||
my $ua = new LWP::UserAgent(agent => "$0/$version");
|
||||
@@ -257,7 +281,25 @@ unless ($opt_n and -e $txt) {
|
||||
}
|
||||
}
|
||||
|
||||
my $currentdate = scalar gmtime($fetched ? $resp->last_modified : (stat($txt))[9]);
|
||||
my $filedate = $fetched ? $resp->last_modified : (stat($txt))[9];
|
||||
my $datesrc = "as of";
|
||||
if(!$filedate) {
|
||||
# mxr.mozilla.org gave us a time, hg.mozilla.org does not!
|
||||
$filedate = time();
|
||||
$datesrc="downloaded on";
|
||||
}
|
||||
|
||||
# get the hash from the download file
|
||||
my $newsha1= sha1($txt);
|
||||
|
||||
if($oldsha1 eq $newsha1) {
|
||||
print STDERR "Downloaded file identical to previous run\'s source file. Exiting\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
print STDERR "SHA1 of new file: $newsha1\n";
|
||||
|
||||
my $currentdate = scalar gmtime($filedate);
|
||||
|
||||
my $format = $opt_t ? "plain text and " : "";
|
||||
if( $stdout ) {
|
||||
@@ -267,9 +309,9 @@ if( $stdout ) {
|
||||
}
|
||||
print CRT <<EOT;
|
||||
##
|
||||
## $crt -- Bundle of CA Root Certificates
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla as of: ${currentdate}
|
||||
## Certificate data from Mozilla ${datesrc}: ${currentdate}
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
@@ -281,6 +323,9 @@ print CRT <<EOT;
|
||||
## an Apache+mod_ssl webserver for SSL client authentication.
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl verison $version.
|
||||
## SHA1: $newsha1
|
||||
##
|
||||
|
||||
EOT
|
||||
|
||||
@@ -415,7 +460,3 @@ unless( $stdout ) {
|
||||
}
|
||||
unlink $txt if ($opt_u);
|
||||
print STDERR "Done ($certnum CA certs processed, $skipnum skipped).\n" if (!$opt_q);
|
||||
|
||||
exit;
|
||||
|
||||
|
||||
|
126
lib/multi.c
126
lib/multi.c
@@ -30,6 +30,7 @@
|
||||
#include "connect.h"
|
||||
#include "progress.h"
|
||||
#include "easyif.h"
|
||||
#include "share.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "timeval.h"
|
||||
@@ -308,6 +309,10 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
if(!multi->msglist)
|
||||
goto error;
|
||||
|
||||
multi->pending = Curl_llist_alloc(multi_freeamsg);
|
||||
if(!multi->pending)
|
||||
goto error;
|
||||
|
||||
/* allocate a new easy handle to use when closing cached connections */
|
||||
multi->closure_handle = curl_easy_init();
|
||||
if(!multi->closure_handle)
|
||||
@@ -333,6 +338,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
|
||||
Curl_close(multi->closure_handle);
|
||||
multi->closure_handle = NULL;
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
|
||||
free(multi);
|
||||
return NULL;
|
||||
@@ -1045,7 +1051,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* There was no connection available. We will go to the pending
|
||||
state and wait for an available connection. */
|
||||
multistate(data, CURLM_STATE_CONNECT_PEND);
|
||||
data->result = CURLE_OK;
|
||||
|
||||
/* add this handle to the list of connect-pending handles */
|
||||
if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data))
|
||||
data->result = CURLE_OUT_OF_MEMORY;
|
||||
else
|
||||
data->result = CURLE_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1084,9 +1095,32 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* awaiting an asynch name resolve to complete */
|
||||
{
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
struct connectdata *conn = data->easy_conn;
|
||||
int stale;
|
||||
|
||||
/* check if we have the name resolved by now */
|
||||
data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = Curl_fetch_addr(conn, conn->host.name, (int)conn->port, &stale);
|
||||
|
||||
if(dns) {
|
||||
dns->inuse++; /* we use it! */
|
||||
#ifdef CURLRES_ASYNCH
|
||||
conn->async.dns = dns;
|
||||
conn->async.done = TRUE;
|
||||
#endif
|
||||
data->result = CURLRESOLV_RESOLVED;
|
||||
infof(data, "Hostname was found in DNS cache\n");
|
||||
}
|
||||
if(stale)
|
||||
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
if(!dns)
|
||||
data->result = Curl_resolver_is_resolved(data->easy_conn, &dns);
|
||||
|
||||
/* Update sockets here, because the socket(s) may have been
|
||||
closed and the application thus needs to be told, even if it
|
||||
@@ -1137,11 +1171,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
data->result = Curl_http_connect(data->easy_conn, &protocol_connect);
|
||||
|
||||
if(data->easy_conn->bits.proxy_connect_closed) {
|
||||
/* reset the error buffer */
|
||||
if(data->set.errorbuffer)
|
||||
data->set.errorbuffer[0] = '\0';
|
||||
data->state.errorbuf = FALSE;
|
||||
|
||||
/* connect back to proxy again */
|
||||
data->result = CURLE_OK;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
@@ -1167,7 +1197,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
&protocol_connect);
|
||||
}
|
||||
|
||||
if(CURLE_OK != data->result) {
|
||||
if(data->easy_conn->bits.proxy_connect_closed) {
|
||||
/* connect back to proxy again since it was closed in a proxy CONNECT
|
||||
setup */
|
||||
data->result = CURLE_OK;
|
||||
result = CURLM_CALL_MULTI_PERFORM;
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
break;
|
||||
}
|
||||
else if(CURLE_OK != data->result) {
|
||||
/* failure detected */
|
||||
/* Just break, the cleaning up is handled all in one place */
|
||||
disconnect_conn = TRUE;
|
||||
@@ -1463,7 +1501,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_send_speed,
|
||||
data->progress.ulspeed, buffersize);
|
||||
Curl_expire(data, timeout_ms);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1479,7 +1517,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
data->set.buffer_size : BUFSIZE);
|
||||
timeout_ms = Curl_sleep_time(data->set.max_recv_speed,
|
||||
data->progress.dlspeed, buffersize);
|
||||
Curl_expire(data, timeout_ms);
|
||||
Curl_expire_latest(data, timeout_ms);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1541,7 +1579,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
/* expire the new receiving pipeline head */
|
||||
if(data->easy_conn->recv_pipe->head)
|
||||
Curl_expire(data->easy_conn->recv_pipe->head->ptr, 1);
|
||||
Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1);
|
||||
|
||||
/* Check if we can move pending requests to send pipe */
|
||||
Curl_multi_process_pending_handles(multi);
|
||||
@@ -1843,18 +1881,12 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
multi->closure_handle->dns.hostcache);
|
||||
|
||||
Curl_close(multi->closure_handle);
|
||||
multi->closure_handle = NULL;
|
||||
}
|
||||
|
||||
Curl_hash_destroy(multi->sockhash);
|
||||
multi->sockhash = NULL;
|
||||
|
||||
Curl_conncache_destroy(multi->conn_cache);
|
||||
multi->conn_cache = NULL;
|
||||
|
||||
/* remove the pending list of messages */
|
||||
Curl_llist_destroy(multi->msglist, NULL);
|
||||
multi->msglist = NULL;
|
||||
Curl_llist_destroy(multi->pending, NULL);
|
||||
|
||||
/* remove all easy handles */
|
||||
data = multi->easyp;
|
||||
@@ -1875,7 +1907,6 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||
}
|
||||
|
||||
Curl_hash_destroy(multi->hostcache);
|
||||
multi->hostcache = NULL;
|
||||
|
||||
/* Free the blacklists by setting them to NULL */
|
||||
Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
|
||||
@@ -2654,6 +2685,46 @@ void Curl_expire(struct SessionHandle *data, long milli)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_expire_latest()
|
||||
*
|
||||
* This is like Curl_expire() but will only add a timeout node to the list of
|
||||
* timers if there is no timeout that will expire before the given time.
|
||||
*
|
||||
* Use this function if the code logic risks calling this function many times
|
||||
* or if there's no particular conditional wait in the code for this specific
|
||||
* time-out period to expire.
|
||||
*
|
||||
*/
|
||||
void Curl_expire_latest(struct SessionHandle *data, long milli)
|
||||
{
|
||||
struct timeval *exp = &data->state.expiretime;
|
||||
|
||||
struct timeval set;
|
||||
|
||||
set = Curl_tvnow();
|
||||
set.tv_sec += milli/1000;
|
||||
set.tv_usec += (milli%1000)*1000;
|
||||
|
||||
if(set.tv_usec >= 1000000) {
|
||||
set.tv_sec++;
|
||||
set.tv_usec -= 1000000;
|
||||
}
|
||||
|
||||
if(exp->tv_sec || exp->tv_usec) {
|
||||
/* This means that the struct is added as a node in the splay tree.
|
||||
Compare if the new time is earlier, and only remove-old/add-new if it
|
||||
is. */
|
||||
long diff = curlx_tvdiff(set, *exp);
|
||||
if(diff > 0)
|
||||
/* the new expire time was later than the top time, so just skip this */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Just add the timeout like normal */
|
||||
Curl_expire(data, milli);
|
||||
}
|
||||
|
||||
CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t s, void *hashp)
|
||||
{
|
||||
@@ -2708,16 +2779,23 @@ struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
|
||||
|
||||
void Curl_multi_process_pending_handles(struct Curl_multi *multi)
|
||||
{
|
||||
struct SessionHandle *data;
|
||||
struct curl_llist_element *e = multi->pending->head;
|
||||
|
||||
while(e) {
|
||||
struct SessionHandle *data = e->ptr;
|
||||
struct curl_llist_element *next = e->next;
|
||||
|
||||
data=multi->easyp;
|
||||
while(data) {
|
||||
if(data->mstate == CURLM_STATE_CONNECT_PEND) {
|
||||
multistate(data, CURLM_STATE_CONNECT);
|
||||
|
||||
/* Remove this node from the list */
|
||||
Curl_llist_remove(multi->pending, e, NULL);
|
||||
|
||||
/* Make sure that the handle will be processed soonish. */
|
||||
Curl_expire(data, 1);
|
||||
Curl_expire_latest(data, 1);
|
||||
}
|
||||
data = data->next; /* operate on next handle */
|
||||
|
||||
e = next; /* operate on next handle */
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, 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
|
||||
@@ -75,6 +75,9 @@ struct Curl_multi {
|
||||
|
||||
struct curl_llist *msglist; /* a list of messages from completed transfers */
|
||||
|
||||
struct curl_llist *pending; /* SessionHandles that are in the
|
||||
CURLM_STATE_CONNECT_PEND state */
|
||||
|
||||
/* callback function and user data pointer for the *socket() API */
|
||||
curl_socket_callback socket_cb;
|
||||
void *socket_userp;
|
||||
|
@@ -26,6 +26,7 @@
|
||||
* Prototypes for library-wide functions provided by multi.c
|
||||
*/
|
||||
void Curl_expire(struct SessionHandle *data, long milli);
|
||||
void Curl_expire_latest(struct SessionHandle *data, long milli);
|
||||
|
||||
bool Curl_multi_pipeline_enabled(const struct Curl_multi* multi);
|
||||
void Curl_multi_handlePipeBreak(struct SessionHandle *data);
|
||||
|
@@ -530,8 +530,10 @@ static int parsedate(const char *date, time_t *output)
|
||||
/* Add the time zone diff between local time zone and GMT. */
|
||||
long delta = (long)(tzoff!=-1?tzoff:0);
|
||||
|
||||
if((delta>0) && (t > LONG_MAX - delta))
|
||||
return -1; /* time_t overflow */
|
||||
if((delta>0) && (t > LONG_MAX - delta)) {
|
||||
*output = 0x7fffffff;
|
||||
return PARSEDATE_LATER; /* time_t overflow */
|
||||
}
|
||||
|
||||
t += delta;
|
||||
}
|
||||
@@ -561,9 +563,6 @@ time_t curl_getdate(const char *p, const time_t *now)
|
||||
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the
|
||||
* gmtime_r() or gmtime() functions anywhere else but here.
|
||||
*
|
||||
* To make sure no such function calls slip in, we define them to cause build
|
||||
* errors, which is why we use the name within parentheses in this function.
|
||||
*
|
||||
*/
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store)
|
||||
|
194
lib/pop3.c
194
lib/pop3.c
@@ -27,6 +27,7 @@
|
||||
* RFC2831 DIGEST-MD5 authentication
|
||||
* RFC4422 Simple Authentication and Security Layer (SASL)
|
||||
* RFC4616 PLAIN authentication
|
||||
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
|
||||
* RFC5034 POP3 SASL Authentication Mechanism
|
||||
* RFC6749 OAuth 2.0 Authorization Framework
|
||||
* Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
|
||||
@@ -320,6 +321,9 @@ static void state(struct connectdata *conn, pop3state newstate)
|
||||
"AUTH_DIGESTMD5_RESP",
|
||||
"AUTH_NTLM",
|
||||
"AUTH_NTLM_TYPE2MSG",
|
||||
"AUTH_GSSAPI",
|
||||
"AUTH_GSSAPI_TOKEN",
|
||||
"AUTH_GSSAPI_NO_DATA",
|
||||
"AUTH_XOAUTH2",
|
||||
"AUTH_CANCEL",
|
||||
"AUTH_FINAL",
|
||||
@@ -1127,6 +1131,158 @@ static CURLcode pop3_state_auth_ntlm_type2msg_resp(struct connectdata *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
/* For AUTH GSSAPI (without initial response) responses */
|
||||
static CURLcode pop3_state_auth_gssapi_resp(struct connectdata *conn,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
size_t len = 0;
|
||||
char *respmsg = NULL;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
failf(data, "Access denied: %d", pop3code);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Create the initial response message */
|
||||
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd, "pop",
|
||||
pop3c->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
&respmsg, &len);
|
||||
if(!result && respmsg) {
|
||||
/* Send the message */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_AUTH_GSSAPI_TOKEN);
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For AUTH GSSAPI user token responses */
|
||||
static CURLcode pop3_state_auth_gssapi_token_resp(struct connectdata *conn,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||
char *chlgmsg = NULL;
|
||||
char *respmsg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
failf(data, "Access denied: %d", pop3code);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Get the challenge message */
|
||||
pop3_get_message(data->state.buffer, &chlgmsg);
|
||||
|
||||
if(pop3c->mutual_auth)
|
||||
/* Decode the user token challenge and create the optional response
|
||||
message */
|
||||
result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL,
|
||||
pop3c->mutual_auth,
|
||||
chlgmsg, &conn->krb5,
|
||||
&respmsg, &len);
|
||||
else
|
||||
/* Decode the security challenge and create the response message */
|
||||
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
|
||||
&conn->krb5,
|
||||
&respmsg, &len);
|
||||
|
||||
if(result) {
|
||||
if(result == CURLE_BAD_CONTENT_ENCODING) {
|
||||
/* Send the cancellation */
|
||||
result = Curl_pp_sendf(&pop3c->pp, "%s", "*");
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_AUTH_CANCEL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Send the response */
|
||||
if(respmsg)
|
||||
result = Curl_pp_sendf(&pop3c->pp, "%s", respmsg);
|
||||
else
|
||||
result = Curl_pp_sendf(&pop3c->pp, "%s", "");
|
||||
|
||||
if(!result)
|
||||
state(conn, (pop3c->mutual_auth ? POP3_AUTH_GSSAPI_NO_DATA :
|
||||
POP3_AUTH_FINAL));
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* For AUTH GSSAPI no data responses */
|
||||
static CURLcode pop3_state_auth_gssapi_no_data_resp(struct connectdata *conn,
|
||||
int pop3code,
|
||||
pop3state instate)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *chlgmsg = NULL;
|
||||
char *respmsg = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
(void)instate; /* no use for this yet */
|
||||
|
||||
if(pop3code != '+') {
|
||||
failf(data, "Access denied: %d", pop3code);
|
||||
result = CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
/* Get the challenge message */
|
||||
pop3_get_message(data->state.buffer, &chlgmsg);
|
||||
|
||||
/* Decode the security challenge and create the security message */
|
||||
result = Curl_sasl_create_gssapi_security_message(data, chlgmsg,
|
||||
&conn->krb5,
|
||||
&respmsg, &len);
|
||||
if(result) {
|
||||
if(result == CURLE_BAD_CONTENT_ENCODING) {
|
||||
/* Send the cancellation */
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_AUTH_CANCEL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Send the response */
|
||||
if(respmsg) {
|
||||
result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", respmsg);
|
||||
|
||||
if(!result)
|
||||
state(conn, POP3_AUTH_FINAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Curl_safefree(respmsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* For AUTH XOAUTH2 (without initial response) responses */
|
||||
static CURLcode pop3_state_auth_xoauth2_resp(struct connectdata *conn,
|
||||
int pop3code, pop3state instate)
|
||||
@@ -1435,6 +1591,21 @@ static CURLcode pop3_statemach_act(struct connectdata *conn)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
case POP3_AUTH_GSSAPI:
|
||||
result = pop3_state_auth_gssapi_resp(conn, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_AUTH_GSSAPI_TOKEN:
|
||||
result = pop3_state_auth_gssapi_token_resp(conn, pop3code, pop3c->state);
|
||||
break;
|
||||
|
||||
case POP3_AUTH_GSSAPI_NO_DATA:
|
||||
result = pop3_state_auth_gssapi_no_data_resp(conn, pop3code,
|
||||
pop3c->state);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case POP3_AUTH_XOAUTH2:
|
||||
result = pop3_state_auth_xoauth2_resp(conn, pop3code, pop3c->state);
|
||||
break;
|
||||
@@ -1764,8 +1935,8 @@ static CURLcode pop3_regular_transfer(struct connectdata *conn,
|
||||
/* Set the progress data */
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, -1);
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
/* Carry out the perform */
|
||||
result = pop3_perform(conn, &connected, dophase_done);
|
||||
@@ -1950,6 +2121,25 @@ static CURLcode pop3_calc_sasl_details(struct connectdata *conn,
|
||||
|
||||
/* Calculate the supported authentication mechanism, by decreasing order of
|
||||
security, as well as the initial response where appropriate */
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
if((pop3c->authmechs & SASL_MECH_GSSAPI) &&
|
||||
(pop3c->prefmech & SASL_MECH_GSSAPI)) {
|
||||
pop3c->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
|
||||
|
||||
*mech = SASL_MECH_STRING_GSSAPI;
|
||||
*state1 = POP3_AUTH_GSSAPI;
|
||||
*state2 = POP3_AUTH_GSSAPI_TOKEN;
|
||||
pop3c->authused = SASL_MECH_GSSAPI;
|
||||
|
||||
if(data->set.sasl_ir)
|
||||
result = Curl_sasl_create_gssapi_user_message(data, conn->user,
|
||||
conn->passwd, "pop",
|
||||
pop3c->mutual_auth,
|
||||
NULL, &conn->krb5,
|
||||
initresp, len);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
|
||||
(pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user