Compare commits
163 Commits
curl-7_21_
...
curl-7_21_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
827f0a318c | ||
![]() |
b66eeb8bf8 | ||
![]() |
c3a6116dc9 | ||
![]() |
f19ace8d33 | ||
![]() |
c2dff28c41 | ||
![]() |
e36c039a07 | ||
![]() |
96ea650ec7 | ||
![]() |
3bb1291fbd | ||
![]() |
61fc9044c7 | ||
![]() |
311bd4c7b1 | ||
![]() |
39d0d787d2 | ||
![]() |
3cffcba3d0 | ||
![]() |
ae7fe3b7f4 | ||
![]() |
b370fcd300 | ||
![]() |
5348e8f276 | ||
![]() |
266bcb06d7 | ||
![]() |
fe165c69de | ||
![]() |
4e2ac742c9 | ||
![]() |
0696260122 | ||
![]() |
54d9f060b4 | ||
![]() |
2cacd82661 | ||
![]() |
ec7978c512 | ||
![]() |
0e9626ba39 | ||
![]() |
73eb9965cf | ||
![]() |
08a77025c6 | ||
![]() |
7a4b5079c6 | ||
![]() |
7a53c77cb5 | ||
![]() |
b89122a2bf | ||
![]() |
99dcb11ed8 | ||
![]() |
819dfddc58 | ||
![]() |
32a050ec7e | ||
![]() |
76ac6b94ed | ||
![]() |
28c830efd8 | ||
![]() |
7ba5e88053 | ||
![]() |
ef19e30985 | ||
![]() |
2d356ba168 | ||
![]() |
dc0a7161f8 | ||
![]() |
77cbfe2274 | ||
![]() |
20690e412d | ||
![]() |
dbcaa00657 | ||
![]() |
4b837a7e15 | ||
![]() |
73b518f269 | ||
![]() |
3427bece89 | ||
![]() |
e79c1e39e9 | ||
![]() |
77f0fcae0e | ||
![]() |
03be2c99ba | ||
![]() |
b77a3b9a35 | ||
![]() |
c0a2ee65a4 | ||
![]() |
4ba3d8bd00 | ||
![]() |
511031c8d8 | ||
![]() |
59cf93ccdb | ||
![]() |
4f13340ab8 | ||
![]() |
b0940753c6 | ||
![]() |
b35622f387 | ||
![]() |
ce24fdaa2c | ||
![]() |
02c99899a2 | ||
![]() |
7fcbdd68b9 | ||
![]() |
fc77790bcd | ||
![]() |
ef46fcdd90 | ||
![]() |
0243aa9eb0 | ||
![]() |
8fa7b8cb9b | ||
![]() |
fd6b4b3e9b | ||
![]() |
1da65c3d4d | ||
![]() |
d541085407 | ||
![]() |
c73e5e839d | ||
![]() |
db2e425346 | ||
![]() |
6aa5206042 | ||
![]() |
61623b74e3 | ||
![]() |
5f7d34811a | ||
![]() |
42f5e8a0f1 | ||
![]() |
c5d9cd5c1b | ||
![]() |
b5cc77bd25 | ||
![]() |
3d81320426 | ||
![]() |
308db9d780 | ||
![]() |
03ea06b8e3 | ||
![]() |
08a65b10fb | ||
![]() |
1238edaeaf | ||
![]() |
a9cd4f4ed4 | ||
![]() |
1d28efb9d1 | ||
![]() |
9ba42a023d | ||
![]() |
ebb9c7ae04 | ||
![]() |
53014175e8 | ||
![]() |
651c0bcdf2 | ||
![]() |
d45ed0ecf5 | ||
![]() |
e21b103c3e | ||
![]() |
0029b2f042 | ||
![]() |
7c5d888ea6 | ||
![]() |
adb49ad8bb | ||
![]() |
a2c8966d50 | ||
![]() |
d8f6d1c334 | ||
![]() |
1e52ea92eb | ||
![]() |
28888a0b41 | ||
![]() |
1022e754f4 | ||
![]() |
703573c72b | ||
![]() |
7af54ef9a5 | ||
![]() |
1602ed6ba1 | ||
![]() |
9e46318a03 | ||
![]() |
c0c89cd44e | ||
![]() |
6cf35852ad | ||
![]() |
83e9fb21aa | ||
![]() |
5c42b2ceae | ||
![]() |
82aa386732 | ||
![]() |
c43ad0f972 | ||
![]() |
53640a3ce0 | ||
![]() |
35e1d6538a | ||
![]() |
45cea71968 | ||
![]() |
569202c9a4 | ||
![]() |
2b3fbc8cdb | ||
![]() |
1ad5764feb | ||
![]() |
ae29142198 | ||
![]() |
cd045e24a0 | ||
![]() |
0dc8479b89 | ||
![]() |
420eac5542 | ||
![]() |
15aeb94f3f | ||
![]() |
b6a3e2be8e | ||
![]() |
9f64bbd6d8 | ||
![]() |
879914def3 | ||
![]() |
6076549304 | ||
![]() |
49465fffdb | ||
![]() |
5825aa149d | ||
![]() |
7dc9393d3b | ||
![]() |
2dded8fedb | ||
![]() |
be16b227b7 | ||
![]() |
e6d99f4ba7 | ||
![]() |
16c4314a21 | ||
![]() |
375aa41ba1 | ||
![]() |
5f829456c1 | ||
![]() |
a834e00454 | ||
![]() |
0e944fb24e | ||
![]() |
f37d681166 | ||
![]() |
30bd7427ea | ||
![]() |
71ab0ceaa0 | ||
![]() |
9acac91960 | ||
![]() |
af54fbbcb5 | ||
![]() |
1e739e781e | ||
![]() |
8d569c7bb0 | ||
![]() |
7f3b87d878 | ||
![]() |
6b5dc72575 | ||
![]() |
8ab137b2bc | ||
![]() |
bcfb9ea34c | ||
![]() |
f0aad0089e | ||
![]() |
d2395f962d | ||
![]() |
476b1a079b | ||
![]() |
9583b4af90 | ||
![]() |
8219bc9e19 | ||
![]() |
57523e3578 | ||
![]() |
37a22d4749 | ||
![]() |
1df74d886d | ||
![]() |
76c54bd129 | ||
![]() |
8f50a404f9 | ||
![]() |
f6ebae65d6 | ||
![]() |
a0a70dc21d | ||
![]() |
5e37689a1a | ||
![]() |
c75a9fef59 | ||
![]() |
9035709e25 | ||
![]() |
b88ead62e7 | ||
![]() |
b998b04c02 | ||
![]() |
68b2a9818b | ||
![]() |
a7cf30f808 | ||
![]() |
be312336f6 | ||
![]() |
6761cf49f2 | ||
![]() |
108d7693a4 | ||
![]() |
00a5bd41be |
@@ -1,44 +0,0 @@
|
||||
#cmakedefine CHECK_TYPE_SIZE_TYPE @CHECK_TYPE_SIZE_TYPE@
|
||||
#ifdef CHECK_TYPE_SIZE_TYPE
|
||||
|
||||
@CHECK_TYPE_SIZE_PREINCLUDE@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif /* HAVE_SYS_TYPES_H */
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif /* HAVE_STDINT_H */
|
||||
|
||||
#ifdef HAVE_STDDEF_H
|
||||
# include <stddef.h>
|
||||
#endif /* HAVE_STDDEF_H */
|
||||
|
||||
@CHECK_TYPE_SIZE_PREMAIN@
|
||||
|
||||
#ifdef __CLASSIC_C__
|
||||
int main(){
|
||||
int ac;
|
||||
char*av[];
|
||||
#else
|
||||
int main(int ac, char*av[]){
|
||||
#endif
|
||||
if(ac > 1000){return *av[0];}
|
||||
return sizeof(CHECK_TYPE_SIZE_TYPE);
|
||||
}
|
||||
|
||||
#else /* CHECK_TYPE_SIZE_TYPE */
|
||||
|
||||
# error "CHECK_TYPE_SIZE_TYPE has to specify the type"
|
||||
|
||||
#endif /* CHECK_TYPE_SIZE_TYPE */
|
@@ -1,57 +0,0 @@
|
||||
# - Check sizeof a type
|
||||
# CHECK_TYPE_SIZE(TYPE VARIABLE)
|
||||
# Check if the type exists and determine size of type. if the type
|
||||
# exists, the size will be stored to the variable.
|
||||
#
|
||||
# VARIABLE - variable to store size if the type exists.
|
||||
# HAVE_${VARIABLE} - does the variable exists or not
|
||||
|
||||
macro(CHECK_TYPE_SIZE TYPE VARIABLE)
|
||||
set(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS 1)
|
||||
if(NOT DEFINED ${VARIABLE})
|
||||
if("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
||||
set(CHECK_TYPE_SIZE_TYPE "${TYPE}")
|
||||
set(MACRO_CHECK_TYPE_SIZE_FLAGS
|
||||
"${CMAKE_REQUIRED_FLAGS}")
|
||||
foreach(def HAVE_SYS_TYPES_H
|
||||
HAVE_STDINT_H HAVE_STDDEF_H HAVE_SYS_SOCKET_H)
|
||||
if("${def}")
|
||||
set(MACRO_CHECK_TYPE_SIZE_FLAGS
|
||||
"${MACRO_CHECK_TYPE_SIZE_FLAGS} -D${def}")
|
||||
endif("${def}")
|
||||
endforeach(def)
|
||||
set(CHECK_TYPE_SIZE_PREMAIN)
|
||||
foreach(def ${CMAKE_EXTRA_INCLUDE_FILES})
|
||||
set(CHECK_TYPE_SIZE_PREMAIN "${CHECK_TYPE_SIZE_PREMAIN}#include \"${def}\"\n")
|
||||
endforeach(def)
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CMake/CheckTypeSize.c.in"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c"
|
||||
IMMEDIATE @ONLY)
|
||||
file(READ
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c"
|
||||
CHECK_TYPE_SIZE_FILE_CONTENT)
|
||||
message(STATUS "Check size of ${TYPE}")
|
||||
if(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CHECK_TYPE_SIZE_ADD_LIBRARIES
|
||||
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
|
||||
endif(CMAKE_REQUIRED_LIBRARIES)
|
||||
try_run(${VARIABLE} HAVE_${VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSize.c"
|
||||
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_TYPE_SIZE_FLAGS}
|
||||
"${CHECK_TYPE_SIZE_ADD_LIBRARIES}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(HAVE_${VARIABLE})
|
||||
message(STATUS "Check size of ${TYPE} - done")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining size of ${TYPE} passed with the following output:\n${OUTPUT}\n\n")
|
||||
else(HAVE_${VARIABLE})
|
||||
message(STATUS "Check size of ${TYPE} - failed")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining size of ${TYPE} failed with the following output:\n${OUTPUT}\nCheckTypeSize.c:\n${CHECK_TYPE_SIZE_FILE_CONTENT}\n\n")
|
||||
endif(HAVE_${VARIABLE})
|
||||
endif("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
||||
endif(NOT DEFINED ${VARIABLE})
|
||||
set(CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS )
|
||||
endmacro(CHECK_TYPE_SIZE)
|
@@ -183,13 +183,7 @@ include (CheckIncludeFile)
|
||||
include (CheckIncludeFiles)
|
||||
include (CheckLibraryExists)
|
||||
include (CheckSymbolExists)
|
||||
# if crosscompiling is on, the CHECK_TYPE_SIZE macro coming with cmake uses
|
||||
# TRY_COMPILE instead of TRY_RUN which makes crosscompiling easier, Alex
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
include ("${CMAKE_MODULE_PATH}/CheckTypeSize.cmake")
|
||||
else(CMAKE_CROSSCOMPILING)
|
||||
include (CheckTypeSize)
|
||||
endif(CMAKE_CROSSCOMPILING)
|
||||
include (CheckTypeSize)
|
||||
|
||||
# On windows preload settings
|
||||
if(WIN32)
|
||||
@@ -781,7 +775,13 @@ endif(CMAKE_COMPILER_IS_GNUCC AND APPLE)
|
||||
|
||||
if(HAVE_SOCKLEN_T)
|
||||
set(CURL_TYPEOF_CURL_SOCKLEN_T "socklen_t")
|
||||
if(WIN32)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;ws2tcpip.h")
|
||||
elseif(HAVE_SYS_SOCKET_H)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
|
||||
endif()
|
||||
check_type_size("socklen_t" CURL_SIZEOF_CURL_SOCKLEN_T)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(NOT HAVE_CURL_SIZEOF_CURL_SOCKLEN_T)
|
||||
message(FATAL_ERROR
|
||||
"Check for sizeof socklen_t failed, see CMakeFiles/CMakerror.log")
|
||||
|
2
COPYING
2
COPYING
@@ -1,6 +1,6 @@
|
||||
COPYRIGHT AND PERMISSION NOTICE
|
||||
|
||||
Copyright (c) 1996 - 2010, Daniel Stenberg, <daniel@haxx.se>.
|
||||
Copyright (c) 1996 - 2011, Daniel Stenberg, <daniel@haxx.se>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
16
Makefile.am
16
Makefile.am
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -24,15 +24,19 @@ AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt CMake/CheckTypeSize.c.in CMake/CheckTypeSize.cmake \
|
||||
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/FindOpenSSL.cmake CMake/FindZLIB.cmake \
|
||||
CMake/OtherTests.cmake CMake/Platforms/WindowsCache.cmake \
|
||||
CMake/Utilities.cmake include/curl/curlbuild.h.cmake
|
||||
|
||||
WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
|
||||
winbuild/MakefileBuild.vc winbuild/Makefile.vc
|
||||
|
||||
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
|
||||
curl-style.el sample.emacs RELEASE-NOTES buildconf \
|
||||
libcurl.pc.in vc6curl.dsw MacOSX-Framework Android.mk $(CMAKE_DIST)
|
||||
libcurl.pc.in vc6curl.dsw MacOSX-Framework Android.mk $(CMAKE_DIST) \
|
||||
Makefile.msvc.names $(WINBUILD_DIST)
|
||||
|
||||
bin_SCRIPTS = curl-config
|
||||
|
||||
|
@@ -32,27 +32,27 @@ ssl:
|
||||
|
||||
borland:
|
||||
cd lib
|
||||
make -f Makefile.b32
|
||||
$(MAKE) -f Makefile.b32
|
||||
cd ..\src
|
||||
make -f Makefile.b32
|
||||
$(MAKE) -f Makefile.b32
|
||||
|
||||
borland-ssl:
|
||||
cd lib
|
||||
make -f Makefile.b32 WITH_SSL=1
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1
|
||||
cd ..\src
|
||||
make -f Makefile.b32 WITH_SSL=1
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1
|
||||
|
||||
borland-ssl-zlib:
|
||||
cd lib
|
||||
make -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
cd ..\src
|
||||
make -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
|
||||
|
||||
borland-clean:
|
||||
cd lib
|
||||
make -f Makefile.b32 clean
|
||||
$(MAKE) -f Makefile.b32 clean
|
||||
cd ..\src
|
||||
make -f Makefile.b32 clean
|
||||
$(MAKE) -f Makefile.b32 clean
|
||||
|
||||
watcom: .SYMBOLIC
|
||||
cd lib && $(MAKE) -u -f Makefile.Watcom
|
||||
|
81
Makefile.msvc.names
Normal file
81
Makefile.msvc.names
Normal file
@@ -0,0 +1,81 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
#
|
||||
# This file is included from MSVC makefiles located in lib and src,
|
||||
# providing libcurl common file names required by these makefiles.
|
||||
#
|
||||
|
||||
# ------------------
|
||||
# libcurl base name
|
||||
# ------------------
|
||||
|
||||
!IF !DEFINED(LIB_NAME) || "$(LIB_NAME)" == ""
|
||||
LIB_NAME = libcurl
|
||||
!ENDIF
|
||||
|
||||
# -------------------------------------------------
|
||||
# libcurl static and dynamic libraries common base
|
||||
# file names for release and debug configurations
|
||||
# -------------------------------------------------
|
||||
|
||||
!IF !DEFINED(LIB_NAME_STA_REL) || "$(LIB_NAME_STA_REL)" == ""
|
||||
LIB_NAME_STA_REL = $(LIB_NAME)
|
||||
!ENDIF
|
||||
|
||||
!IF !DEFINED(LIB_NAME_STA_DBG) || "$(LIB_NAME_STA_DBG)" == ""
|
||||
LIB_NAME_STA_DBG = $(LIB_NAME_STA_REL)d
|
||||
!ENDIF
|
||||
|
||||
!IF !DEFINED(LIB_NAME_DYN_REL) || "$(LIB_NAME_DYN_REL)" == ""
|
||||
LIB_NAME_DYN_REL = $(LIB_NAME)
|
||||
!ENDIF
|
||||
|
||||
!IF !DEFINED(LIB_NAME_DYN_DBG) || "$(LIB_NAME_DYN_DBG)" == ""
|
||||
LIB_NAME_DYN_DBG = $(LIB_NAME_DYN_REL)d
|
||||
!ENDIF
|
||||
|
||||
# --------------------------------------------
|
||||
# Base names for libcurl DLL import libraries
|
||||
# --------------------------------------------
|
||||
|
||||
!IF !DEFINED(LIB_NAME_IMP_REL) || "$(LIB_NAME_IMP_REL)" == ""
|
||||
LIB_NAME_IMP_REL = $(LIB_NAME_DYN_REL)_imp
|
||||
!ENDIF
|
||||
|
||||
!IF !DEFINED(LIB_NAME_IMP_DBG) || "$(LIB_NAME_IMP_DBG)" == ""
|
||||
LIB_NAME_IMP_DBG = $(LIB_NAME_DYN_DBG)_imp
|
||||
!ENDIF
|
||||
|
||||
# --------------------------------------
|
||||
# File names with extension and no path
|
||||
# --------------------------------------
|
||||
|
||||
LIBCURL_STA_LIB_REL = $(LIB_NAME_STA_REL).lib
|
||||
LIBCURL_STA_LIB_DBG = $(LIB_NAME_STA_DBG).lib
|
||||
LIBCURL_DYN_LIB_REL = $(LIB_NAME_DYN_REL).dll
|
||||
LIBCURL_DYN_LIB_DBG = $(LIB_NAME_DYN_DBG).dll
|
||||
LIBCURL_IMP_LIB_REL = $(LIB_NAME_IMP_REL).lib
|
||||
LIBCURL_IMP_LIB_DBG = $(LIB_NAME_IMP_DBG).lib
|
||||
LIBCURL_DYN_LIB_PDB = $(LIB_NAME_IMP_DBG).pdb
|
||||
|
||||
# End of Makefile.msvc.names
|
@@ -1,51 +1,54 @@
|
||||
Curl and libcurl 7.21.3
|
||||
Curl and libcurl 7.21.4
|
||||
|
||||
Public curl releases: 119
|
||||
Public curl releases: 120
|
||||
Command line options: 143
|
||||
curl_easy_setopt() options: 185
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 39
|
||||
Contributors: 827
|
||||
Contributors: 834
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added --noconfigure switch to testcurl.pl
|
||||
o Added --xattr option
|
||||
o Added CURLOPT_RESOLVE and --resolve
|
||||
o Added CURLAUTH_ONLY
|
||||
o Added version-check.pl to the examples dir
|
||||
o CURLINFO_FTP_ENTRY_PATH now supports SFTP
|
||||
o introduced new framework for unit-testing
|
||||
o IDN: use win32 API if told to
|
||||
o ares: ask for both IPv4 and IPv6 addresses
|
||||
o HTTP: do Negotiate authentication using SSPI on windows
|
||||
o Windows build: alternative makefile
|
||||
o TLS-SRP: support added when using GnuTLS
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o check for libcurl features for some command line options
|
||||
o Curl_setopt: disallow CURLOPT_USE_SSL without SSL support
|
||||
o http_chunks: remove debug output
|
||||
o URL-parsing: consider ? a divider
|
||||
o SSH: avoid using the libssh2_ prefix
|
||||
o SSH: use libssh2_session_handshake() to work on win64
|
||||
o ftp: prevent server from hanging on closed data connection when stopping
|
||||
a transfer before the end of the full transfer (ranges)
|
||||
o LDAP: detect non-binary attributes properly
|
||||
o ftp: treat server's response 421 as CURLE_OPERATION_TIMEDOUT
|
||||
o gnutls->handshake: improved timeout handling
|
||||
o security: Pass the right parameter to init
|
||||
o krb5: Use GSS_ERROR to check for error
|
||||
o TFTP: resend the correct data
|
||||
o configure: fix autoconf 2.68 warning: no AC_LANG_SOURCE call detected
|
||||
o GnuTLS: now detects socket errors on Windows
|
||||
o symbols-in-versions: updated en masse
|
||||
o added a couple examples that were missing from the tar ball
|
||||
o Curl_send/recv_plain: return errno on failure
|
||||
o Curl_wait_for_resolv (for c-ares): correct timeout
|
||||
o ossl_connect_common: detect connection re-use
|
||||
o configure: Prevent link errors with --librtmp
|
||||
o openldap: use remote port in URL passed to ldap_init_fd()
|
||||
o url: provide dead_connection flag in Curl_handler::disconnect
|
||||
o lots of compiler warning fixes
|
||||
o ssh: fix a download resume point calculation
|
||||
o fix getinfo CURLINFO_LOCAL* for reused connections
|
||||
o multi: the returned running handles conuter could turn negative
|
||||
o multi: only ever consider pipelining for connections doing HTTP(S)
|
||||
o SMTP: add brackets for MAIL FROM
|
||||
o ossl_seed: no more RAND_screen (on Windows)
|
||||
o multi: connect fail => use next IP address
|
||||
o use the timeout when using multiple IP addresses similar to how
|
||||
the easy interface does it
|
||||
o cookies: tricked dotcounter fixed
|
||||
o pubkey_show: allocate buffer to fit any-size result
|
||||
o Curl_nss_connect: avoid PATH_MAX
|
||||
o Curl_do: avoid using stale conn pointer
|
||||
o tftpd test server: avoid buffer overflow report from glibc
|
||||
o nss: avoid CURLE_OUT_OF_MEMORY given a file name without any slash
|
||||
o nss: fix a bug in handling of CURLOPT_CAPATH
|
||||
o CMake: Use upstream CheckTypeSize module
|
||||
o OpenSSL get_cert_chain: support larger data sets
|
||||
o SCP/SFTP transfers: acknowledge speedcheck
|
||||
o GnuTLS builds: fix memory leak
|
||||
o connect problem: use UDP correctly
|
||||
o Borland C++ makefile tweaks
|
||||
o OpenSSL: improved error message on SSL_CTX_new failures
|
||||
o HTTP: memory leak on multiple Location:
|
||||
o ares_query_completed_cb: don't touch invalid data
|
||||
o ares: memory leak fix
|
||||
o mk-ca-bundle: use new cacert url
|
||||
o Curl_gmtime: added a portable gmtime and check for NULL
|
||||
o curl.1: typo in -v description
|
||||
o CURLOPT_SOCKOPTFUNCTION: return proper error code
|
||||
o --keepalive-time: warn if not supported properly
|
||||
o file: add support for CURLOPT_TIMECONDITION
|
||||
o nss: avoid memory leaks and failure of NSS shutdown
|
||||
o multi: fix CURLM_STATE_TOOFAST for multi_socket
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
@@ -54,8 +57,11 @@ This release includes the following known bugs:
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Dan Fandrich, Guenter Knauf, Pat Ray, Hongli Lai, Kamil Dudka,
|
||||
Stefan Tomanek, Alfred Gebert, Yang Tse, Julien Chaffraix, Adam Light,
|
||||
Rutger Hofman, Matthias Bolte, Heinrich Ko, Dmitri Shubin
|
||||
Amr Shahin, Andreas Olsson, Bjoern Sikora, Brad Hards, Brad King,
|
||||
Dan Fandrich, Daniel Mentz, Darshan Mody, Dave Reisner, Eric Hu,
|
||||
Guenter Knauf, Ian D Allen, John Bradshaw, Julien Chaffraix, Kamil Dudka,
|
||||
Luke Amery, Marcel Roelofs, Martin Lemke, Nicholas Maniscalco,
|
||||
Pasha Kuznetsov, Patrick Monnerat, Paul Howarth, Pedro Larroy, Pierre Joye,
|
||||
Quinn Slack, Samuel Thibault, Tommie Gannert, Vsevolod Novikov, Yang Tse
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@@ -3181,7 +3181,7 @@ AC_DEFUN([CURL_CHECK_WIN32_LARGEFILE], [
|
||||
;;
|
||||
win32_small_files)
|
||||
AC_MSG_RESULT([yes (large file disabled)])
|
||||
AC_DEFINE_UNQUOTED(USE_WIN32_LARGE_FILES, 1,
|
||||
AC_DEFINE_UNQUOTED(USE_WIN32_SMALL_FILES, 1,
|
||||
[Define to 1 if you are building a Windows target without large file support.])
|
||||
;;
|
||||
*)
|
||||
|
111
configure.ac
111
configure.ac
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -140,12 +140,13 @@ AC_SUBST(PKGADD_VENDOR)
|
||||
|
||||
dnl
|
||||
dnl initialize all the info variables
|
||||
curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl} )"
|
||||
curl_ssl_msg="no (--with-{ssl,gnutls,nss,polarssl,axtls} )"
|
||||
curl_ssh_msg="no (--with-libssh2)"
|
||||
curl_zlib_msg="no (--with-zlib)"
|
||||
curl_krb4_msg="no (--with-krb4*)"
|
||||
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)"
|
||||
curl_idn_msg="no (--with-libidn)"
|
||||
@@ -156,6 +157,7 @@ curl_verbose_msg="enabled (--disable-verbose)"
|
||||
curl_ldaps_msg="no (--enable-ldaps)"
|
||||
curl_rtsp_msg="no (--enable-rtsp)"
|
||||
curl_rtmp_msg="no (--with-librtmp)"
|
||||
init_ssl_msg=${curl_ssl_msg}
|
||||
|
||||
dnl
|
||||
dnl Save anything in $LIBS for later
|
||||
@@ -1753,6 +1755,17 @@ if test "$GNUTLS_ENABLED" = "1"; then
|
||||
])
|
||||
fi
|
||||
|
||||
dnl ---
|
||||
dnl We require GnuTLS with SRP support.
|
||||
dnl ---
|
||||
if test "$GNUTLS_ENABLED" = "1"; then
|
||||
AC_CHECK_LIB(gnutls, gnutls_srp_verifier,
|
||||
[
|
||||
AC_DEFINE(HAVE_GNUTLS_SRP, 1, [if you have the function gnutls_srp_verifier])
|
||||
AC_SUBST(HAVE_GNUTLS_SRP, [1])
|
||||
])
|
||||
fi
|
||||
|
||||
dnl ----------------------------------------------------
|
||||
dnl check for PolarSSL
|
||||
dnl ----------------------------------------------------
|
||||
@@ -1933,9 +1946,64 @@ if test "$OPENSSL_ENABLED" != "1" -a "$GNUTLS_ENABLED" != "1"; then
|
||||
|
||||
fi dnl OPENSSL != 1 -a GNUTLS_ENABLED != 1
|
||||
|
||||
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED" = "x"; then
|
||||
OPT_AXTLS=off
|
||||
|
||||
AC_ARG_WITH(axtls,dnl
|
||||
AC_HELP_STRING([--with-axtls=PATH],[Where to look for axTLS, PATH points to the axTLS installation prefix (default: /usr/local). Ignored if another SSL engine is selected.])
|
||||
AC_HELP_STRING([--without-axtls], [disable axTLS]),
|
||||
OPT_AXTLS=$withval)
|
||||
|
||||
if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
||||
if test X"$OPT_AXTLS" != Xno; then
|
||||
dnl backup the pre-axtls variables
|
||||
CLEANLDFLAGS="$LDFLAGS"
|
||||
CLEANCPPFLAGS="$CPPFLAGS"
|
||||
CLEANLIBS="$LIBS"
|
||||
|
||||
case "$OPT_AXTLS" in
|
||||
yes)
|
||||
dnl --with-axtls (without path) used
|
||||
PREFIX_AXTLS=/usr/local
|
||||
LIB_AXTLS="$PREFIX_AXTLS/lib"
|
||||
LDFLAGS="$LDFLAGS -L$LIB_AXTLS"
|
||||
CPPFLAGS="$CPPFLAGS -I$PREFIX_AXTLS/include"
|
||||
;;
|
||||
off)
|
||||
dnl no --with-axtls option given, just check default places
|
||||
PREFIX_AXTLS=
|
||||
;;
|
||||
*)
|
||||
dnl check the given --with-axtls spot
|
||||
PREFIX_AXTLS=$OPT_AXTLS
|
||||
LIB_AXTLS="$PREFIX_AXTLS/lib"
|
||||
LDFLAGS="$LDFLAGS -L$LIB_AXTLS"
|
||||
CPPFLAGS="$CPPFLAGS -I$PREFIX_AXTLS/include"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_LIB(axtls, ssl_version,[
|
||||
LIBS="-laxtls $LIBS"
|
||||
AC_DEFINE(USE_AXTLS, 1, [if axTLS is enabled])
|
||||
AC_SUBST(USE_AXTLS, [1])
|
||||
AXTLS_ENABLED=1
|
||||
USE_AXTLS="yes"
|
||||
curl_ssl_msg="enabled (axTLS)"
|
||||
|
||||
|
||||
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$LIB_AXTLS"
|
||||
export LD_LIBRARY_PATH
|
||||
AC_MSG_NOTICE([Added $LIB_AXTLS to LD_LIBRARY_PATH])
|
||||
],[
|
||||
LDFLAGS="$CLEANLDFLAGS"
|
||||
CPPFLAGS="$CLEANCPPFLAGS"
|
||||
LIBS="$CLEANLIBS"
|
||||
])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$OPENSSL_ENABLED$GNUTLS_ENABLED$NSS_ENABLED$POLARSSL_ENABLED$AXTLS_ENABLED" = "x"; then
|
||||
AC_MSG_WARN([SSL disabled, you will not be able to use HTTPS, FTPS, NTLM and more.])
|
||||
AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-polarssl or --with-nss to address this.])
|
||||
AC_MSG_WARN([Use --with-ssl, --with-gnutls, --with-polarssl, --with-nss or --with-axtls to address this.])
|
||||
else
|
||||
# SSL is enabled, genericly
|
||||
AC_SUBST(SSL_ENABLED)
|
||||
@@ -2505,7 +2573,8 @@ AM_CONDITIONAL(USE_MANUAL, test x"$USE_MANUAL" = x1)
|
||||
CURL_CHECK_LIB_ARES
|
||||
AM_CONDITIONAL(USE_EMBEDDED_ARES, test x$embedded_ares = xyes)
|
||||
|
||||
if test "x$enable_shared" = "xyes"; then
|
||||
if test "x$ac_cv_native_windows" != "xyes" &&
|
||||
test "x$enable_shared" = "xyes"; then
|
||||
build_libhostname=yes
|
||||
else
|
||||
build_libhostname=no
|
||||
@@ -2597,6 +2666,33 @@ AC_HELP_STRING([--disable-crypto-auth],[Disable cryptographic authentication]),
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
dnl ************************************************************
|
||||
dnl disable TLS-SRP authentication
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable TLS-SRP authentication])
|
||||
AC_ARG_ENABLE(tls-srp,
|
||||
AC_HELP_STRING([--enable-tls-srp],[Enable TLS-SRP authentication])
|
||||
AC_HELP_STRING([--disable-tls-srp],[Disable TLS-SRP authentication]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(CURL_DISABLE_TLS_SRP, 1, [to disable TLS-SRP authentication])
|
||||
want_tls_srp=no
|
||||
;;
|
||||
*) AC_MSG_RESULT(yes)
|
||||
want_tls_srp=yes
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(yes)
|
||||
want_tls_srp=yes
|
||||
)
|
||||
|
||||
if test "$want_tls_srp" = "yes" && test "x$HAVE_GNUTLS_SRP" = "x1"; then
|
||||
AC_DEFINE(USE_TLS_SRP, 1, [Use TLS-SRP authentication])
|
||||
USE_TLS_SRP=1
|
||||
curl_tls_srp_msg="enabled"
|
||||
fi
|
||||
|
||||
dnl ************************************************************
|
||||
dnl disable cookies support
|
||||
dnl
|
||||
@@ -2745,6 +2841,9 @@ if test "x$USE_SSLEAY" = "x1" -o "x$USE_WINDOWS_SSPI" = "x1" \
|
||||
-o "x$GNUTLS_ENABLED" = "x1" -o "x$NSS_ENABLED" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES NTLM"
|
||||
fi
|
||||
if test "x$USE_TLS_SRP" = "x1"; then
|
||||
SUPPORT_FEATURES="$SUPPORT_FEATURES TLS-SRP"
|
||||
fi
|
||||
|
||||
AC_SUBST(SUPPORT_FEATURES)
|
||||
|
||||
@@ -2854,6 +2953,7 @@ AC_CONFIG_FILES([Makefile \
|
||||
tests/data/Makefile \
|
||||
tests/server/Makefile \
|
||||
tests/libtest/Makefile \
|
||||
tests/unit/Makefile \
|
||||
packages/Makefile \
|
||||
packages/Win32/Makefile \
|
||||
packages/Win32/cygwin/Makefile \
|
||||
@@ -2887,6 +2987,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
|
||||
krb4 support: ${curl_krb4_msg}
|
||||
GSSAPI 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}
|
||||
IDN support: ${curl_idn_msg}
|
||||
|
@@ -189,7 +189,7 @@
|
||||
|
||||
3.2 How To Make a Patch with git
|
||||
|
||||
You need to first checkout the respository:
|
||||
You need to first checkout the repository:
|
||||
|
||||
git clone git://github.com/bagder/curl.git
|
||||
|
||||
|
32
docs/FAQ
32
docs/FAQ
@@ -1,4 +1,4 @@
|
||||
Updated: October 6, 2010 (http://curl.haxx.se/docs/faq.html)
|
||||
Updated: January 29, 2011 (http://curl.haxx.se/docs/faq.html)
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
@@ -446,10 +446,10 @@ FAQ
|
||||
|
||||
2.2 Does curl work/build with other SSL libraries?
|
||||
|
||||
Curl has been written to use OpenSSL, GnuTLS, yassl, NSS or PolarSSL,
|
||||
although there should not be many problems using a different library. If
|
||||
anyone does "port" curl to use a different SSL library, we are of course
|
||||
very interested in getting the patch!
|
||||
Curl has been written to use OpenSSL, GnuTLS, yassl, NSS, PolarSSL, axTLS or
|
||||
qssl, although there should not be many problems using a different
|
||||
library. If anyone does "port" curl to use a different SSL library, we are
|
||||
of course very interested in getting the patch!
|
||||
|
||||
2.3 Where can I find a copy of LIBEAY32.DLL?
|
||||
|
||||
@@ -1224,16 +1224,18 @@ FAQ
|
||||
|
||||
5.13 How do I stop an ongoing transfer?
|
||||
|
||||
There are several ways, but none of them are instant. There is no function
|
||||
you can call from another thread or similar that will stop it immediately.
|
||||
With the easy interface you make sure to return the correct error code from
|
||||
one of the callbacks, but none of them are instant. There is no function you
|
||||
can call from another thread or similar that will stop it immediately.
|
||||
Instead you need to make sure that one of the callbacks you use return an
|
||||
appropriate value that will stop the transfer.
|
||||
|
||||
Suitable callbacks that you can do this with include the progress callback,
|
||||
the read callback and the write callback.
|
||||
|
||||
If you're using the multi interface, you also stop a transfer by removing
|
||||
the particular easy handle from the multi stack.
|
||||
If you're using the multi interface, you can also stop a transfer by
|
||||
removing the particular easy handle from the multi stack. At any moment you
|
||||
think the transfer is done.
|
||||
|
||||
5.14 Using C++ non-static functions for callbacks?
|
||||
|
||||
@@ -1345,12 +1347,16 @@ FAQ
|
||||
You do not have to reveal or make public any changes to the libcurl source
|
||||
code.
|
||||
|
||||
You do not have to reveal or make public that you are using libcurl within
|
||||
You do not have to broadcast to the world that you are using libcurl within
|
||||
your app.
|
||||
|
||||
As can be seen here: http://curl.haxx.se/docs/companies.html and
|
||||
elsewhere, more and more companies are discovering the power
|
||||
of libcurl and take advantage of it even in commercial environments.
|
||||
All we ask is that you disclose "the copyright notice and this permission
|
||||
notice" somewhere. Most probably like in the documentation or in the section
|
||||
where other third party dependencies already are mentioned and acknowledged.
|
||||
|
||||
As can be seen here: http://curl.haxx.se/docs/companies.html and elsewhere,
|
||||
more and more companies are discovering the power of libcurl and take
|
||||
advantage of it even in commercial environments.
|
||||
|
||||
|
||||
7. PHP/CURL Issues
|
||||
|
@@ -125,7 +125,7 @@ FILE
|
||||
FOOTNOTES
|
||||
=========
|
||||
|
||||
*1 = requires OpenSSL, GnuTLS, NSS, yassl or PolarSSL
|
||||
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS or PolarSSL
|
||||
*2 = requires OpenLDAP
|
||||
*3 = requires a GSSAPI-compliant library, such as Heimdal or similar.
|
||||
*4 = requires FBopenssl
|
||||
|
100
docs/INSTALL
100
docs/INSTALL
@@ -142,6 +142,9 @@ UNIX
|
||||
To build with PolarSSL support instead of OpenSSL for SSL/TLS, note that
|
||||
you need to use both --without-ssl and --with-polarssl.
|
||||
|
||||
To build with axTLS support instead of OpenSSL for TLS, note that you
|
||||
need to use both --without-ssl and --with-axtls.
|
||||
|
||||
To get GSSAPI support, build with --with-gssapi and have the MIT or
|
||||
Heimdal Kerberos 5 packages installed.
|
||||
|
||||
@@ -208,9 +211,9 @@ Win32
|
||||
adjust as necessary. It is also possible to override these paths with
|
||||
environment variables, for example:
|
||||
|
||||
set ZLIB_PATH=c:\zlib-1.2.3
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8k
|
||||
set LIBSSH2_PATH=c:\libssh2-1.1
|
||||
set ZLIB_PATH=c:\zlib-1.2.5
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8r
|
||||
set LIBSSH2_PATH=c:\libssh2-1.2.7
|
||||
|
||||
ATTENTION: if you want to build with libssh2 support you have to use latest
|
||||
version 0.17 - previous versions will NOT work with 7.17.0 and later!
|
||||
@@ -229,7 +232,7 @@ Win32
|
||||
|
||||
If you want to enable LDAPS support then set LDAPS=1.
|
||||
|
||||
- optional MingW32-built OpenlDAP SDK available from:
|
||||
- optional MingW32-built OpenLDAP SDK available from:
|
||||
http://www.gknw.net/mirror/openldap/
|
||||
- optional recent Novell CLDAP SDK available from:
|
||||
http://developer.novell.com/ndk/cldap.htm
|
||||
@@ -311,7 +314,7 @@ Win32
|
||||
documentation on how to compile zlib. Define the ZLIB_PATH environment
|
||||
variable to the location of zlib.h and zlib.lib, for example:
|
||||
|
||||
set ZLIB_PATH=c:\zlib-1.2.3
|
||||
set ZLIB_PATH=c:\zlib-1.2.5
|
||||
|
||||
Then run 'nmake vc-zlib' in curl's root directory.
|
||||
|
||||
@@ -325,7 +328,7 @@ Win32
|
||||
Before running nmake define the OPENSSL_PATH environment variable with
|
||||
the root/base directory of OpenSSL, for example:
|
||||
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8k
|
||||
set OPENSSL_PATH=c:\openssl-0.9.8q
|
||||
|
||||
Then run 'nmake vc-ssl' or 'nmake vc-ssl-dll' in curl's root
|
||||
directory. 'nmake vc-ssl' will create a libcurl static and dynamic
|
||||
@@ -374,30 +377,49 @@ Win32
|
||||
Borland C++ compiler
|
||||
---------------------
|
||||
|
||||
compile openssl
|
||||
Ensure that your build environment is properly set up to use the compiler
|
||||
and associated tools. PATH environment variable must include the path to
|
||||
bin subdirectory of your compiler installation, eg: c:\Borland\BCC55\bin
|
||||
|
||||
Make sure you include the paths to curl/include and openssl/inc32 in
|
||||
your bcc32.cnf file
|
||||
It is advisable to set environment variable BCCDIR to the base path of
|
||||
the compiler installation.
|
||||
|
||||
eg : -I"c:\Bcc55\include;c:\path_curl\include;c:\path_openssl\inc32"
|
||||
set BCCDIR=c:\Borland\BCC55
|
||||
|
||||
Check to make sure that all of the sources listed in lib/Makefile.b32
|
||||
are present in the /path_to_curl/lib directory. (Check the src
|
||||
directory for missing ones.)
|
||||
In order to build a plain vanilla version of curl and libcurl run the
|
||||
following command from curl's root directory:
|
||||
|
||||
Make sure the environment variable "BCCDIR" is set to the install
|
||||
location for the compiler eg : c:\Borland\BCC55
|
||||
make borland
|
||||
|
||||
command line:
|
||||
make -f /path_to_curl/lib/Makefile-ssl.b32
|
||||
To build curl and libcurl with zlib and OpenSSL support set environment
|
||||
variables ZLIB_PATH and OPENSSL_PATH to the base subdirectories of the
|
||||
already built zlib and OpenSSL libraries and from curl's root directory
|
||||
run command:
|
||||
|
||||
compile simplessl.c with appropriate links
|
||||
make borland-ssl-zlib
|
||||
|
||||
libcurl library will be built in 'lib' subdirectory while curl tool
|
||||
is built in 'src' subdirectory. In order to use libcurl library it is
|
||||
advisable to modify compiler's configuration file bcc32.cfg located
|
||||
in c:\Borland\BCC55\bin to reflect the location of libraries include
|
||||
paths for example the '-I' line could result in something like:
|
||||
|
||||
-I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32"
|
||||
|
||||
bcc3.cfg '-L' line could also be modified to reflect the location of
|
||||
of libcurl library resulting for example:
|
||||
|
||||
-L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32"
|
||||
|
||||
In order to build sample program 'simple.c' from the docs\examples
|
||||
subdirectory run following command from mentioned subdirectory:
|
||||
|
||||
bcc32 simple.c libcurl.lib cw32mt.lib
|
||||
|
||||
In order to build sample program simplessl.c an SSL enabled libcurl
|
||||
is required, as well as the OpenSSL libeay32.lib and ssleay32.lib
|
||||
libraries.
|
||||
|
||||
c:\curl\docs\examples\> bcc32 -L c:\path_to_curl\lib\libcurl.lib
|
||||
-L c:\borland\bcc55\lib\psdk\ws2_32.lib
|
||||
-L c:\openssl\out32\libeay32.lib
|
||||
-L c:\openssl\out32\ssleay32.lib
|
||||
simplessl.c
|
||||
|
||||
OTHER MSVC IDEs
|
||||
---------------
|
||||
@@ -638,7 +660,7 @@ NetWare
|
||||
Builds automatically created 8 times a day from current git are here:
|
||||
http://www.gknw.net/mirror/curl/autobuilds/
|
||||
the status of these builds can be viewed at the autobuild table:
|
||||
http://curl.haxx.se/auto/
|
||||
http://curl.haxx.se/dev/builds.html
|
||||
|
||||
|
||||
eCos
|
||||
@@ -980,17 +1002,21 @@ PORTS
|
||||
Useful URLs
|
||||
===========
|
||||
|
||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||
GNU GSS http://www.gnu.org/software/gss/
|
||||
GnuTLS http://www.gnu.org/software/gnutls/
|
||||
Heimdal http://www.pdc.kth.se/heimdal/
|
||||
libidn http://www.gnu.org/software/libidn/
|
||||
libssh2 http://www.libssh2.org
|
||||
MingW http://www.mingw.org
|
||||
axTLS http://axtls.sourceforge.net/
|
||||
c-ares http://c-ares.haxx.se/
|
||||
GNU GSS http://www.gnu.org/software/gss/
|
||||
GnuTLS http://www.gnu.org/software/gnutls/
|
||||
Heimdal http://www.pdc.kth.se/heimdal/
|
||||
libidn http://www.gnu.org/software/libidn/
|
||||
libssh2 http://www.libssh2.org/
|
||||
MIT Kerberos http://web.mit.edu/kerberos/www/dist/
|
||||
NSS http://www.mozilla.org/projects/security/pki/nss/
|
||||
OpenLDAP http://www.openldap.org
|
||||
OpenSSL http://www.openssl.org
|
||||
PolarSSL http://polarssl.org
|
||||
yassl http://www.yassl.com/
|
||||
Zlib http://www.gzip.org/zlib/
|
||||
NSS http://www.mozilla.org/projects/security/pki/nss/
|
||||
OpenLDAP http://www.openldap.org/
|
||||
OpenSSL http://www.openssl.org/
|
||||
PolarSSL http://polarssl.org/
|
||||
yassl http://www.yassl.com/
|
||||
Zlib http://www.zlib.net/
|
||||
|
||||
MingW http://www.mingw.org/
|
||||
MinGW-w64 http://mingw-w64.sourceforge.net/
|
||||
OpenWatcom http://www.openwatcom.org/
|
||||
|
@@ -15,7 +15,7 @@ INTERNALS
|
||||
GIT
|
||||
===
|
||||
All changes to the sources are committed to the git repository as soon as
|
||||
they're somewhat verified to work. Changes shall be commited as independently
|
||||
they're somewhat verified to work. Changes shall be committed as independently
|
||||
as possible so that individual changes can be easier spotted and tracked
|
||||
afterwards.
|
||||
|
||||
@@ -44,6 +44,7 @@ Portability
|
||||
MIT krb5 lib 1.2.4
|
||||
qsossl V5R2M0
|
||||
NSS 3.11.x
|
||||
axTLS 1.2.7
|
||||
Heimdal ?
|
||||
|
||||
* = only partly functional, but that's due to bugs in the third party lib, not
|
||||
@@ -90,7 +91,7 @@ Windows vs Unix
|
||||
do it etc there might be reasons for applications to alter that behaviour.
|
||||
|
||||
3. The file descriptors for network communication and file operations are
|
||||
not easily interchangable as in unix.
|
||||
not easily interchangeable as in unix.
|
||||
|
||||
We avoid this by not trying any funny tricks on file descriptors.
|
||||
|
||||
@@ -182,7 +183,7 @@ Library
|
||||
|
||||
Some time during the DO function, the Curl_setup_transfer() function must
|
||||
be called with some basic info about the upcoming transfer: what socket(s)
|
||||
to read/write and the expected file tranfer sizes (if known).
|
||||
to read/write and the expected file transfer sizes (if known).
|
||||
|
||||
o Transfer()
|
||||
|
||||
@@ -224,15 +225,15 @@ Library
|
||||
A quick roundup on internal function sequences (many of these call
|
||||
protocol-specific function-pointers):
|
||||
|
||||
curl_connect - connects to a remote site and does initial connect fluff
|
||||
Curl_connect - connects to a remote site and does initial connect fluff
|
||||
This also checks for an existing connection to the requested site and uses
|
||||
that one if it is possible.
|
||||
|
||||
curl_do - starts a transfer
|
||||
curl_transfer() - transfers data
|
||||
curl_done - ends a transfer
|
||||
Curl_do - starts a transfer
|
||||
Curl_handler::do_it() - transfers data
|
||||
Curl_done - ends a transfer
|
||||
|
||||
curl_disconnect - disconnects from a remote site. This is called when the
|
||||
Curl_disconnect - disconnects from a remote site. This is called when the
|
||||
disconnect is really requested, which doesn't necessarily have to be
|
||||
exactly after curl_done in case we want to keep the connection open for
|
||||
a while.
|
||||
@@ -249,13 +250,13 @@ Library
|
||||
HTTPS uses in almost every means the same procedure as HTTP, with only two
|
||||
exceptions: the connect procedure is different and the function used to read
|
||||
or write from the socket is different, although the latter fact is hidden in
|
||||
the source by the use of curl_read() for reading and curl_write() for writing
|
||||
the source by the use of Curl_read() for reading and Curl_write() for writing
|
||||
data to the remote server.
|
||||
|
||||
http_chunks.c contains functions that understands HTTP 1.1 chunked transfer
|
||||
encoding.
|
||||
|
||||
An interesting detail with the HTTP(S) request, is the add_buffer() series of
|
||||
An interesting detail with the HTTP(S) request, is the Curl_add_buffer() series of
|
||||
functions we use. They append data to one single buffer, and when the
|
||||
building is done the entire request is sent off in one single write. This is
|
||||
done this way to overcome problems with flawed firewalls and lame servers.
|
||||
@@ -291,7 +292,7 @@ Library
|
||||
URL encoding and decoding, called escaping and unescaping in the source code,
|
||||
is found in lib/escape.c.
|
||||
|
||||
While transfering data in Transfer() a few functions might get used.
|
||||
While transferring data in Transfer() a few functions might get used.
|
||||
curl_getdate() in lib/parsedate.c is for HTTP date comparisons (and more).
|
||||
|
||||
lib/getenv.c offers curl_getenv() which is for reading environment variables
|
||||
@@ -303,7 +304,7 @@ Library
|
||||
lib/netrc.c holds the .netrc parser
|
||||
|
||||
lib/timeval.c features replacement functions for systems that don't have
|
||||
gettimeofday() and a few support functions for timeval convertions.
|
||||
gettimeofday() and a few support functions for timeval conversions.
|
||||
|
||||
A function named curl_version() that returns the full curl version string is
|
||||
found in lib/version.c.
|
||||
@@ -356,8 +357,10 @@ multi interface/non-blocking
|
||||
|
||||
The FTP and the SFTP/SCP protocols are thus perfect examples of how we adapt
|
||||
and adjust the code to allow non-blocking operations even on multi-stage
|
||||
protocols. The DICT, LDAP and TELNET are crappy examples and they are subject
|
||||
for rewrite in the future to better fit the libcurl protocol family.
|
||||
protocols. They are built around state machines that return when they could
|
||||
block waiting for data. The DICT, LDAP and TELNET protocols are crappy
|
||||
examples and they are subject for rewrite in the future to better fit the
|
||||
libcurl protocol family.
|
||||
|
||||
SSL libraries
|
||||
=============
|
||||
@@ -379,7 +382,9 @@ Library Symbols
|
||||
All symbols used internally in libcurl must use a 'Curl_' prefix if they're
|
||||
used in more than a single file. Single-file symbols must be made static.
|
||||
Public ("exported") symbols must use a 'curl_' prefix. (There are exceptions,
|
||||
but they are to be changed to follow this pattern in future versions.)
|
||||
but they are to be changed to follow this pattern in future versions.) Public
|
||||
API functions are marked with CURL_EXTERN in the public header files so that
|
||||
all others can be hidden on platforms where this is possible.
|
||||
|
||||
Return Codes and Informationals
|
||||
===============================
|
||||
@@ -462,15 +467,15 @@ Test Suite
|
||||
subdirectory directly off the root in the curl archive tree, and it contains
|
||||
a bunch of scripts and a lot of test case data.
|
||||
|
||||
The main test script is runtests.pl that will invoke the two servers
|
||||
The main test script is runtests.pl that will invoke test servers like
|
||||
httpserver.pl and ftpserver.pl before all the test cases are performed. The
|
||||
test suite currently only runs on unix-like platforms.
|
||||
|
||||
You'll find a complete description of the test case data files in the
|
||||
tests/README file.
|
||||
You'll find a description of the test suite in the tests/README file, and the
|
||||
test case data files in the tests/FILEFORMAT file.
|
||||
|
||||
The test suite automatically detects if curl was built with the memory
|
||||
debugging enabled, and if it was it will detect memory leaks too.
|
||||
debugging enabled, and if it was it will detect memory leaks, too.
|
||||
|
||||
Building Releases
|
||||
=================
|
||||
|
@@ -55,6 +55,10 @@ NSS http://www.mozilla.org/projects/security/pki/nss/
|
||||
grant you different permissions and impose different obligations. You
|
||||
should select the license that best meets your needs.
|
||||
|
||||
axTLS http://axtls.sourceforge.net/
|
||||
|
||||
(May be used for SSL/TLS support) Uses a Modified BSD-style license.
|
||||
|
||||
c-ares http://daniel.haxx.se/projects/c-ares/license.html
|
||||
|
||||
(Used for asynchronous name resolves) Uses an MIT license that is very
|
||||
|
@@ -30,6 +30,7 @@ Alexey Borzov
|
||||
Alexey Pesternikov
|
||||
Alexey Simak
|
||||
Alexis Carvalho
|
||||
Alfred Gebert
|
||||
Allen Pulsifer
|
||||
Amol Pattekar
|
||||
Anatoli Tubman
|
||||
@@ -199,6 +200,7 @@ Dimitris Sarris
|
||||
Dinar
|
||||
Dirk Eddelbuettel
|
||||
Dirk Manske
|
||||
Dmitri Shubin
|
||||
Dmitriy Sergeyev
|
||||
Dmitry Bartsevich
|
||||
Dmitry Kurochkin
|
||||
@@ -307,10 +309,12 @@ Hardeep Singh
|
||||
Harshal Pradhan
|
||||
Hauke Duden
|
||||
Heikki Korpela
|
||||
Heinrich Ko
|
||||
Hendrik Visage
|
||||
Henrik Storner
|
||||
Hidemoto Nakada
|
||||
Hoi-Ho Chan
|
||||
Hongli Lai
|
||||
Howard Chu
|
||||
Hzhijun
|
||||
Ian Ford
|
||||
@@ -522,6 +526,7 @@ Matt Witherspoon
|
||||
Matt Wixson
|
||||
Matthew Blain
|
||||
Matthew Clarke
|
||||
Matthias Bolte
|
||||
Maurice Barnum
|
||||
Mauro Iorio
|
||||
Max Katsev
|
||||
@@ -695,6 +700,7 @@ Rosimildo da Silva
|
||||
Roy Shan
|
||||
Rune Kleveland
|
||||
Ruslan Gazizov
|
||||
Rutger Hofman
|
||||
Ryan Chan
|
||||
Ryan Nelson
|
||||
S. Moonesamy
|
||||
@@ -735,6 +741,7 @@ Stan van de Burgt
|
||||
Stefan Esser
|
||||
Stefan Krause
|
||||
Stefan Teleman
|
||||
Stefan Tomanek
|
||||
Stefan Ulrich
|
||||
Stephan Bergmann
|
||||
Stephen Collyer
|
||||
|
10
docs/TODO
10
docs/TODO
@@ -16,6 +16,7 @@
|
||||
1.2 More data sharing
|
||||
1.3 struct lifreq
|
||||
1.4 signal-based resolver timeouts
|
||||
1.5 get rid of PATH_MAX
|
||||
|
||||
2. libcurl - multi interface
|
||||
2.1 More non-blocking
|
||||
@@ -134,6 +135,15 @@
|
||||
Also, alarm() provides timeout resolution only to the nearest second. alarm
|
||||
ought to be replaced by setitimer on systems that support it.
|
||||
|
||||
1.5 get rid of PATH_MAX
|
||||
|
||||
Having code use and rely on PATH_MAX is not nice:
|
||||
http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
|
||||
Currently the SSH based code uses it a bit, but to remove PATH_MAX from there
|
||||
we need libssh2 to properly tell us when we pass in a too small buffer and
|
||||
its current API (as of libssh2 1.2.7) doesn't.
|
||||
|
||||
2. libcurl - multi interface
|
||||
|
||||
2.1 More non-blocking
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Online: http://curl.haxx.se/docs/httpscripting.html
|
||||
Date: May 28, 2008
|
||||
Date: Jan 19, 2011
|
||||
|
||||
The Art Of Scripting HTTP Requests Using Curl
|
||||
=============================================
|
||||
@@ -38,10 +38,26 @@ Date: May 28, 2008
|
||||
request a particular action, and then the server replies a few text lines
|
||||
before the actual requested content is sent to the client.
|
||||
|
||||
Using curl's option --verbose (-v as a short option) will display what kind of
|
||||
commands curl sends to the server, as well as a few other informational texts.
|
||||
--verbose is the single most useful option when it comes to debug or even
|
||||
understand the curl<->server interaction.
|
||||
The client, curl, sends a HTTP request. The request contains a method (like
|
||||
GET, POST, HEAD etc), a number of request headers and sometimes a request
|
||||
body. The HTTP server responds with a status line (indicating if things went
|
||||
well), response headers and most often also a response body. The "body" part
|
||||
is the plain data you requested, like the actual HTML or the image etc.
|
||||
|
||||
1.1 See the Protocol
|
||||
|
||||
Using curl's option --verbose (-v as a short option) will display what kind
|
||||
of commands curl sends to the server, as well as a few other informational
|
||||
texts.
|
||||
|
||||
--verbose is the single most useful option when it comes to debug or even
|
||||
understand the curl<->server interaction.
|
||||
|
||||
Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer
|
||||
even more details as they show EVERYTHING curl sends and receives. Use it
|
||||
like this:
|
||||
|
||||
curl --trace-ascii debugdump.txt http://www.example.com/
|
||||
|
||||
2. URL
|
||||
|
||||
@@ -61,10 +77,10 @@ Date: May 28, 2008
|
||||
you get a web page returned in your terminal window. The entire HTML document
|
||||
that that URL holds.
|
||||
|
||||
All HTTP replies contain a set of headers that are normally hidden, use
|
||||
curl's --include (-i) option to display them as well as the rest of the
|
||||
document. You can also ask the remote server for ONLY the headers by using the
|
||||
--head (-I) option (which will make curl issue a HEAD request).
|
||||
All HTTP replies contain a set of response headers that are normally hidden,
|
||||
use curl's --include (-i) option to display them as well as the rest of the
|
||||
document. You can also ask the remote server for ONLY the headers by using
|
||||
the --head (-I) option (which will make curl issue a HEAD request).
|
||||
|
||||
4. Forms
|
||||
|
||||
@@ -127,7 +143,8 @@ Date: May 28, 2008
|
||||
And to use curl to post this form with the same data filled in as before, we
|
||||
could do it like:
|
||||
|
||||
curl --data "birthyear=1905&press=%20OK%20" http://www.hotmail.com/when/junk.cgi
|
||||
curl --data "birthyear=1905&press=%20OK%20" \
|
||||
http://www.example.com/when.cgi
|
||||
|
||||
This kind of POST will use the Content-Type
|
||||
application/x-www-form-urlencoded and is the most widely used POST kind.
|
||||
@@ -204,7 +221,7 @@ Date: May 28, 2008
|
||||
|
||||
Put a file to a HTTP server with curl:
|
||||
|
||||
curl --upload-file uploadfile http://www.uploadhttp.com/receive.cgi
|
||||
curl --upload-file uploadfile http://www.example.com/receive.cgi
|
||||
|
||||
6. HTTP Authentication
|
||||
|
||||
@@ -217,7 +234,7 @@ Date: May 28, 2008
|
||||
|
||||
To tell curl to use a user and password for authentication:
|
||||
|
||||
curl --user name:password http://www.secrets.com
|
||||
curl --user name:password http://www.example.com
|
||||
|
||||
The site might require a different authentication method (check the headers
|
||||
returned by the server), and then --ntlm, --digest, --negotiate or even
|
||||
@@ -257,7 +274,7 @@ Date: May 28, 2008
|
||||
|
||||
Use curl to set the referer field with:
|
||||
|
||||
curl --referer http://curl.haxx.se http://daniel.haxx.se
|
||||
curl --referer http://www.example.come http://www.example.com
|
||||
|
||||
8. User Agent
|
||||
|
||||
@@ -273,13 +290,13 @@ Date: May 28, 2008
|
||||
is time to set the User Agent field to fool the server into thinking you're
|
||||
one of those browsers.
|
||||
|
||||
To make curl look like Internet Explorer on a Windows 2000 box:
|
||||
To make curl look like Internet Explorer 5 on a Windows 2000 box:
|
||||
|
||||
curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
|
||||
curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
|
||||
|
||||
Or why not look like you're using Netscape 4.73 on a Linux (PIII) box:
|
||||
Or why not look like you're using Netscape 4.73 on an old Linux box:
|
||||
|
||||
curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
|
||||
curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
|
||||
|
||||
9. Redirects
|
||||
|
||||
@@ -294,7 +311,7 @@ Date: May 28, 2008
|
||||
|
||||
To tell curl to follow a Location:
|
||||
|
||||
curl --location http://www.sitethatredirects.com
|
||||
curl --location http://www.example.com
|
||||
|
||||
If you use curl to POST to a site that immediately redirects you to another
|
||||
page, you can safely use --location (-L) and --data/--form together. Curl will
|
||||
@@ -321,13 +338,13 @@ Date: May 28, 2008
|
||||
The simplest way to send a few cookies to the server when getting a page with
|
||||
curl is to add them on the command line like:
|
||||
|
||||
curl --cookie "name=Daniel" http://www.cookiesite.com
|
||||
curl --cookie "name=Daniel" http://www.example.com
|
||||
|
||||
Cookies are sent as common HTTP headers. This is practical as it allows curl
|
||||
to record cookies simply by recording headers. Record cookies with curl by
|
||||
using the --dump-header (-D) option like:
|
||||
|
||||
curl --dump-header headers_and_cookies http://www.cookiesite.com
|
||||
curl --dump-header headers_and_cookies http://www.example.com
|
||||
|
||||
(Take note that the --cookie-jar option described below is a better way to
|
||||
store cookies.)
|
||||
@@ -338,24 +355,25 @@ Date: May 28, 2008
|
||||
believing you had a previous connection). To use previously stored cookies,
|
||||
you run curl like:
|
||||
|
||||
curl --cookie stored_cookies_in_file http://www.cookiesite.com
|
||||
curl --cookie stored_cookies_in_file http://www.example.com
|
||||
|
||||
Curl's "cookie engine" gets enabled when you use the --cookie option. If you
|
||||
only want curl to understand received cookies, use --cookie with a file that
|
||||
doesn't exist. Example, if you want to let curl understand cookies from a page
|
||||
and follow a location (and thus possibly send back cookies it received), you
|
||||
can invoke it like:
|
||||
doesn't exist. Example, if you want to let curl understand cookies from a
|
||||
page and follow a location (and thus possibly send back cookies it received),
|
||||
you can invoke it like:
|
||||
|
||||
curl --cookie nada --location http://www.cookiesite.com
|
||||
curl --cookie nada --location http://www.example.com
|
||||
|
||||
Curl has the ability to read and write cookie files that use the same file
|
||||
format that Netscape and Mozilla do. It is a convenient way to share cookies
|
||||
between browsers and automatic scripts. The --cookie (-b) switch automatically
|
||||
detects if a given file is such a cookie file and parses it, and by using the
|
||||
--cookie-jar (-c) option you'll make curl write a new cookie file at the end of
|
||||
an operation:
|
||||
between browsers and automatic scripts. The --cookie (-b) switch
|
||||
automatically detects if a given file is such a cookie file and parses it,
|
||||
and by using the --cookie-jar (-c) option you'll make curl write a new cookie
|
||||
file at the end of an operation:
|
||||
|
||||
curl --cookie cookies.txt --cookie-jar newcookies.txt http://www.cookiesite.com
|
||||
curl --cookie cookies.txt --cookie-jar newcookies.txt \
|
||||
http://www.example.com
|
||||
|
||||
11. HTTPS
|
||||
|
||||
@@ -371,7 +389,7 @@ Date: May 28, 2008
|
||||
Curl supports encrypted fetches thanks to the freely available OpenSSL
|
||||
libraries. To get a page from a HTTPS server, simply run curl like:
|
||||
|
||||
curl https://that.secure.server.com
|
||||
curl https://secure.example.com
|
||||
|
||||
11.1 Certificates
|
||||
|
||||
@@ -382,7 +400,7 @@ Date: May 28, 2008
|
||||
can be specified on the command line or if not, entered interactively when
|
||||
curl queries for it. Use a certificate with curl on a HTTPS server like:
|
||||
|
||||
curl --cert mycert.pem https://that.secure.server.com
|
||||
curl --cert mycert.pem https://secure.example.com
|
||||
|
||||
curl also tries to verify that the server is who it claims to be, by
|
||||
verifying the server's certificate against a locally stored CA cert
|
||||
@@ -403,17 +421,18 @@ Date: May 28, 2008
|
||||
For example, you can change the POST request to a PROPFIND and send the data
|
||||
as "Content-Type: text/xml" (instead of the default Content-Type) like this:
|
||||
|
||||
curl --data "<xml>" --header "Content-Type: text/xml" --request PROPFIND url.com
|
||||
curl --data "<xml>" --header "Content-Type: text/xml" \
|
||||
--request PROPFIND url.com
|
||||
|
||||
You can delete a default header by providing one without content. Like you
|
||||
can ruin the request by chopping off the Host: header:
|
||||
|
||||
curl --header "Host:" http://mysite.com
|
||||
curl --header "Host:" http://www.example.com
|
||||
|
||||
You can add headers the same way. Your server may want a "Destination:"
|
||||
header, and you can add it:
|
||||
|
||||
curl --header "Destination: http://moo.com/nowhere" http://url.com
|
||||
curl --header "Destination: http://nowhere" http://example.com
|
||||
|
||||
13. Web Login
|
||||
|
||||
@@ -444,7 +463,6 @@ Date: May 28, 2008
|
||||
to do a proper login POST. Remember that the contents need to be URL encoded
|
||||
when sent in a normal POST.
|
||||
|
||||
|
||||
14. Debug
|
||||
|
||||
Many times when you run curl on a site, you'll notice that the site doesn't
|
||||
@@ -480,12 +498,10 @@ Date: May 28, 2008
|
||||
RFC 2616 is a must to read if you want in-depth understanding of the HTTP
|
||||
protocol.
|
||||
|
||||
RFC 2396 explains the URL syntax.
|
||||
RFC 3986 explains the URL syntax.
|
||||
|
||||
RFC 2109 defines how cookies are supposed to work.
|
||||
|
||||
RFC 1867 defines the HTTP post upload format.
|
||||
|
||||
http://www.openssl.org is the home of the OpenSSL project
|
||||
|
||||
http://curl.haxx.se is the home of the cURL project
|
||||
|
73
docs/curl.1
73
docs/curl.1
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -20,7 +20,7 @@
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH curl 1 "28 November 2009" "Curl 7.20.0" "Curl Manual"
|
||||
.TH curl 1 "28 November 2009" "Curl 7.21.4" "Curl Manual"
|
||||
.SH NAME
|
||||
curl \- transfer a URL
|
||||
.SH SYNOPSIS
|
||||
@@ -358,11 +358,12 @@ this option assumes a \&"certificate" file that is the private key and the
|
||||
private certificate concatenated! See \fI--cert\fP and \fI--key\fP to specify
|
||||
them independently.
|
||||
|
||||
If curl is built against the NSS SSL library then this option tells
|
||||
If curl is built against the NSS SSL library then this option can tell
|
||||
curl the nickname of the certificate to use within the NSS database defined
|
||||
by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
|
||||
NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
|
||||
loaded.
|
||||
loaded. If you want to use a file from the current directory, please precede
|
||||
it with "./" prefix, in order to avoid confusion with a nickname.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cert-type <type>"
|
||||
@@ -393,11 +394,11 @@ may be loaded.
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--capath <CA certificate directory>"
|
||||
(SSL) Tells curl to use the specified certificate directory to verify the
|
||||
peer. The certificates must be in PEM format, and the directory must have been
|
||||
processed using the c_rehash utility supplied with openssl. Using
|
||||
\fI--capath\fP can allow curl to make SSL-connections much more efficiently
|
||||
than using \fI--cacert\fP if the \fI--cacert\fP file contains many CA
|
||||
certificates.
|
||||
peer. The certificates must be in PEM format, and if curl is built against
|
||||
OpenSSL, the directory must have been processed using the c_rehash utility
|
||||
supplied with OpenSSL. Using \fI--capath\fP can allow OpenSSL-powered curl to
|
||||
make SSL-connections much more efficiently than using \fI--cacert\fP if the
|
||||
\fI--cacert\fP file contains many CA certificates.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-f/--fail"
|
||||
@@ -427,7 +428,7 @@ server. The method argument should be one of the following alternatives:
|
||||
.RS
|
||||
.IP multicwd
|
||||
curl does a single CWD operation for each path part in the given URL. For deep
|
||||
hierarchies this means very many commands. This is how RFC1738 says it should
|
||||
hierarchies this means very many commands. This is how RFC 1738 says it should
|
||||
be done. This is the default but the slowest behavior.
|
||||
.IP nocwd
|
||||
curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full
|
||||
@@ -439,7 +440,7 @@ compliant than 'nocwd' but without the full penalty of 'multicwd'.
|
||||
.RE
|
||||
(Added in 7.15.1)
|
||||
.IP "--ftp-pasv"
|
||||
(FTP) Use passive mode for the data conection. Passive is the internal default
|
||||
(FTP) Use passive mode for the data connection. Passive is the internal default
|
||||
behavior, but using this option can be used to override a previous
|
||||
\fI-P/-ftp-port\fP option. (Added in 7.11.0)
|
||||
|
||||
@@ -501,7 +502,7 @@ waits for a reply from the server.
|
||||
.IP "-F/--form <name=content>"
|
||||
(HTTP) This lets curl emulate a filled-in form in which a user has pressed the
|
||||
submit button. This causes curl to POST data using the Content-Type
|
||||
multipart/form-data according to RFC2388. This enables uploading of binary
|
||||
multipart/form-data according to RFC 2388. This enables uploading of binary
|
||||
files etc. To force the 'content' part to be a file, prefix the file name
|
||||
with an @ sign. To just get the content part from a file, prefix the file name
|
||||
with the symbol <. The difference between @ and < is then that @ makes a file
|
||||
@@ -514,8 +515,8 @@ input:
|
||||
|
||||
\fBcurl\fP -F password=@/etc/passwd www.mypasswords.com
|
||||
|
||||
To read the file's content from stdin instead of a file, use - where the file
|
||||
name should've been. This goes for both @ and < constructs.
|
||||
To read content from stdin instead of a file, use - as the filename. This goes
|
||||
for both @ and < constructs.
|
||||
|
||||
You can also tell curl what Content-Type to use by using 'type=', in a manner
|
||||
similar to:
|
||||
@@ -1051,11 +1052,12 @@ just before the transfer command(s), prefix the command with a '+' (this
|
||||
is only supported for FTP). You may specify any number of commands. If
|
||||
the server returns failure for one of the commands, the entire operation
|
||||
will be aborted. You must send syntactically correct FTP commands as
|
||||
RFC959 defines to FTP servers, or one of the commands listed below to
|
||||
RFC 959 defines to FTP servers, or one of the commands listed below to
|
||||
SFTP servers. This option can be used multiple times.
|
||||
|
||||
SFTP is a binary protocol. Unlike for FTP, libcurl interprets SFTP quote
|
||||
commands before sending them to the server. Following is the list of
|
||||
commands itself before sending them to the server. File names may be quoted
|
||||
shell-style to embed spaces or special characters. Following is the list of
|
||||
all supported SFTP quote commands:
|
||||
.RS
|
||||
.IP "chgrp group file"
|
||||
@@ -1234,14 +1236,12 @@ This option (as well as \fI--socks4\fP) does not work with IPV6, FTPS or LDAP.
|
||||
The default service name for a socks server is rcmd/server-fqdn. This option
|
||||
allows you to change it.
|
||||
|
||||
Examples:
|
||||
--socks5 proxy-name \fI--socks5-gssapi-service\fP sockd would use
|
||||
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 princpal name.
|
||||
(Added in 7.19.4).
|
||||
Examples: --socks5 proxy-name \fI--socks5-gssapi-service\fP sockd would use
|
||||
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. The rfc1961
|
||||
As part of the gssapi 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).
|
||||
@@ -1264,12 +1264,25 @@ XDISPLOC=<X display> Sets the X display location.
|
||||
NEW_ENV=<var,val> Sets an environment variable.
|
||||
.IP "--tftp-blksize <value>"
|
||||
(TFTP) Set TFTP BLKSIZE option (must be >512). This is the block size that
|
||||
curl will try to use when tranferring data to or from a TFTP server. By
|
||||
curl will try to use when transferring data to or from a TFTP server. By
|
||||
default 512 bytes will be used.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
|
||||
(Added in 7.20.0)
|
||||
.IP "--tlsauthtype <authtype>"
|
||||
Set TLS authentication type. Currently, the only supported option is "SRP",
|
||||
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
|
||||
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
|
||||
(Added in 7.21.4)
|
||||
.IP "--tlsuser <user>"
|
||||
Set username for use with the TLS authentication method specified with
|
||||
\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in
|
||||
7.21.4)
|
||||
.IP "--tlspassword <password>"
|
||||
Set password for use with the TLS authentication method specified with
|
||||
\fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in
|
||||
7.21.4)
|
||||
.IP "-T/--upload-file <file>"
|
||||
This transfers the specified local file to the remote URL. If there is no file
|
||||
part in the specified URL, Curl will append the local file name. NOTE that you
|
||||
@@ -1357,7 +1370,7 @@ If you think this option still doesn't give you enough details, consider using
|
||||
|
||||
This option overrides previous uses of \fI--trace-ascii\fP or \fI--trace\fP.
|
||||
|
||||
Use \fI-S/--silent\fP to make curl quiet.
|
||||
Use \fI-s/--silent\fP to make curl quiet.
|
||||
.IP "-V/--version"
|
||||
Displays information about curl and the libcurl version it uses.
|
||||
|
||||
@@ -1396,6 +1409,8 @@ This curl supports IDN - international domain names.
|
||||
.IP "SSPI"
|
||||
SSPI is supported. If you use NTLM and set a blank user name, curl will
|
||||
authenticate with your current user and password.
|
||||
.IP "TLS-SRP"
|
||||
SRP (Secure Remote Password) authentication is supported for TLS.
|
||||
.RE
|
||||
.IP "-w/--write-out <format>"
|
||||
Defines what to display on stdout after a completed and successful
|
||||
@@ -1552,9 +1567,9 @@ not set.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "-z/--time-cond <date expression>"
|
||||
(HTTP/FTP) Request a file that has been modified later than the given time and
|
||||
date, or one that has been modified before that time. The date expression can
|
||||
be all sorts of date strings or if it doesn't match any internal ones, it
|
||||
(HTTP/FTP/FILE) Request a file that has been modified later than the given time
|
||||
and date, or one that has been modified before that time. The date expression
|
||||
can be all sorts of date strings or if it doesn't match any internal ones, it
|
||||
tries to get the time from a given file name instead! See the
|
||||
\fIcurl_getdate(3)\fP man pages for date expression details.
|
||||
|
||||
@@ -1702,7 +1717,7 @@ Unknown TELNET option specified.
|
||||
.IP 49
|
||||
Malformed telnet option.
|
||||
.IP 51
|
||||
The peer's SSL certificate or SSH MD5 fingerprint was not ok.
|
||||
The peer's SSL certificate or SSH MD5 fingerprint was not OK.
|
||||
.IP 52
|
||||
The server didn't reply anything, which here is considered an error.
|
||||
.IP 53
|
||||
|
3
docs/examples/.gitignore
vendored
3
docs/examples/.gitignore
vendored
@@ -29,4 +29,7 @@ sendrecv
|
||||
sepheaders
|
||||
simple
|
||||
simplepost
|
||||
simplesmtp
|
||||
simplessl
|
||||
smtp-multi
|
||||
smtp-tls
|
||||
|
@@ -34,4 +34,4 @@ LDADD = $(LIBDIR)/libcurl.la
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
|
||||
all: $(check_PROGRAMS)
|
||||
|
@@ -4,7 +4,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \
|
||||
https multi-app multi-debugcallback multi-double multi-post multi-single \
|
||||
persistant post-callback postit2 sepheaders simple simplepost simplessl \
|
||||
sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \
|
||||
smtp-multi
|
||||
smtp-multi simplesmtp smtp-tls
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
|
@@ -9,9 +9,12 @@
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
(void)stream;
|
||||
(void)ptr;
|
||||
return size * nmemb;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
|
||||
} else if (strncasecmp(*argv, "-T", 2) == 0) {
|
||||
prttime = 1;
|
||||
} else if (strncasecmp(*argv, "-M=", 3) == 0) {
|
||||
long m = strtol(argv+3, NULL, 10);
|
||||
long m = strtol((*argv)+3, NULL, 10);
|
||||
switch(m) {
|
||||
case 1: url = URL_1M;
|
||||
break;
|
||||
|
@@ -28,12 +28,12 @@ void dump(const char *text,
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %010.10ld bytes (0x%08.8lx)\n",
|
||||
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%04.4lx: ", (long)i);
|
||||
fprintf(stream, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
|
@@ -367,7 +367,7 @@ static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
int sockfd;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if ( lstat (fifo, &st) == 0 )
|
||||
|
@@ -68,8 +68,8 @@ struct fcurl_data
|
||||
} handle; /* handle */
|
||||
|
||||
char *buffer; /* buffer to store cached data*/
|
||||
int buffer_len; /* currently allocated buffers length */
|
||||
int buffer_pos; /* end of data in buffer*/
|
||||
size_t buffer_len; /* currently allocated buffers length */
|
||||
size_t buffer_pos; /* end of data in buffer*/
|
||||
int still_running; /* Is background url fetch still in progress */
|
||||
};
|
||||
|
||||
@@ -80,7 +80,7 @@ URL_FILE *url_fopen(const char *url,const char *operation);
|
||||
int url_fclose(URL_FILE *file);
|
||||
int url_feof(URL_FILE *file);
|
||||
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
|
||||
char * url_fgets(char *ptr, int size, URL_FILE *file);
|
||||
char * url_fgets(char *ptr, size_t size, URL_FILE *file);
|
||||
void url_rewind(URL_FILE *file);
|
||||
|
||||
/* we use a global one for convenience */
|
||||
@@ -93,7 +93,7 @@ static size_t write_callback(char *buffer,
|
||||
void *userp)
|
||||
{
|
||||
char *newbuff;
|
||||
int rembuff;
|
||||
size_t rembuff;
|
||||
|
||||
URL_FILE *url = (URL_FILE *)userp;
|
||||
size *= nitems;
|
||||
@@ -121,7 +121,7 @@ static size_t write_callback(char *buffer,
|
||||
}
|
||||
|
||||
/* use to attempt to fill the read buffer up to requested number of bytes */
|
||||
static int fill_buffer(URL_FILE *file,int want,int waittime)
|
||||
static int fill_buffer(URL_FILE *file, size_t want)
|
||||
{
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
@@ -323,7 +323,7 @@ size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||
case CFTYPE_CURL:
|
||||
want = nmemb * size;
|
||||
|
||||
fill_buffer(file,want,1);
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill_buffer()
|
||||
* either errored or EOF */
|
||||
@@ -351,10 +351,10 @@ size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
|
||||
return want;
|
||||
}
|
||||
|
||||
char *url_fgets(char *ptr, int size, URL_FILE *file)
|
||||
char *url_fgets(char *ptr, size_t size, URL_FILE *file)
|
||||
{
|
||||
int want = size - 1;/* always need to leave room for zero termination */
|
||||
int loop;
|
||||
size_t want = size - 1;/* always need to leave room for zero termination */
|
||||
size_t loop;
|
||||
|
||||
switch(file->type) {
|
||||
case CFTYPE_FILE:
|
||||
@@ -362,7 +362,7 @@ char *url_fgets(char *ptr, int size, URL_FILE *file)
|
||||
break;
|
||||
|
||||
case CFTYPE_CURL:
|
||||
fill_buffer(file,want,1);
|
||||
fill_buffer(file,want);
|
||||
|
||||
/* check if theres data in the buffer - if not fill either errored or
|
||||
* EOF */
|
||||
|
@@ -21,6 +21,8 @@
|
||||
|
||||
static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
/* we are not interested in the headers itself,
|
||||
so we only return the size we would have saved ... */
|
||||
return (size_t)(size * nmemb);
|
||||
@@ -58,7 +60,7 @@ int main(void)
|
||||
if((CURLE_OK == res) && filetime)
|
||||
printf("filetime %s: %s", filename, ctime(&filetime));
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
|
||||
if((CURLE_OK == res) && filesize)
|
||||
if((CURLE_OK == res) && (filesize>0))
|
||||
printf("filesize %s: %0.0f bytes\n", filename, filesize);
|
||||
} else {
|
||||
/* we failed */
|
||||
|
@@ -27,7 +27,7 @@ write_response(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
return fwrite(ptr, size, nmemb, writehere);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
@@ -48,7 +48,7 @@ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
@@ -43,7 +43,7 @@ WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
|
||||
@@ -87,7 +87,7 @@ int main(int argc, char **argv)
|
||||
* you're done with it, you should free() it as a nice application.
|
||||
*/
|
||||
|
||||
printf("%lu bytes retrieved\n", chunk.size);
|
||||
printf("%lu bytes retrieved\n", (long)chunk.size);
|
||||
|
||||
if(chunk.memory)
|
||||
free(chunk.memory);
|
||||
|
@@ -350,7 +350,7 @@ static int init_fifo (GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
int sockfd;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if (lstat (fifo, &st) == 0) {
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
|
||||
#define FTP_HANDLE 1 /* Index for the FTP transfer */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *handles[HANDLECOUNT];
|
||||
CURLM *multi_handle;
|
||||
|
@@ -37,12 +37,12 @@ void dump(const char *text,
|
||||
/* without the hex output, we can fit more on screen */
|
||||
width = 0x40;
|
||||
|
||||
fprintf(stream, "%s, %010.10ld bytes (0x%08.8lx)\n",
|
||||
fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n",
|
||||
text, (long)size, (long)size);
|
||||
|
||||
for(i=0; i<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%04.4lx: ", (long)i);
|
||||
fprintf(stream, "%4.4lx: ", (long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
@@ -79,6 +79,7 @@ int my_trace(CURL *handle, curl_infotype type,
|
||||
{
|
||||
const char *text;
|
||||
|
||||
(void)userp;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch (type) {
|
||||
@@ -108,7 +109,7 @@ int my_trace(CURL *handle, curl_infotype type,
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Simply download two HTTP files!
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURL *http_handle2;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#include <unistd.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* Auxiliary function that waits on the socket. */
|
||||
static int wait_on_socket(int sockfd, int for_recv, long timeout_ms)
|
||||
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set infd, outfd, errfd;
|
||||
@@ -49,7 +49,8 @@ int main(void)
|
||||
CURLcode res;
|
||||
/* Minimalistic http request */
|
||||
const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
|
||||
int sockfd; /* socket */
|
||||
curl_socket_t sockfd; /* socket */
|
||||
long sockextr;
|
||||
size_t iolen;
|
||||
|
||||
curl = curl_easy_init();
|
||||
@@ -65,9 +66,11 @@ int main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract the socket from the curl handle - we'll need it
|
||||
* for waiting */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockfd);
|
||||
/* Extract the socket from the curl handle - we'll need it for waiting.
|
||||
* Note that this API takes a pointer to a 'long' while we use
|
||||
* curl_socket_t for sockets otherwise.
|
||||
*/
|
||||
res = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr);
|
||||
|
||||
if(CURLE_OK != res)
|
||||
{
|
||||
@@ -75,6 +78,8 @@ int main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sockfd = sockextr;
|
||||
|
||||
/* wait for the socket to become ready for sending */
|
||||
if(!wait_on_socket(sockfd, 0, 60000L))
|
||||
{
|
||||
|
@@ -21,7 +21,7 @@ static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
return written;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
static const char *headerfilename = "head.out";
|
||||
|
71
docs/examples/simplesmtp.c
Normal file
71
docs/examples/simplesmtp.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *recipients = NULL;
|
||||
|
||||
/* value for envelope reverse-path */
|
||||
static const char *from = "<bradh@example.com>";
|
||||
|
||||
/* this becomes the envelope forward-path */
|
||||
static const char *to = "<bradh@example.net>";
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* this is the URL for your mailserver - you can also use an smtps:// URL
|
||||
* here */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.net.");
|
||||
|
||||
/* Note that this option isn't strictly required, omitting it will result in
|
||||
* libcurl will sent the MAIL FROM command with no sender data. All
|
||||
* autoresponses should have an empty reverse-path, and should be directed
|
||||
* to the address in the reverse-path which triggered them. Otherwise, they
|
||||
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);
|
||||
|
||||
/* Note that the CURLOPT_MAIL_RCPT takes a list, not a char array. */
|
||||
recipients = curl_slist_append(recipients, to);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
|
||||
|
||||
/* You provide the payload (headers and the body of the message) as the
|
||||
* "data" element. There are two choices, either:
|
||||
* - provide a callback function and specify the function name using the
|
||||
* CURLOPT_READFUNCTION option; or
|
||||
* - just provide a FILE pointer that can be used to read the data from.
|
||||
* The easiest case is just to read from standard input, (which is available
|
||||
* as a FILE pointer) as shown here.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, stdin);
|
||||
|
||||
/* send the message (including headers) */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* free the list of recipients */
|
||||
curl_slist_free_all(recipients);
|
||||
|
||||
/* curl won't send the QUIT command until you call cleanup, so you should be
|
||||
* able to re-use this connection for additional messages (setting
|
||||
* CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling
|
||||
* curl_easy_perform() again. It may not be a good idea to keep the
|
||||
* connection open for a very long time though (more than a few minutes may
|
||||
* result in the server timing out the connection), and you do want to clean
|
||||
* up in the end.
|
||||
*/
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -32,7 +32,7 @@
|
||||
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
@@ -47,7 +47,7 @@ int main(int argc, char **argv)
|
||||
|
||||
const char *pEngine;
|
||||
|
||||
#if USE_ENGINE
|
||||
#ifdef USE_ENGINE
|
||||
pKeyName = "rsa_test";
|
||||
pKeyType = "ENG";
|
||||
pEngine = "chil"; /* for nChiper HSM... */
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#define SMTPSERVER "smtp.example.com"
|
||||
#define SMTPPORT ":587" /* it is a colon+port string, but you can set it
|
||||
to "" to use the default port */
|
||||
#define RECEPIENT "receipient@example.com"
|
||||
#define RECIPIENT "<recipient@example.com>"
|
||||
#define MAILFROM "<realuser@example.com>"
|
||||
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
@@ -99,9 +99,9 @@ int main(void)
|
||||
if(!mcurl)
|
||||
return 2;
|
||||
|
||||
rcpt_list = curl_slist_append(rcpt_list, RECEPIENT);
|
||||
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
|
||||
/* more addresses can be added here
|
||||
rcpt_list = curl_slist_append(rcpt_list, "others@example.com");
|
||||
rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
|
||||
*/
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://" SMTPSERVER SMTPPORT);
|
||||
|
136
docs/examples/smtp-tls.c
Normal file
136
docs/examples/smtp-tls.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to send mail using libcurl's SMTP
|
||||
* capabilities. It builds on the simplesmtp.c example, adding some
|
||||
* authentication and transport security.
|
||||
*/
|
||||
|
||||
#define FROM "<sender@example.org>"
|
||||
#define TO "<addressee@example.net>"
|
||||
#define CC "<info@example.org>"
|
||||
|
||||
static const char *payload_text[]={
|
||||
"Date: Mon, 29 Nov 2010 21:54:29 +1100\n",
|
||||
"To: " TO "\n",
|
||||
"From: " FROM "(Example User)\n",
|
||||
"Cc: " CC "(Another example User)\n",
|
||||
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\n",
|
||||
"Subject: SMTP TLS example message\n",
|
||||
"\n", /* empty line to divide headers from body, see RFC5322 */
|
||||
"The body of the message starts here.\n",
|
||||
"\n",
|
||||
"It could be a lot of lines, could be MIME encoded, whatever.\n",
|
||||
"Check RFC5322.\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct upload_status {
|
||||
int lines_read;
|
||||
};
|
||||
|
||||
static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
|
||||
if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = payload_text[upload_ctx->lines_read];
|
||||
|
||||
if (data) {
|
||||
size_t len = strlen(data);
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->lines_read ++;
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *recipients = NULL;
|
||||
struct upload_status upload_ctx;
|
||||
|
||||
upload_ctx.lines_read = 0;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (curl) {
|
||||
/* This is the URL for your mailserver. Note the use of port 587 here,
|
||||
* instead of the normal SMTP port (25). Port 587 is commonly used for
|
||||
* secure mail submission (see RFC4403), but you should use whatever
|
||||
* matches your server configuration. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "smtp://mainserver.example.net:587");
|
||||
|
||||
/* In this example, we'll start with a plain text connection, and upgrade
|
||||
* to Transport Layer Security (TLS) using the STARTTLS command. Be careful
|
||||
* of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
|
||||
* will continue anyway - see the security discussion in the libcurl
|
||||
* tutorial for more details. */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
/* If your server doesn't have a valid certificate, then you can disable
|
||||
* part of the Transport Layer Security protection by setting the
|
||||
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
* That is, in general, a bad idea. It is still better than sending your
|
||||
* authentication details in plain text though.
|
||||
* Instead, you should get the issuer certificate (or the host certificate
|
||||
* if the certificate is self-signed) and add it to the set of certificates
|
||||
* that are known to libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See
|
||||
* docs/SSLCERTS for more information.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
|
||||
|
||||
/* A common reason for requiring transport security is to protect
|
||||
* authentication details (user names and passwords) from being "snooped"
|
||||
* on the network. Here is how the user name and password are provided: */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user@example.net");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "P@ssw0rd");
|
||||
|
||||
/* value for envelope reverse-path */
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
|
||||
/* Add two recipients, in this particular case they correspond to the
|
||||
* To: and Cc: addressees in the header, but they could be any kind of
|
||||
* recipient. */
|
||||
recipients = curl_slist_append(recipients, TO);
|
||||
recipients = curl_slist_append(recipients, CC);
|
||||
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
|
||||
|
||||
/* In this case, we're using a callback function to specify the data. You
|
||||
* could just use the CURLOPT_READDATA option to specify a FILE pointer to
|
||||
* read from.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the transfer.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
/* send the message (including headers) */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* free the list of recipients and clean up */
|
||||
curl_slist_free_all(recipients);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -206,6 +206,8 @@ Pass a pointer to a char pointer to receive a pointer to a string holding the
|
||||
path of the entry path. That is the initial path libcurl ended up in when
|
||||
logging on to the remote FTP server. This stores a NULL as pointer if
|
||||
something is wrong. (Added in 7.15.4)
|
||||
|
||||
Also works for SFTP since 7.21.4
|
||||
.IP CURLINFO_CERTINFO
|
||||
Pass a pointer to a 'struct curl_certinfo *' and you'll get it set to point to
|
||||
struct that holds a number of linked lists with info about the certificate
|
||||
|
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -870,6 +870,29 @@ This is a meta symbol. Or this value together with a single specific auth
|
||||
value to force libcurl to probe for un-restricted auth and if not, only that
|
||||
single auth algorithm is acceptable. (Added in 7.21.3)
|
||||
.RE
|
||||
.IP CURLOPT_TLSAUTH_TYPE
|
||||
Pass a long as parameter, which is set to a bitmask, to tell libcurl which
|
||||
authentication method(s) you want it to use for TLS authentication.
|
||||
.RS
|
||||
.IP CURLOPT_TLSAUTH_SRP
|
||||
TLS-SRP authentication. Secure Remote Password authentication for TLS is
|
||||
defined in RFC 5054 and provides mutual authentication if both sides have a
|
||||
shared secret. To use TLS-SRP, you must also set the
|
||||
\fICURLOPT_TLSAUTH_USERNAME\fP and \fICURLOPT_TLSAUTH_PASSWORD\fP options.
|
||||
|
||||
You need to build libcurl with GnuTLS and with TLS-SRP support for this to
|
||||
work. (Added in 7.21.4)
|
||||
.RE
|
||||
.IP CURLOPT_TLSAUTH_USERNAME
|
||||
Pass a char * as parameter, which should point to the zero-terminated username
|
||||
to use for the TLS authentication method specified with the
|
||||
\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
|
||||
\fICURLOPT_TLS_PASSWORD\fP option also be set. (Added in 7.21.4)
|
||||
.IP CURLOPT_TLSAUTH_PASSWORD
|
||||
Pass a char * as parameter, which should point to the zero-terminated password
|
||||
to use for the TLS authentication method specified with the
|
||||
\fICURLOPT_TLSAUTH_TYPE\fP option. Requires that the
|
||||
\fICURLOPT_TLS_USERNAME\fP option also be set. (Added in 7.21.4)
|
||||
.IP CURLOPT_PROXYAUTH
|
||||
Pass a long as parameter, which is set to a bitmask, to tell libcurl which
|
||||
authentication method(s) you want it to use for your proxy authentication. If
|
||||
@@ -1189,6 +1212,10 @@ option is set to zero. (added in 7.16.2)
|
||||
Pass a pointer to a zero terminated string as parameter. It will be used to
|
||||
specify the sender address in a mail when sending an SMTP mail with libcurl.
|
||||
|
||||
An originator email address in SMTP lingo is specified within angle brackets
|
||||
(<>) which libcurl will not add for you before version 7.21.4. Failing to
|
||||
provide such brackets may cause the server to reject your mail.
|
||||
|
||||
(Added in 7.20.0)
|
||||
.IP CURLOPT_MAIL_RCPT
|
||||
Pass a pointer to a linked list of recipients to pass to the server in your
|
||||
@@ -1644,8 +1671,8 @@ given limit. This concerns both FTP and HTTP transfers.
|
||||
.IP CURLOPT_TIMECONDITION
|
||||
Pass a long as parameter. This defines how the \fICURLOPT_TIMEVALUE\fP time
|
||||
value is treated. You can set this parameter to \fICURL_TIMECOND_IFMODSINCE\fP
|
||||
or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP, FTP, and
|
||||
RTSP.
|
||||
or \fICURL_TIMECOND_IFUNMODSINCE\fP. This feature applies to HTTP, FTP, RTSP,
|
||||
and FILE.
|
||||
|
||||
The last modification time of a file is not always known and in such instances
|
||||
this feature will have no effect even if the given time condition would not
|
||||
@@ -1807,8 +1834,9 @@ Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the file name of your certificate. The default format is "PEM" and can be
|
||||
changed with \fICURLOPT_SSLCERTTYPE\fP.
|
||||
|
||||
With NSS this is the nickname of the certificate you wish to authenticate
|
||||
with.
|
||||
With NSS this can also be the nickname of the certificate you wish to
|
||||
authenticate with. If you want to use a file from the current directory, please
|
||||
precede it with "./" prefix, in order to avoid confusion with a nickname.
|
||||
.IP CURLOPT_SSLCERTTYPE
|
||||
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||
the format of your certificate. Supported formats are "PEM" and "DER". (Added
|
||||
@@ -1867,28 +1895,30 @@ Force SSLv2
|
||||
Force SSLv3
|
||||
.RE
|
||||
.IP CURLOPT_SSL_VERIFYPEER
|
||||
Pass a long as parameter.
|
||||
Pass a long as parameter. By default, curl assumes a value of 1.
|
||||
|
||||
This option determines whether curl verifies the authenticity of the peer's
|
||||
certificate. A value of 1 means curl verifies; zero means it doesn't. The
|
||||
default is nonzero, but before 7.10, it was zero.
|
||||
certificate. A value of 1 means curl verifies; 0 (zero) means it doesn't.
|
||||
|
||||
When negotiating an SSL connection, the server sends a certificate indicating
|
||||
its identity. Curl verifies whether the certificate is authentic, i.e. that
|
||||
you can trust that the server is who the certificate says it is. This trust
|
||||
is based on a chain of digital signatures, rooted in certification authority
|
||||
(CA) certificates you supply. As of 7.10, curl installs a default bundle of
|
||||
CA certificates and you can specify alternate certificates with the
|
||||
\fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP option.
|
||||
(CA) certificates you supply. curl uses a default bundle of CA certificates
|
||||
(the path for that is determined at build time) and you can specify alternate
|
||||
certificates with the \fICURLOPT_CAINFO\fP option or the \fICURLOPT_CAPATH\fP
|
||||
option.
|
||||
|
||||
When \fICURLOPT_SSL_VERIFYPEER\fP is nonzero, and the verification fails to
|
||||
prove that the certificate is authentic, the connection fails. When the
|
||||
option is zero, the connection succeeds regardless.
|
||||
option is zero, the peer certificate verification succeeds regardless.
|
||||
|
||||
Authenticating the certificate is not by itself very useful. You typically
|
||||
want to ensure that the server, as authentically identified by its
|
||||
certificate, is the server you mean to be talking to. Use
|
||||
\fICURLOPT_SSL_VERIFYHOST\fP to control that.
|
||||
\fICURLOPT_SSL_VERIFYHOST\fP to control 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\fP option.
|
||||
.IP CURLOPT_CAINFO
|
||||
Pass a char * to a zero terminated string naming a file holding one or more
|
||||
certificates to verify the peer with. This makes sense only when used in
|
||||
@@ -1919,13 +1949,15 @@ mismatch with the issuer of peer certificate (\fICURLOPT_SSL_VERIFYPEER\fP has
|
||||
to be set too for the check to fail). (Added in 7.19.0)
|
||||
.IP CURLOPT_CAPATH
|
||||
Pass a char * to a zero terminated string naming a directory holding multiple
|
||||
CA certificates to verify the peer with. 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\fP option. If
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP is zero, \fICURLOPT_CAPATH\fP need not even
|
||||
indicate an accessible path. The \fICURLOPT_CAPATH\fP function apparently
|
||||
does not work in Windows due to some limitation in openssl. This option is
|
||||
OpenSSL-specific and does nothing if libcurl is built to use GnuTLS.
|
||||
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\fP option. If \fICURLOPT_SSL_VERIFYPEER\fP is zero,
|
||||
\fICURLOPT_CAPATH\fP need not even indicate an accessible path. The
|
||||
\fICURLOPT_CAPATH\fP function apparently does not work in Windows due to some
|
||||
limitation in openssl. This option is OpenSSL-specific and does nothing if
|
||||
libcurl is built to use GnuTLS. NSS-powered libcurl provides the option only
|
||||
for backward compatibility.
|
||||
.IP CURLOPT_CRLFILE
|
||||
Pass a char * to a zero terminated string naming a file with the concatenation
|
||||
of CRL (in PEM format) to use in the certificate validation that occurs during
|
||||
@@ -1944,20 +1976,6 @@ A specific error code (CURLE_SSL_CRL_BADFILE) is defined with the option. It
|
||||
is returned when the SSL exchange fails because the CRL file cannot be loaded.
|
||||
A failure in certificate verification due to a revocation information found in
|
||||
the CRL does not trigger this specific error. (Added in 7.19.0)
|
||||
.IP CURLOPT_CERTINFO
|
||||
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
||||
this enabled, libcurl (if built with OpenSSL) will extract lots of information
|
||||
and data about the certificates in the certificate chain used in the SSL
|
||||
connection. This data is then possible to extract after a transfer using
|
||||
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
||||
7.19.1)
|
||||
.IP CURLOPT_RANDOM_FILE
|
||||
Pass a char * to a zero terminated file name. The file will be used to read
|
||||
from to seed the random engine for SSL. The more random the specified file is,
|
||||
the more secure the SSL connection will become.
|
||||
.IP CURLOPT_EGDSOCKET
|
||||
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
|
||||
socket. It will be used to seed the random engine for SSL.
|
||||
.IP CURLOPT_SSL_VERIFYHOST
|
||||
Pass a long as parameter.
|
||||
|
||||
@@ -1981,10 +1999,25 @@ doesn't matter what name it says. (This is not ordinarily a useful setting).
|
||||
When the value is 0, the connection succeeds regardless of the names in the
|
||||
certificate.
|
||||
|
||||
The default, since 7.10, is 2.
|
||||
The default value for this option is 2.
|
||||
|
||||
This option controls checking the server's claimed identity. The server could
|
||||
be lying. To control lying, see \fICURLOPT_SSL_VERIFYPEER\fP.
|
||||
This option controls checking the server's certificate's claimed identity.
|
||||
The server could be lying. To control lying, see
|
||||
\fICURLOPT_SSL_VERIFYPEER\fP.
|
||||
.IP CURLOPT_CERTINFO
|
||||
Pass a long set to 1 to enable libcurl's certificate chain info gatherer. With
|
||||
this enabled, libcurl (if built with OpenSSL) will extract lots of information
|
||||
and data about the certificates in the certificate chain used in the SSL
|
||||
connection. This data is then possible to extract after a transfer using
|
||||
\fIcurl_easy_getinfo(3)\fP and its option \fICURLINFO_CERTINFO\fP. (Added in
|
||||
7.19.1)
|
||||
.IP CURLOPT_RANDOM_FILE
|
||||
Pass a char * to a zero terminated file name. The file will be used to read
|
||||
from to seed the random engine for SSL. The more random the specified file is,
|
||||
the more secure the SSL connection will become.
|
||||
.IP CURLOPT_EGDSOCKET
|
||||
Pass a char * to the zero terminated path name to the Entropy Gathering Daemon
|
||||
socket. It will be used to seed the random engine for SSL.
|
||||
.IP CURLOPT_SSL_CIPHER_LIST
|
||||
Pass a char *, pointing to a zero terminated string holding the list of
|
||||
ciphers to use for the SSL connection. The list must be syntactically correct,
|
||||
|
@@ -283,6 +283,10 @@ yassl
|
||||
|
||||
Required actions unknown.
|
||||
|
||||
axTLS
|
||||
|
||||
Required actions unknown.
|
||||
|
||||
When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1
|
||||
for all handles. Everything will or might work fine except that timeouts are
|
||||
not honored during the DNS lookup - which you can work around by building
|
||||
|
@@ -484,6 +484,9 @@ CURLOPT_TIMECONDITION 7.1
|
||||
CURLOPT_TIMEOUT 7.1
|
||||
CURLOPT_TIMEOUT_MS 7.16.2
|
||||
CURLOPT_TIMEVALUE 7.1
|
||||
CURLOPT_TLSAUTH_PASSWORD 7.21.4
|
||||
CURLOPT_TLSAUTH_TYPE 7.21.4
|
||||
CURLOPT_TLSAUTH_USERNAME 7.21.4
|
||||
CURLOPT_TRANSFERTEXT 7.11.1
|
||||
CURLOPT_UNRESTRICTED_AUTH 7.10.4
|
||||
CURLOPT_UPLOAD 7.1
|
||||
@@ -650,6 +653,8 @@ CURL_TIMECOND_IFMODSINCE 7.9.7
|
||||
CURL_TIMECOND_IFUNMODSINCE 7.9.7
|
||||
CURL_TIMECOND_LASTMOD 7.9.7
|
||||
CURL_TIMECOND_NONE 7.9.7
|
||||
CURL_TLSAUTH_NONE 7.21.4
|
||||
CURL_TLSAUTH_SRP 7.21.4
|
||||
CURL_VERSION_ASYNCHDNS 7.10.7
|
||||
CURL_VERSION_CONV 7.15.4
|
||||
CURL_VERSION_CURLDEBUG 7.19.6
|
||||
@@ -664,4 +669,5 @@ CURL_VERSION_NTLM 7.10.6
|
||||
CURL_VERSION_SPNEGO 7.10.8
|
||||
CURL_VERSION_SSL 7.10
|
||||
CURL_VERSION_SSPI 7.13.2
|
||||
CURL_VERSION_TLSAUTH_SRP 7.21.4
|
||||
CURL_WRITEFUNC_PAUSE 7.18.0
|
||||
|
@@ -1442,6 +1442,15 @@ typedef enum {
|
||||
/* send linked-list of name:port:address sets */
|
||||
CINIT(RESOLVE, OBJECTPOINT, 203),
|
||||
|
||||
/* Set a username for authenticated TLS */
|
||||
CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204),
|
||||
|
||||
/* Set a password for authenticated TLS */
|
||||
CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205),
|
||||
|
||||
/* Set authentication type for authenticated TLS */
|
||||
CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@@ -1538,6 +1547,12 @@ enum {
|
||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||
};
|
||||
|
||||
enum CURL_TLSAUTH {
|
||||
CURL_TLSAUTH_NONE,
|
||||
CURL_TLSAUTH_SRP,
|
||||
CURL_TLSAUTH_LAST /* never use, keep last */
|
||||
};
|
||||
|
||||
/* symbols to use with CURLOPT_POSTREDIR.
|
||||
CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that
|
||||
CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */
|
||||
@@ -2043,6 +2058,7 @@ typedef struct {
|
||||
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
||||
#define CURL_VERSION_CONV (1<<12) /* character conversions supported */
|
||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
|
||||
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -216,14 +216,23 @@ typedef char
|
||||
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
|
||||
*/
|
||||
|
||||
#ifdef CURL_ISOCPP
|
||||
# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
|
||||
# define __CURL_OFF_T_C_HLPR2(x) x
|
||||
# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
|
||||
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
|
||||
#else
|
||||
# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix
|
||||
# ifdef CURL_ISOCPP
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
|
||||
# else
|
||||
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
|
||||
# endif
|
||||
# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
|
||||
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
|
||||
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
||||
#endif
|
||||
#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix)
|
||||
#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T)
|
||||
#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU)
|
||||
|
||||
/*
|
||||
* Get rid of macros private to this header file.
|
||||
|
@@ -30,13 +30,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.21.3-DEV"
|
||||
#define LIBCURL_VERSION "7.21.4-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 21
|
||||
#define LIBCURL_VERSION_PATCH 3
|
||||
#define LIBCURL_VERSION_PATCH 4
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -53,7 +53,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x071503
|
||||
#define LIBCURL_VERSION_NUM 0x071504
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@@ -94,7 +94,7 @@ LIBRTMP_ROOT = ..$(DS)..$(DS)rtmpdump-2.3
|
||||
!ifdef %openssl_root
|
||||
OPENSSL_ROOT = $(%openssl_root)
|
||||
!else
|
||||
OPENSSL_ROOT = ..$(DS)..$(DS)openssl-0.9.8q
|
||||
OPENSSL_ROOT = ..$(DS)..$(DS)openssl-0.9.8r
|
||||
!endif
|
||||
|
||||
!ifdef %ares_root
|
||||
|
@@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@@ -46,7 +46,7 @@ lib_LTLIBRARIES = libcurl.la
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
|
||||
# This might hold -Werror
|
||||
CFLAGS += @CURL_CFLAG_EXTRAS@
|
||||
libcurl_la_CFLAGS = $(CFLAGS) @CURL_CFLAG_EXTRAS@
|
||||
|
||||
# Specify our include paths here, and do it relative to $(top_srcdir) and
|
||||
# $(top_builddir), to ensure that these paths which belong to the library
|
||||
@@ -116,12 +116,23 @@ if MIMPURE
|
||||
MIMPURE = -mimpure-text
|
||||
endif
|
||||
|
||||
libcurl_la_LDFLAGS = $(UNDEF) $(VERSIONINFO) $(MIMPURE) $(LIBCURL_LIBS)
|
||||
LINKFLAGS=$(UNDEF) $(MIMPURE) $(LIBCURL_LIBS)
|
||||
|
||||
libcurl_la_LDFLAGS = $(LINKFLAGS) $(VERSIONINFO)
|
||||
|
||||
# as unit testing will compile and link everything an extra time, we only
|
||||
# do it if debug is enabled
|
||||
if CURLDEBUG
|
||||
noinst_LTLIBRARIES = libcurlu.la
|
||||
libcurlu_la_CFLAGS = -DUNITTESTS
|
||||
libcurlu_la_LDFLAGS = -static $(LINKFLAGS)
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS)
|
||||
|
||||
WIN32SOURCES = $(CSOURCES)
|
||||
WIN32HEADERS = $(HHEADERS) config-win32.h
|
||||
|
@@ -6,19 +6,28 @@
|
||||
#
|
||||
# 'BCCDIR' has to be set up to point to the base directory
|
||||
# of the compiler, i.e. SET BCCDIR = c:\Borland\BCC55
|
||||
# where c:\Borland\BCC55 is the compiler is installed
|
||||
#
|
||||
# Written by Jaepil Kim, pit@paradise.net.nz
|
||||
# Initially written by Jaepil Kim, pit@paradise.net.nz
|
||||
############################################################
|
||||
|
||||
!if "$(__MAKE__)" == ""
|
||||
!error __MAKE__ not defined. Use Borlands's MAKE to process this makefile.
|
||||
!endif
|
||||
|
||||
# Borland's $(MAKEDIR) expands to the path where make.exe is located,
|
||||
# use this feature to define BCCDIR when user has not defined BCCDIR.
|
||||
!ifndef BCCDIR
|
||||
BCCDIR = $(MAKEDIR)\..
|
||||
!endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
!ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.1
|
||||
ZLIB_PATH = ..\..\zlib-1.2.5
|
||||
!endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
!ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.7d
|
||||
OPENSSL_PATH = ..\..\openssl-0.9.8q
|
||||
!endif
|
||||
|
||||
# Set libcurl static lib, dll and import lib
|
||||
@@ -27,55 +36,78 @@ LIBCURL_DLL = libcurl.dll
|
||||
LIBCURL_IMPLIB = libcurl_imp.lib
|
||||
|
||||
# Setup environment
|
||||
CXX = bcc32
|
||||
PP_CMD = cpp32 -q -P-
|
||||
CC_CMD = bcc32 -q -c
|
||||
LD = bcc32
|
||||
CP = copy
|
||||
RM = del
|
||||
RM = del 2>NUL
|
||||
MKDIR = mkdir
|
||||
RMDIR = rmdir /s /q 2>NUL
|
||||
LIB = tlib
|
||||
IMPLIB = implib
|
||||
|
||||
CXXFLAGS = -q -5 -O2 -w-aus -w-ccc -w-csu -w-par -w-pia -w-rch -w-inl -w-ngu -w-pro -tWM
|
||||
CC_FLAGS = -5 -O2 -tWM -w -w-aus -w-ccc -w-dup -w-prc -w-pro -w-rch -w-sig -w-spa -Dinline=__inline
|
||||
LIBFLAGS = /C /P32
|
||||
LDFLAGS = -q -lq -laa -tWD
|
||||
|
||||
INCDIRS = -I.;../include
|
||||
LINKLIB = $(BCCDIR)/lib/cw32mt.lib
|
||||
SRCDIR = .
|
||||
OBJDIR = .\objs
|
||||
INCDIRS = -I.;..\include
|
||||
LINKLIB = $(BCCDIR)\lib\cw32mt.lib
|
||||
DEFINES = -DNDEBUG -DWIN32 -DBUILDING_LIBCURL
|
||||
|
||||
# If you build with SSL support, set WITH_SSL=1
|
||||
DEFINES = -DNDEBUG -DWIN32 -D_CONSOLE -D_MBCS -DBUILDING_LIBCURL
|
||||
# By default SSPI support is enabled for BCC
|
||||
!ifndef DISABLE_SSPI
|
||||
DEFINES = $(DEFINES) -DUSE_WINDOWS_SSPI
|
||||
!endif
|
||||
|
||||
# By default LDAP support is disabled for BCC
|
||||
!ifndef WITH_LDAP
|
||||
DEFINES = $(DEFINES) -DCURL_DISABLE_LDAP
|
||||
!endif
|
||||
|
||||
# ZLIB support is enabled setting WITH_ZLIB=1
|
||||
!ifdef WITH_ZLIB
|
||||
DEFINES = $(DEFINES) -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
INCDIRS = $(INCDIRS);$(ZLIB_PATH)
|
||||
LINKLIB = $(LINKLIB) $(ZLIB_PATH)/zlib.lib
|
||||
LINKLIB = $(LINKLIB) $(ZLIB_PATH)\zlib.lib
|
||||
!endif
|
||||
|
||||
# SSL support is enabled setting WITH_SSL=1
|
||||
!ifdef WITH_SSL
|
||||
DEFINES = $(DEFINES) -DUSE_SSLEAY
|
||||
INCDIRS = $(INCDIRS);$(OPENSSL_PATH)/inc32;$(OPENSSL_PATH)/inc32/openssl
|
||||
LINKLIB = $(LINKLIB) $(OPENSSL_PATH)/out32/ssleay32.lib $(OPENSSL_PATH)/out32/libeay32.lib
|
||||
INCDIRS = $(INCDIRS);$(OPENSSL_PATH)\inc32;$(OPENSSL_PATH)\inc32\openssl
|
||||
LINKLIB = $(LINKLIB) $(OPENSSL_PATH)\out32\ssleay32.lib $(OPENSSL_PATH)\out32\libeay32.lib
|
||||
!endif
|
||||
|
||||
.autodepend
|
||||
|
||||
.path.c = $(SRCDIR)
|
||||
.path.obj = $(OBJDIR)
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
!include Makefile.inc
|
||||
|
||||
OBJECTS = $(CSOURCES:.c=.obj)
|
||||
|
||||
.c.obj:
|
||||
$(CXX) -c $(INCDIRS) $(CXXFLAGS) $(DEFINES) $<
|
||||
@-$(RM) $(@R).int
|
||||
$(PP_CMD) $(CC_FLAGS) $(INCDIRS) $(DEFINES) -o$(@R).int $(<)
|
||||
$(CC_CMD) $(CC_FLAGS) -o$(@) $(@R).int
|
||||
|
||||
all: $(LIBCURL_LIB) $(LIBCURL_DLL)
|
||||
all: $(OBJDIR) $(LIBCURL_LIB) $(LIBCURL_DLL)
|
||||
|
||||
clean:
|
||||
-$(RM) $(LIBCURL_LIB)
|
||||
-$(RM) $(LIBCURL_IMPLIB)
|
||||
-$(RM) libcurl.tds
|
||||
-$(RM) *.obj
|
||||
@-$(RMDIR) $(OBJDIR)
|
||||
@-$(RM) $(LIBCURL_LIB)
|
||||
@-$(RM) $(LIBCURL_IMPLIB)
|
||||
@-$(RM) libcurl.tds
|
||||
|
||||
$(OBJDIR):
|
||||
@-$(RMDIR) $(OBJDIR)
|
||||
@-$(MKDIR) $(OBJDIR)
|
||||
|
||||
$(LIBCURL_LIB): $(OBJECTS)
|
||||
@-$(RM) $@
|
||||
@-$(RM) $(LIBCURL_LIB)
|
||||
$(LIB) $(LIBFLAGS) $@ @&&!
|
||||
+$(**: = &^
|
||||
+)
|
||||
@@ -87,3 +119,5 @@ $(LIBCURL_DLL) $(LIBCURL_IMPLIB): $(OBJECTS) $(LINKLIB)
|
||||
$(LD) $(LDFLAGS) -e$(LIBCURL_DLL) $**
|
||||
$(IMPLIB) $(LIBCURL_IMPLIB) $(LIBCURL_DLL)
|
||||
|
||||
|
||||
# End of Makefile.b32
|
||||
|
@@ -21,7 +21,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c \
|
||||
curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c \
|
||||
warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gethostname.c\
|
||||
gopher.c
|
||||
gopher.c axtls.c idn_win32.c http_negotiate_sspi.c
|
||||
|
||||
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
|
||||
@@ -36,5 +36,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
|
||||
curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h \
|
||||
curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h \
|
||||
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
|
||||
gopher.h
|
||||
gopher.h axtls.h
|
||||
|
||||
|
@@ -20,7 +20,7 @@ ZLIB_PATH = ../../zlib-1.2.5
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8q
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
|
@@ -19,7 +19,7 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8q
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
@@ -27,6 +27,11 @@ ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.2.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your axTLS package.
|
||||
ifndef AXTLS_PATH
|
||||
AXTLS_PATH = ../../axTLS-1.2.7
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your libidn package.
|
||||
ifndef LIBIDN_PATH
|
||||
LIBIDN_PATH = ../../libidn-1.18
|
||||
@@ -140,7 +145,11 @@ AR = ar
|
||||
ARFLAGS = -cq
|
||||
LIBEXT = a
|
||||
RANLIB = ranlib
|
||||
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fno-strict-aliasing
|
||||
ifeq ($(findstring gcc,$(CC)),gcc)
|
||||
CFLAGS += -fpcc-struct-return
|
||||
endif
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
ifeq ($(POSIXFL),1)
|
||||
@@ -195,6 +204,17 @@ ifdef WITH_SSL
|
||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||
IMPORTS += GetProcessSwitchCount RunningProcess
|
||||
INSTDEP += ca-bundle.crt
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
INCLUDES += -I$(AXTLS_PATH)/inc
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += $(AXTLS_PATH)/lib/libaxtls.$(LIBEXT)
|
||||
else
|
||||
MODULES += libaxtls.nlm
|
||||
IMPORTS += $(AXTLS_PATH)/lib/libaxtls.imp
|
||||
endif
|
||||
INSTDEP += ca-bundle.crt
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_ZLIB
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
@@ -563,6 +583,10 @@ ifdef WITH_SSL
|
||||
@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
else
|
||||
ifdef WITH_AXTLS
|
||||
@echo $(DL)#define USE_AXTLS 1$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
ifdef WITH_SSH2
|
||||
@echo $(DL)#define USE_LIBSSH2 1$(DL) >> $@
|
||||
|
193
lib/Makefile.vc6
193
lib/Makefile.vc6
@@ -18,6 +18,8 @@
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC6
|
||||
@@ -41,20 +43,27 @@
|
||||
#
|
||||
##############################################################
|
||||
|
||||
#
|
||||
# Stem for static libs and DLLs
|
||||
#
|
||||
LIB_NAME = libcurl
|
||||
LIB_NAME_DEBUG = libcurld
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\Makefile.msvc.names
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Stem for DLL import libs
|
||||
#
|
||||
IMPLIB_NAME = libcurl_imp
|
||||
IMPLIB_NAME_DEBUG = libcurld_imp
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8o
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
@@ -81,7 +90,7 @@ MACHINE = X86
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "C:\Program Files\Microsoft SDK"
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
@@ -129,42 +138,18 @@ RTLIBD = /MTd
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIB_NAME).dll
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
@@ -173,14 +158,14 @@ CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
@@ -188,7 +173,7 @@ CFGSET = TRUE
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
@@ -198,23 +183,22 @@ CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIB_NAME).dll
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
@@ -226,7 +210,7 @@ CFGSET = TRUE
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
@@ -235,14 +219,39 @@ CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -252,11 +261,11 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME).lib
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -266,7 +275,7 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
@@ -277,7 +286,7 @@ CFGSET = TRUE
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
@@ -289,7 +298,7 @@ CFGSET = TRUE
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
@@ -297,23 +306,11 @@ CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
@@ -322,11 +319,23 @@ CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
@@ -338,7 +347,7 @@ CFGSET = TRUE
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).lib
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
@@ -351,9 +360,9 @@ CFGSET = TRUE
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -363,10 +372,10 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -376,10 +385,10 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -389,11 +398,11 @@ RESOURCE = $(DIROBJ)\libcurl.res
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIB_NAME_DEBUG).dll
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).lib /PDB:$(DIROBJ)\$(IMPLIB_NAME_DEBUG).pdb
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
@@ -498,7 +507,7 @@ X_OBJS= \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
@@ -538,14 +547,14 @@ all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIB_NAME).dll . /y
|
||||
-xcopy $(DIROBJ)\$(LIB_NAME).lib . /y
|
||||
-xcopy $(DIROBJ)\$(LIB_NAME_DEBUG).dll . /y
|
||||
-xcopy $(DIROBJ)\$(LIB_NAME_DEBUG).lib . /y
|
||||
-xcopy $(DIROBJ)\$(IMPLIB_NAME).lib . /y
|
||||
-xcopy $(DIROBJ)\$(IMPLIB_NAME_DEBUG).lib . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
|
500
lib/axtls.c
Normal file
500
lib/axtls.c
Normal file
@@ -0,0 +1,500 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, DirecTV
|
||||
* contact: Eric Hu <ehu@directv.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Source file for all axTLS-specific code for the TLS/SSL layer. No code
|
||||
* but sslgen.c should ever call or use these functions.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#ifdef USE_AXTLS
|
||||
#include <axTLS/ssl.h>
|
||||
#include "axtls.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "sendf.h"
|
||||
#include "inet_pton.h"
|
||||
#include "sslgen.h"
|
||||
#include "parsedate.h"
|
||||
#include "connect.h" /* for the connect timeout */
|
||||
#include "select.h"
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* SSL_read is opied from axTLS compat layer */
|
||||
static int SSL_read(SSL *ssl, void *buf, int num)
|
||||
{
|
||||
uint8_t *read_buf;
|
||||
int ret;
|
||||
|
||||
while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
|
||||
|
||||
if(ret > SSL_OK){
|
||||
memcpy(buf, read_buf, ret > num ? num : ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Global axTLS init, called from Curl_ssl_init() */
|
||||
int Curl_axtls_init(void)
|
||||
{
|
||||
/* axTLS has no global init. Everything is done through SSL and SSL_CTX
|
||||
* structs stored in connectdata structure. Perhaps can move to axtls.h.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Curl_axtls_cleanup(void)
|
||||
{
|
||||
/* axTLS has no global cleanup. Perhaps can move this to axtls.h. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static CURLcode map_error_to_curl(int axtls_err)
|
||||
{
|
||||
switch (axtls_err)
|
||||
{
|
||||
case SSL_ERROR_NOT_SUPPORTED:
|
||||
case SSL_ERROR_INVALID_VERSION:
|
||||
case -70: /* protocol version alert from server */
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
break;
|
||||
case SSL_ERROR_NO_CIPHER:
|
||||
return CURLE_SSL_CIPHER;
|
||||
break;
|
||||
case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
|
||||
case SSL_ERROR_NO_CERT_DEFINED:
|
||||
case -42: /* bad certificate alert from server */
|
||||
case -43: /* unsupported cert alert from server */
|
||||
case -44: /* cert revoked alert from server */
|
||||
case -45: /* cert expired alert from server */
|
||||
case -46: /* cert unknown alert from server */
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
break;
|
||||
case SSL_X509_ERROR(X509_NOT_OK):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
|
||||
case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
|
||||
case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
break;
|
||||
case -48: /* unknown ca alert from server */
|
||||
return CURLE_SSL_CACERT;
|
||||
break;
|
||||
case -49: /* access denied alert from server */
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
break;
|
||||
case SSL_ERROR_CONN_LOST:
|
||||
case SSL_ERROR_SOCK_SETUP_FAILURE:
|
||||
case SSL_ERROR_INVALID_HANDSHAKE:
|
||||
case SSL_ERROR_INVALID_PROT_MSG:
|
||||
case SSL_ERROR_INVALID_HMAC:
|
||||
case SSL_ERROR_INVALID_SESSION:
|
||||
case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
|
||||
case SSL_ERROR_FINISHED_INVALID:
|
||||
case SSL_ERROR_NO_CLIENT_RENOG:
|
||||
default:
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Curl_recv axtls_recv;
|
||||
static Curl_send axtls_send;
|
||||
|
||||
/*
|
||||
* This function is called after the TCP connect has completed. Setup the TLS
|
||||
* layer and do all necessary magic.
|
||||
*/
|
||||
CURLcode
|
||||
Curl_axtls_connect(struct connectdata *conn,
|
||||
int sockindex)
|
||||
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl;
|
||||
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
|
||||
int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
|
||||
int i, ssl_fcn_return;
|
||||
const uint8_t *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
const char *x509;
|
||||
|
||||
/* Assuming users will not compile in custom key/cert to axTLS */
|
||||
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
|
||||
|
||||
if(conn->ssl[sockindex].state == ssl_connection_complete)
|
||||
/* to make us tolerant against being called more than once for the
|
||||
same connection */
|
||||
return CURLE_OK;
|
||||
|
||||
/* axTLS only supports TLSv1 */
|
||||
/* check to see if we've been told to use an explicit SSL/TLS version */
|
||||
switch(data->set.ssl.version) {
|
||||
case CURL_SSLVERSION_DEFAULT:
|
||||
case CURL_SSLVERSION_TLSv1:
|
||||
break;
|
||||
default:
|
||||
failf(data, "axTLS only supports TLSv1");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#ifdef AXTLSDEBUG
|
||||
client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
|
||||
#endif /* AXTLSDEBUG */
|
||||
|
||||
/* Allocate an SSL_CTX struct */
|
||||
ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
|
||||
if(ssl_ctx == NULL) {
|
||||
failf(data, "unable to create client SSL context");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
/* Load the trusted CA cert bundle file */
|
||||
if(data->set.ssl.CAfile) {
|
||||
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL)
|
||||
!= SSL_OK){
|
||||
infof(data, "error reading ca cert file %s \n",
|
||||
data->set.ssl.CAfile);
|
||||
if(data->set.ssl.verifypeer){
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
}
|
||||
}
|
||||
else
|
||||
infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
|
||||
}
|
||||
|
||||
/* gtls.c tasks we're skipping for now:
|
||||
* 1) certificate revocation list checking
|
||||
* 2) dns name assignment to host
|
||||
* 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
|
||||
* 4) set certificate priority. axTLS ignores type and sends certs in
|
||||
* order added. can probably ignore this.
|
||||
*/
|
||||
|
||||
/* Load client certificate */
|
||||
if(data->set.str[STRING_CERT]){
|
||||
i=0;
|
||||
/* Instead of trying to analyze cert type here, let axTLS try them all. */
|
||||
while(cert_types[i] != 0){
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
|
||||
data->set.str[STRING_CERT], NULL);
|
||||
if(ssl_fcn_return == SSL_OK){
|
||||
infof(data, "successfully read cert file %s \n",
|
||||
data->set.str[STRING_CERT]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* Tried all cert types, none worked. */
|
||||
if(cert_types[i] == 0){
|
||||
failf(data, "%s is not x509 or pkcs12 format",
|
||||
data->set.str[STRING_CERT]);
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load client key.
|
||||
If a pkcs12 file successfully loaded a cert, then there's nothing to do
|
||||
because the key has already been loaded. */
|
||||
if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12){
|
||||
i=0;
|
||||
/* Instead of trying to analyze key type here, let axTLS try them all. */
|
||||
while(key_types[i] != 0){
|
||||
ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
|
||||
data->set.str[STRING_KEY], NULL);
|
||||
if(ssl_fcn_return == SSL_OK){
|
||||
infof(data, "successfully read key file %s \n",
|
||||
data->set.str[STRING_KEY]);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* Tried all key types, none worked. */
|
||||
if(key_types[i] == 0){
|
||||
failf(data, "Failure: %s is not a supported key file",
|
||||
data->set.str[STRING_KEY]);
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* gtls.c does more here that is being left out for now
|
||||
* 1) set session credentials. can probably ignore since axtls puts this
|
||||
* info in the ssl_ctx struct
|
||||
* 2) setting up callbacks. these seem gnutls specific
|
||||
*/
|
||||
|
||||
/* In axTLS, handshaking happens inside ssl_client_new. */
|
||||
if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) {
|
||||
/* we got a session id, use it! */
|
||||
infof (data, "SSL re-using session ID\n");
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
|
||||
ssl_sessionid, (uint8_t)ssl_idsize);
|
||||
}
|
||||
else
|
||||
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
|
||||
|
||||
/* Check to make sure handshake was ok. */
|
||||
ssl_fcn_return = ssl_handshake_status(ssl);
|
||||
if(ssl_fcn_return != SSL_OK){
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
|
||||
return map_error_to_curl(ssl_fcn_return);
|
||||
}
|
||||
infof (data, "handshake completed successfully\n");
|
||||
|
||||
/* Here, gtls.c gets the peer certificates and fails out depending on
|
||||
* settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
|
||||
*/
|
||||
|
||||
/* Verify server's certificate */
|
||||
if(data->set.ssl.verifypeer){
|
||||
if(ssl_verify_cert(ssl) != SSL_OK){
|
||||
Curl_axtls_close(conn, sockindex);
|
||||
failf(data, "server cert verify failed");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
infof(data, "\t server certificate verification SKIPPED\n");
|
||||
|
||||
/* Here, gtls.c does issuer verfication. axTLS has no straightforward
|
||||
* equivalent, so omitting for now.*/
|
||||
|
||||
/* See if common name was set in server certificate */
|
||||
x509 = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
|
||||
if(x509 == NULL)
|
||||
infof(data, "error fetching CN from cert\n");
|
||||
|
||||
/* Here, gtls.c does the following
|
||||
* 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
|
||||
* it seems useful. Omitting for now.
|
||||
* 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
|
||||
* 3) displays a bunch of cert information. axTLS doesn't support most of
|
||||
* this, but a couple fields are available.
|
||||
*/
|
||||
|
||||
/* General housekeeping */
|
||||
conn->ssl[sockindex].state = ssl_connection_complete;
|
||||
conn->ssl[sockindex].ssl = ssl;
|
||||
conn->ssl[sockindex].ssl_ctx = ssl_ctx;
|
||||
conn->recv[sockindex] = axtls_recv;
|
||||
conn->send[sockindex] = axtls_send;
|
||||
|
||||
/* Put our freshly minted SSL session in cache */
|
||||
ssl_idsize = ssl_get_session_id_size(ssl);
|
||||
ssl_sessionid = ssl_get_session_id(ssl);
|
||||
if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize)
|
||||
!= CURLE_OK)
|
||||
infof (data, "failed to add session to cache\n");
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* return number of sent (non-SSL) bytes */
|
||||
static ssize_t axtls_send(struct connectdata *conn,
|
||||
int sockindex,
|
||||
const void *mem,
|
||||
size_t len,
|
||||
CURLcode *err)
|
||||
{
|
||||
/* ssl_write() returns 'int' while write() and send() returns 'size_t' */
|
||||
int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
|
||||
|
||||
infof(conn->data, " axtls_send\n");
|
||||
|
||||
if(rc < 0 ) {
|
||||
*err = map_error_to_curl(rc);
|
||||
rc = -1; /* generic error code for send failure */
|
||||
}
|
||||
|
||||
*err = CURLE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Curl_axtls_close_all(struct SessionHandle *data)
|
||||
{
|
||||
(void)data;
|
||||
infof(data, " Curl_axtls_close_all\n");
|
||||
}
|
||||
|
||||
void Curl_axtls_close(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
|
||||
infof(conn->data, " Curl_axtls_close\n");
|
||||
if(connssl->ssl) {
|
||||
/* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
|
||||
axTLS compat layer does nothing for SSL_shutdown */
|
||||
|
||||
/* The following line is from ssluse.c. There seems to be no axTLS
|
||||
equivalent. ssl_free and ssl_ctx_free close things.
|
||||
SSL_set_connect_state(connssl->handle); */
|
||||
|
||||
ssl_free (connssl->ssl);
|
||||
connssl->ssl = NULL;
|
||||
}
|
||||
if(connssl->ssl_ctx) {
|
||||
ssl_ctx_free (connssl->ssl_ctx);
|
||||
connssl->ssl_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called to shut down the SSL layer but keep the
|
||||
* socket open (CCC - Clear Command Channel)
|
||||
*/
|
||||
int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
/* Outline taken from ssluse.c since functions are in axTLS compat layer.
|
||||
axTLS's error set is much smaller, so a lot of error-handling was removed.
|
||||
*/
|
||||
int retval = 0;
|
||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||
struct SessionHandle *data = conn->data;
|
||||
char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
|
||||
to be at least 120 bytes long. */
|
||||
ssize_t nread;
|
||||
|
||||
infof(conn->data, " Curl_axtls_shutdown\n");
|
||||
|
||||
/* This has only been tested on the proftpd server, and the mod_tls code
|
||||
sends a close notify alert without waiting for a close notify alert in
|
||||
response. Thus we wait for a close notify alert from the server, but
|
||||
we do not send one. Let's hope other servers do the same... */
|
||||
|
||||
/* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
|
||||
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
|
||||
(void)SSL_shutdown(connssl->ssl);
|
||||
*/
|
||||
|
||||
if(connssl->ssl) {
|
||||
int what = Curl_socket_ready(conn->sock[sockindex],
|
||||
CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
|
||||
if(what > 0) {
|
||||
/* Something to read, let's do it and hope that it is the close
|
||||
notify alert from the server */
|
||||
nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
|
||||
sizeof(buf));
|
||||
|
||||
if (nread < SSL_OK){
|
||||
failf(data, "close notify alert not received during shutdown");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
else if(0 == what) {
|
||||
/* timeout */
|
||||
failf(data, "SSL shutdown timeout");
|
||||
}
|
||||
else {
|
||||
/* anything that gets here is fatally bad */
|
||||
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
ssl_free (connssl->ssl);
|
||||
connssl->ssl = NULL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
|
||||
int num, /* socketindex */
|
||||
char *buf, /* store read data here */
|
||||
size_t buffersize, /* max amount to read */
|
||||
CURLcode *err)
|
||||
{
|
||||
struct ssl_connect_data *connssl = &conn->ssl[num];
|
||||
ssize_t ret = 0;
|
||||
|
||||
infof(conn->data, " axtls_recv\n");
|
||||
|
||||
if(connssl){
|
||||
ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf, (int)buffersize);
|
||||
|
||||
/* axTLS isn't terribly generous about error reporting */
|
||||
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
|
||||
team approves proposed fix. */
|
||||
if(ret == -3 ){
|
||||
Curl_axtls_close(conn, num);
|
||||
}
|
||||
else if(ret < 0) {
|
||||
failf(conn->data, "axTLS recv error (%d)", (int)ret);
|
||||
*err = map_error_to_curl(ret);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*err = CURLE_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return codes:
|
||||
* 1 means the connection is still in place
|
||||
* 0 means the connection has been closed
|
||||
* -1 means the connection status is unknown
|
||||
*/
|
||||
int Curl_axtls_check_cxn(struct connectdata *conn)
|
||||
{
|
||||
/* ssluse.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
|
||||
axTLS compat layer always returns the last argument, so connection is
|
||||
always alive? */
|
||||
|
||||
infof(conn->data, " Curl_axtls_check_cxn\n");
|
||||
return 1; /* connection still in place */
|
||||
}
|
||||
|
||||
void Curl_axtls_session_free(void *ptr)
|
||||
{
|
||||
(void)ptr;
|
||||
/* free the ID */
|
||||
/* both ssluse.c and gtls.c do something here, but axTLS's OpenSSL
|
||||
compatibility layer does nothing, so we do nothing too. */
|
||||
}
|
||||
|
||||
size_t Curl_axtls_version(char *buffer, size_t size)
|
||||
{
|
||||
return snprintf(buffer, size, "axTLS/%s", ssl_version());
|
||||
}
|
||||
|
||||
#endif /* USE_AXTLS */
|
62
lib/axtls.h
Normal file
62
lib/axtls.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef __AXTLS_H
|
||||
#define __AXTLS_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, DirecTV
|
||||
* contact: Eric Hu <ehu@directv.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_AXTLS
|
||||
#include "curl/curl.h"
|
||||
#include "urldata.h"
|
||||
|
||||
int Curl_axtls_init(void);
|
||||
int Curl_axtls_cleanup(void);
|
||||
CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex);
|
||||
|
||||
/* tell axTLS to close down all open information regarding connections (and
|
||||
thus session ID caching etc) */
|
||||
void Curl_axtls_close_all(struct SessionHandle *data);
|
||||
|
||||
/* close a SSL connection */
|
||||
void Curl_axtls_close(struct connectdata *conn, int sockindex);
|
||||
|
||||
void Curl_axtls_session_free(void *ptr);
|
||||
size_t Curl_axtls_version(char *buffer, size_t size);
|
||||
int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
|
||||
int Curl_axtls_check_cxn(struct connectdata *conn);
|
||||
|
||||
/* API setup for axTLS */
|
||||
#define curlssl_init Curl_axtls_init
|
||||
#define curlssl_cleanup Curl_axtls_cleanup
|
||||
#define curlssl_connect Curl_axtls_connect
|
||||
#define curlssl_session_free(x) Curl_axtls_session_free(x)
|
||||
#define curlssl_close_all Curl_axtls_close_all
|
||||
#define curlssl_close Curl_axtls_close
|
||||
#define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y)
|
||||
#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_FAILED_INIT)
|
||||
#define curlssl_set_engine_default(x) (x=x, CURLE_FAILED_INIT)
|
||||
#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
|
||||
#define curlssl_version Curl_axtls_version
|
||||
#define curlssl_check_cxn(x) Curl_axtls_check_cxn(x)
|
||||
#define curlssl_data_pending(x,y) (x=x, y=y, 0)
|
||||
|
||||
#endif /* USE_AXTLS */
|
||||
#endif
|
@@ -357,7 +357,7 @@
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/* Define this if you have struct sockaddr_storage */
|
||||
#ifndef __SALFORDC__
|
||||
#if !defined(__SALFORDC__) && !defined(__BORLANDC__)
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
#endif
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -124,15 +124,17 @@ singleipconnect(struct connectdata *conn,
|
||||
* transfer/connection. If the value is negative, the timeout time has already
|
||||
* elapsed.
|
||||
*
|
||||
* The start time is stored in progress.t_startsingle - as set with
|
||||
* Curl_pgrsTime(..., TIMER_STARTSINGLE);
|
||||
*
|
||||
* If 'nowp' is non-NULL, it points to the current time.
|
||||
* 'duringconnect' is FALSE if not during a connect, as then of course the
|
||||
* connect timeout is not taken into account!
|
||||
*/
|
||||
long Curl_timeleft(struct connectdata *conn,
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
struct timeval *nowp,
|
||||
bool duringconnect)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
int timeout_set = 0;
|
||||
long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
|
||||
struct timeval now;
|
||||
@@ -658,6 +660,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
curl_socket_t sockfd = conn->sock[sockindex];
|
||||
long allow = DEFAULT_CONNECT_TIMEOUT;
|
||||
int error = 0;
|
||||
struct timeval now;
|
||||
|
||||
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||
|
||||
@@ -669,8 +672,10 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
now = Curl_tvnow();
|
||||
|
||||
/* figure out how long time we have left to connect */
|
||||
allow = Curl_timeleft(conn, NULL, TRUE);
|
||||
allow = Curl_timeleft(data, &now, TRUE);
|
||||
|
||||
if(allow < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
@@ -680,9 +685,16 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
|
||||
/* check for connect without timeout as we want to return immediately */
|
||||
rc = waitconnect(conn, sockfd, 0);
|
||||
if(WAITCONN_TIMEOUT == rc)
|
||||
if(WAITCONN_TIMEOUT == rc) {
|
||||
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
||||
infof(data, "After %ldms connect time, move on!\n",
|
||||
conn->timeoutms_per_addr);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* not an error, but also no connection yet */
|
||||
return code;
|
||||
}
|
||||
|
||||
if(WAITCONN_CONNECTED == rc) {
|
||||
if(verifyconnect(sockfd, &error)) {
|
||||
@@ -715,6 +727,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
data->state.os_errno = error;
|
||||
SET_SOCKERRNO(error);
|
||||
}
|
||||
next:
|
||||
|
||||
code = trynextip(conn, sockindex, connected);
|
||||
|
||||
@@ -844,7 +857,7 @@ singleipconnect(struct connectdata *conn,
|
||||
|
||||
addr.family = ai->ai_family;
|
||||
addr.socktype = conn->socktype;
|
||||
addr.protocol = ai->ai_protocol;
|
||||
addr.protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
|
||||
addr.addrlen = ai->ai_addrlen;
|
||||
|
||||
if(addr.addrlen > sizeof(struct Curl_sockaddr_storage))
|
||||
@@ -913,7 +926,7 @@ singleipconnect(struct connectdata *conn,
|
||||
CURLSOCKTYPE_IPCXN);
|
||||
if(error) {
|
||||
sclose(sockfd); /* close the socket and bail out */
|
||||
return res;
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,8 +941,12 @@ singleipconnect(struct connectdata *conn,
|
||||
curlx_nonblock(sockfd, TRUE);
|
||||
|
||||
/* Connect TCP sockets, bind UDP */
|
||||
if(conn->socktype == SOCK_STREAM)
|
||||
if(conn->socktype == SOCK_STREAM) {
|
||||
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
|
||||
conn->connecttime = Curl_tvnow();
|
||||
if(conn->num_addr > 1)
|
||||
Curl_expire(data, conn->timeoutms_per_addr);
|
||||
}
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
@@ -1010,7 +1027,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd = CURL_SOCKET_BAD;
|
||||
int aliasindex;
|
||||
int num_addr;
|
||||
Curl_addrinfo *ai;
|
||||
Curl_addrinfo *curr_addr;
|
||||
|
||||
@@ -1021,13 +1037,12 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
* Figure out what maximum time we have left
|
||||
*************************************************************/
|
||||
long timeout_ms;
|
||||
long timeout_per_addr;
|
||||
|
||||
DEBUGASSERT(sockconn);
|
||||
*connected = FALSE; /* default to not connected */
|
||||
|
||||
/* get the timeout left */
|
||||
timeout_ms = Curl_timeleft(conn, &before, TRUE);
|
||||
timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* a precaution, no need to continue if time already is up */
|
||||
@@ -1036,8 +1051,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
|
||||
/* Max time for each address */
|
||||
num_addr = Curl_num_addresses(remotehost->addr);
|
||||
timeout_per_addr = timeout_ms / num_addr;
|
||||
conn->num_addr = Curl_num_addresses(remotehost->addr);
|
||||
conn->timeoutms_per_addr = timeout_ms / conn->num_addr;
|
||||
|
||||
ai = remotehost->addr;
|
||||
|
||||
@@ -1045,10 +1060,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
* know for the given host. One by one until one IP succeeds.
|
||||
*/
|
||||
|
||||
if(data->state.used_interface == Curl_if_multi)
|
||||
/* don't hang when doing multi */
|
||||
timeout_per_addr = 0;
|
||||
|
||||
/*
|
||||
* Connecting with a Curl_addrinfo chain
|
||||
*/
|
||||
@@ -1057,7 +1068,10 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
|
||||
/* start connecting to the IP curr_addr points to */
|
||||
CURLcode res =
|
||||
singleipconnect(conn, curr_addr, timeout_per_addr, &sockfd, connected);
|
||||
singleipconnect(conn, curr_addr,
|
||||
/* don't hang when doing multi */
|
||||
(data->state.used_interface == Curl_if_multi)?0:
|
||||
conn->timeoutms_per_addr, &sockfd, connected);
|
||||
|
||||
if(res)
|
||||
return res;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -37,7 +37,7 @@ CURLcode Curl_connecthost(struct connectdata *conn,
|
||||
|
||||
/* generic function that returns how much time there's left to run, according
|
||||
to the timeouts set */
|
||||
long Curl_timeleft(struct connectdata *conn,
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
struct timeval *nowp,
|
||||
bool duringconnect);
|
||||
|
||||
|
12
lib/cookie.c
12
lib/cookie.c
@@ -270,6 +270,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
we don't care about that, we treat the names the same anyway */
|
||||
|
||||
const char *domptr=whatptr;
|
||||
const char *nextptr;
|
||||
int dotcount=1;
|
||||
|
||||
/* Count the dots, we need to make sure that there are enough
|
||||
@@ -280,12 +281,13 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
domptr++;
|
||||
|
||||
do {
|
||||
domptr = strchr(domptr, '.');
|
||||
if(domptr) {
|
||||
domptr++;
|
||||
dotcount++;
|
||||
nextptr = strchr(domptr, '.');
|
||||
if(nextptr) {
|
||||
if(domptr != nextptr)
|
||||
dotcount++;
|
||||
domptr = nextptr+1;
|
||||
}
|
||||
} while(domptr);
|
||||
} while(nextptr);
|
||||
|
||||
/* The original Netscape cookie spec defined that this domain name
|
||||
MUST have three dots (or two if one of the seven holy TLDs),
|
||||
|
@@ -89,7 +89,7 @@
|
||||
|
||||
#ifdef ENABLE_CURLX_PRINTF
|
||||
/* If this define is set, we define all "standard" printf() functions to use
|
||||
the curlx_* version instead. It makes the source code transparant and
|
||||
the curlx_* version instead. It makes the source code transparent and
|
||||
easier to understand/patch. Undefine them first in case _MPRINTF_REPLACE
|
||||
is set. */
|
||||
# undef printf
|
||||
|
20
lib/file.c
20
lib/file.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -463,6 +463,13 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
fstated = TRUE;
|
||||
}
|
||||
|
||||
if(fstated && !data->state.range && data->set.timecondition) {
|
||||
if(!Curl_meets_timecondition(data, data->info.filetime)) {
|
||||
*done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have selected NOBODY and HEADER, it means that we only want file
|
||||
information. Which for FILE can't be much more than the file size and
|
||||
date. */
|
||||
@@ -480,14 +487,13 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
if(fstated) {
|
||||
const struct tm *tm;
|
||||
time_t filetime = (time_t)statbuf.st_mtime;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
struct tm buffer;
|
||||
tm = (const struct tm *)gmtime_r(&filetime, &buffer);
|
||||
#else
|
||||
tm = gmtime(&filetime);
|
||||
#endif
|
||||
const struct tm *tm = &buffer;
|
||||
result = Curl_gmtime(filetime, &buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
snprintf(buf, BUFSIZE-1,
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
|
16
lib/ftp.c
16
lib/ftp.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -322,7 +322,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn)
|
||||
curl_socklen_t size = (curl_socklen_t) sizeof(add);
|
||||
|
||||
for(;;) {
|
||||
timeout_ms = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* if a timeout was already reached, bail out */
|
||||
@@ -1841,14 +1841,14 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||
ftpc->file &&
|
||||
data->set.get_filetime &&
|
||||
(data->info.filetime>=0) ) {
|
||||
struct tm *tm;
|
||||
time_t filetime = (time_t)data->info.filetime;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
struct tm buffer;
|
||||
tm = (struct tm *)gmtime_r(&filetime, &buffer);
|
||||
#else
|
||||
tm = gmtime(&filetime);
|
||||
#endif
|
||||
const struct tm *tm = &buffer;
|
||||
|
||||
result = Curl_gmtime(filetime, &buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26" */
|
||||
snprintf(buf, BUFSIZE-1,
|
||||
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||||
|
@@ -447,9 +447,10 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
else if(c == '\n') {
|
||||
finfo->b_data[parser->item_length - 1] = 0;
|
||||
if(strncmp("total ", finfo->b_data, 6) == 0) {
|
||||
char *endptr = NULL;
|
||||
char *endptr = finfo->b_data+6;
|
||||
/* here we can deal with directory size */
|
||||
curlx_strtoofft(finfo->b_data+6, &endptr, 10);
|
||||
while(ISSPACE(*endptr))
|
||||
endptr++;
|
||||
if(*endptr != 0) {
|
||||
PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST);
|
||||
return bufflen;
|
||||
|
97
lib/gtls.c
97
lib/gtls.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -170,13 +170,12 @@ static void showtime(struct SessionHandle *data,
|
||||
const char *text,
|
||||
time_t stamp)
|
||||
{
|
||||
struct tm *tm;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
struct tm buffer;
|
||||
tm = (struct tm *)gmtime_r(&stamp, &buffer);
|
||||
#else
|
||||
tm = gmtime(&stamp);
|
||||
#endif
|
||||
const struct tm *tm = &buffer;
|
||||
CURLcode result = Curl_gmtime(stamp, &buffer);
|
||||
if(result)
|
||||
return;
|
||||
|
||||
snprintf(data->state.buffer,
|
||||
BUFSIZE,
|
||||
"\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT\n",
|
||||
@@ -238,7 +237,7 @@ static CURLcode handshake(struct connectdata *conn,
|
||||
|
||||
for(;;) {
|
||||
/* check allowed time left */
|
||||
timeout_ms = Curl_timeleft(conn, NULL, duringconnect);
|
||||
timeout_ms = Curl_timeleft(data, NULL, duringconnect);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* no need to continue if time already is up */
|
||||
@@ -346,6 +345,29 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username);
|
||||
|
||||
rc = gnutls_srp_allocate_client_credentials(
|
||||
&conn->ssl[sockindex].srp_client_cred);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
|
||||
gnutls_strerror(rc));
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].srp_client_cred,
|
||||
data->set.ssl.username,
|
||||
data->set.ssl.password);
|
||||
if(rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_srp_set_client_cred() failed: %s",
|
||||
gnutls_strerror(rc));
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(data->set.ssl.CAfile) {
|
||||
/* set the trusted CA cert bundle file */
|
||||
gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
|
||||
@@ -431,9 +453,18 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
/* put the credentials to the current session */
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||
conn->ssl[sockindex].cred);
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) {
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
|
||||
conn->ssl[sockindex].srp_client_cred);
|
||||
if (rc != GNUTLS_E_SUCCESS) {
|
||||
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
|
||||
conn->ssl[sockindex].cred);
|
||||
|
||||
/* set the connection handle (file descriptor for the socket) */
|
||||
gnutls_transport_set_ptr(session,
|
||||
@@ -483,6 +514,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
int rc;
|
||||
int incache;
|
||||
void *ssl_sessionid;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* This function will return the peer's raw certificate (chain) as sent by
|
||||
the peer. These certificates are in raw format (DER encoded for
|
||||
@@ -495,8 +527,21 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
if(data->set.ssl.verifypeer ||
|
||||
data->set.ssl.verifyhost ||
|
||||
data->set.ssl.issuercert) {
|
||||
failf(data, "failed to get server cert");
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
#ifdef USE_TLS_SRP
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
|
||||
&& data->set.ssl.username != NULL
|
||||
&& !data->set.ssl.verifypeer
|
||||
&& gnutls_cipher_get(session)) {
|
||||
/* no peer cert, but auth is ok if we have SRP user and cipher and no
|
||||
peer verify */
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
failf(data, "failed to get server cert");
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
#ifdef USE_TLS_SRP
|
||||
}
|
||||
#endif
|
||||
}
|
||||
infof(data, "\t common name: WARNING couldn't obtain\n");
|
||||
}
|
||||
@@ -529,8 +574,10 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
else
|
||||
infof(data, "\t server certificate verification OK\n");
|
||||
}
|
||||
else
|
||||
else {
|
||||
infof(data, "\t server certificate verification SKIPPED\n");
|
||||
goto after_server_cert_verification;
|
||||
}
|
||||
|
||||
/* initialize an X.509 certificate structure. */
|
||||
gnutls_x509_crt_init(&x509_cert);
|
||||
@@ -660,6 +707,8 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
|
||||
gnutls_x509_crt_deinit(x509_cert);
|
||||
|
||||
after_server_cert_verification:
|
||||
|
||||
/* compression algorithm (if any) */
|
||||
ptr = gnutls_compression_get_name(gnutls_compression_get(session));
|
||||
/* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
|
||||
@@ -701,11 +750,17 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* store this session id */
|
||||
return Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
|
||||
result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize);
|
||||
if(result) {
|
||||
free(connect_sessionid);
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -813,6 +868,12 @@ static void close_one(struct connectdata *conn,
|
||||
gnutls_certificate_free_credentials(conn->ssl[idx].cred);
|
||||
conn->ssl[idx].cred = NULL;
|
||||
}
|
||||
#ifdef USE_TLS_SRP
|
||||
if (conn->ssl[idx].srp_client_cred) {
|
||||
gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred);
|
||||
conn->ssl[idx].srp_client_cred = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Curl_gtls_close(struct connectdata *conn, int sockindex)
|
||||
@@ -882,6 +943,12 @@ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
|
||||
|
||||
#ifdef USE_TLS_SRP
|
||||
if(data->set.ssl.authtype == CURL_TLSAUTH_SRP
|
||||
&& data->set.ssl.username != NULL)
|
||||
gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
|
||||
#endif
|
||||
|
||||
conn->ssl[sockindex].cred = NULL;
|
||||
conn->ssl[sockindex].session = NULL;
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -224,7 +224,7 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn,
|
||||
long timeout;
|
||||
struct timeval now = Curl_tvnow();
|
||||
|
||||
timeout = Curl_timeleft(conn, &now, TRUE);
|
||||
timeout = Curl_timeleft(data, &now, TRUE);
|
||||
if(!timeout)
|
||||
timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
|
||||
|
||||
@@ -332,8 +332,17 @@ static void ares_query_completed_cb(void *arg, /* (struct connectdata *) */
|
||||
(void)timeouts; /* ignored */
|
||||
#endif
|
||||
|
||||
if (status == CURL_ASYNC_SUCCESS) {
|
||||
switch(status) {
|
||||
case CURL_ASYNC_SUCCESS:
|
||||
ai = Curl_he2ai(hostent, conn->async.port);
|
||||
break;
|
||||
case ARES_EDESTRUCTION:
|
||||
/* this ares handle is getting destroyed, the 'arg' pointer may not be
|
||||
valid! */
|
||||
return;
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
(void)Curl_addrinfo_callback(arg, status, ai);
|
||||
@@ -398,13 +407,30 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
Curl_safefree(conn->async.hostname);
|
||||
conn->async.hostname = bufp;
|
||||
conn->async.port = port;
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
conn->async.done = FALSE; /* not done */
|
||||
conn->async.status = 0; /* clear */
|
||||
conn->async.dns = NULL; /* clear */
|
||||
conn->async.temp_ai = NULL; /* clear */
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||
(ares_host_callback)ares_query_completed_cb, conn);
|
||||
#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
|
||||
if(family == PF_UNSPEC) {
|
||||
conn->async.num_pending = 2;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET,
|
||||
ares_query_completed_cb, conn);
|
||||
ares_gethostbyname(data->state.areschannel, hostname, PF_INET6,
|
||||
ares_query_completed_cb, conn);
|
||||
}
|
||||
else
|
||||
#endif /* CURLRES_IPV6 */
|
||||
{
|
||||
conn->async.num_pending = 1;
|
||||
|
||||
/* areschannel is already setup in the Curl_open() function */
|
||||
ares_gethostbyname(data->state.areschannel, hostname, family,
|
||||
ares_query_completed_cb, conn);
|
||||
}
|
||||
|
||||
*waitp = 1; /* expect asynchronous response */
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -72,6 +72,20 @@
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_ASYNCH
|
||||
|
||||
/*
|
||||
* Cancel all possibly still on-going resolves for this connection.
|
||||
*/
|
||||
void Curl_async_cancel(struct connectdata *conn)
|
||||
{
|
||||
/* If we have a "half" response already received, we first clear that off
|
||||
so that nothing is tempted to use it */
|
||||
if(conn->async.temp_ai) {
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
|
||||
* or getaddrinfo_thread() when we got the name resolved (or not!).
|
||||
@@ -82,7 +96,7 @@
|
||||
*
|
||||
* The storage operation locks and unlocks the DNS cache.
|
||||
*/
|
||||
CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
||||
CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
int status,
|
||||
struct Curl_addrinfo *ai)
|
||||
{
|
||||
@@ -95,6 +109,24 @@ CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
||||
if(ai) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
Curl_addrinfo *ai_tail = ai;
|
||||
|
||||
while (ai_tail->ai_next)
|
||||
ai_tail = ai_tail->ai_next;
|
||||
|
||||
/* Add the new results to the list of old results. */
|
||||
ai_tail->ai_next = conn->async.temp_ai;
|
||||
conn->async.temp_ai = ai;
|
||||
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
|
||||
/* make sure the temp pointer is cleared and isn't pointing to something
|
||||
we take care of below */
|
||||
conn->async.temp_ai = NULL;
|
||||
#endif
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
@@ -110,9 +142,53 @@ CURLcode Curl_addrinfo_callback(struct connectdata * conn,
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
else
|
||||
else {
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
if(--conn->async.num_pending > 0) {
|
||||
/* We are not done yet. Clean up and return.
|
||||
This function will be called again. */
|
||||
if(conn->async.temp_ai) {
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
#if defined(ENABLE_IPV6) && defined(CURLRES_ARES) /* CURLRES_IPV6 */
|
||||
else
|
||||
{
|
||||
if(--conn->async.num_pending > 0)
|
||||
/* We are not done yet. Just return. */
|
||||
return CURLE_OK;
|
||||
|
||||
if(conn->async.temp_ai) {
|
||||
/* We are done, and while this latest request
|
||||
failed, some previous results exist. */
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = Curl_cache_addr(data, conn->async.temp_ai,
|
||||
conn->async.hostname,
|
||||
conn->async.port);
|
||||
if(!dns) {
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(conn->async.temp_ai);
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
/* make sure the temp pointer is cleared and isn't pointing to
|
||||
something we've taken care of already */
|
||||
conn->async.temp_ai = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
conn->async.dns = dns;
|
||||
|
||||
|
@@ -70,6 +70,12 @@ struct hostent;
|
||||
struct SessionHandle;
|
||||
struct connectdata;
|
||||
|
||||
#ifdef CURLRES_ASYNCH
|
||||
void Curl_async_cancel(struct connectdata *conn);
|
||||
#else
|
||||
#define Curl_async_cancel(x) do {} while(0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_global_host_cache_init() initializes and sets up a global DNS cache.
|
||||
* Global DNS cache is general badness. Do not use. This will be removed in
|
||||
|
52
lib/http.c
52
lib/http.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -520,7 +520,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *auth=NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
#endif
|
||||
@@ -530,7 +530,7 @@ output_auth_headers(struct connectdata *conn,
|
||||
(void)path;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
|
||||
negdata->context && !GSS_ERROR(negdata->status)) {
|
||||
auth="GSS-Negotiate";
|
||||
@@ -727,7 +727,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
if(checkprefix("GSS-Negotiate", start) ||
|
||||
checkprefix("Negotiate", start)) {
|
||||
int neg;
|
||||
@@ -1881,10 +1881,22 @@ static int https_getsock(struct connectdata *conn,
|
||||
(void)numsocks;
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifdef USE_AXTLS
|
||||
static int https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
(void)conn;
|
||||
(void)socks;
|
||||
(void)numsocks;
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
#endif /* USE_AXTLS */
|
||||
#endif /* USE_POLARSSL */
|
||||
#endif /* USE_QSOSSL */
|
||||
#endif /* USE_NSS */
|
||||
#endif /* USE_SSLEAY || USE_GNUTLS */
|
||||
|
||||
/*
|
||||
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
||||
@@ -2040,9 +2052,17 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
struct tm *tm;
|
||||
const struct tm *tm;
|
||||
char *buf = data->state.buffer;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct tm keeptime;
|
||||
|
||||
result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
if(result) {
|
||||
failf(data, "Invalid TIMEVALUE\n");
|
||||
return result;
|
||||
}
|
||||
tm = &keeptime;
|
||||
|
||||
/* The If-Modified-Since header family should have their times set in
|
||||
* GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
|
||||
@@ -2051,14 +2071,6 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
* Time)." (see page 20 of RFC2616).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GMTIME_R
|
||||
/* thread-safe version */
|
||||
struct tm keeptime;
|
||||
tm = (struct tm *)gmtime_r(&data->set.timevalue, &keeptime);
|
||||
#else
|
||||
tm = gmtime(&data->set.timevalue);
|
||||
#endif
|
||||
|
||||
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||||
snprintf(buf, BUFSIZE-1,
|
||||
"%s, %02d %s %4d %02d:%02d:%02d GMT",
|
||||
@@ -2642,7 +2654,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
#endif
|
||||
|
||||
if(data->set.timecondition) {
|
||||
result = Curl_add_timecondition(data, req_buffer);
|
||||
result = Curl_add_timecondition(data, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
@@ -3711,7 +3723,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
return result;
|
||||
}
|
||||
else if((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||
checkprefix("Location:", k->p)) {
|
||||
checkprefix("Location:", k->p) &&
|
||||
!data->req.location) {
|
||||
/* this is the URL that the server advises us to use instead */
|
||||
char *location = Curl_copy_header_value(k->p);
|
||||
if (!location)
|
||||
@@ -3720,7 +3733,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
/* ignore empty data */
|
||||
free(location);
|
||||
else {
|
||||
DEBUGASSERT(!data->req.location);
|
||||
data->req.location = location;
|
||||
|
||||
if(data->set.http_follow_location) {
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef USE_HTTP_NEGOTIATE
|
||||
|
||||
/* this is for Negotiate header input */
|
||||
int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
@@ -33,6 +33,10 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data);
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
#define GSS_ERROR(status) (status & 0x80000000)
|
||||
#endif
|
||||
|
||||
#endif /* USE_HTTP_NEGOTIATE */
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
|
||||
|
293
lib/http_negotiate_sspi.c
Normal file
293
lib/http_negotiate_sspi.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/* -- WIN32 approved -- */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_base64.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, bool proxy, char *server)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
const char* service;
|
||||
size_t length;
|
||||
|
||||
/* 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(server, 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;
|
||||
SecBufferDesc out_buff_desc;
|
||||
SecBuffer out_sec_buff;
|
||||
SecBufferDesc in_buff_desc;
|
||||
SecBuffer in_sec_buff;
|
||||
ULONG context_attributes;
|
||||
TimeStamp lifetime;
|
||||
|
||||
int ret;
|
||||
size_t len = 0, input_token_len = 0;
|
||||
bool gss = FALSE;
|
||||
const char* protocol;
|
||||
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
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 == SEC_E_OK) {
|
||||
/* We finished succesfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
* can't invent anything better */
|
||||
Curl_cleanup_negotiate(conn->data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(strlen(neg_ctx->server_name) == 0 &&
|
||||
(ret = get_gss_name(conn, proxy, neg_ctx->server_name)))
|
||||
return ret;
|
||||
|
||||
if (!neg_ctx->max_token_length) {
|
||||
PSecPkgInfo SecurityPackage;
|
||||
ret = s_pSecFn->QuerySecurityPackageInfo((SEC_CHAR *)"Negotiate",
|
||||
&SecurityPackage);
|
||||
if (ret != SEC_E_OK)
|
||||
return -1;
|
||||
|
||||
/* Allocate input and output buffers according to the max token size
|
||||
as indicated by the security package */
|
||||
neg_ctx->max_token_length = SecurityPackage->cbMaxToken;
|
||||
neg_ctx->output_token = (BYTE *)malloc(neg_ctx->max_token_length);
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
}
|
||||
|
||||
/* Obtain the input token, if any */
|
||||
header += strlen(neg_ctx->protocol);
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
if(len > 0) {
|
||||
input_token = malloc(neg_ctx->max_token_length);
|
||||
if(!input_token)
|
||||
return -1;
|
||||
|
||||
input_token_len = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token);
|
||||
if(input_token_len == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( !input_token ) {
|
||||
/* first call in a new negotation, we have to require credentials,
|
||||
and allocate memory for the context */
|
||||
|
||||
neg_ctx->credentials = (CredHandle *)malloc(sizeof(CredHandle));
|
||||
neg_ctx->context = (CtxtHandle *)malloc(sizeof(CtxtHandle));
|
||||
|
||||
if ( !neg_ctx->credentials || !neg_ctx->context)
|
||||
return -1;
|
||||
|
||||
neg_ctx->status =
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL, (SEC_CHAR *)"Negotiate",
|
||||
SECPKG_CRED_OUTBOUND, NULL, NULL,
|
||||
NULL, NULL, neg_ctx->credentials,
|
||||
&lifetime);
|
||||
if ( neg_ctx->status != SEC_E_OK )
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* prepare the output buffers, and input buffers if present */
|
||||
out_buff_desc.ulVersion = 0;
|
||||
out_buff_desc.cBuffers = 1;
|
||||
out_buff_desc.pBuffers = &out_sec_buff;
|
||||
|
||||
out_sec_buff.cbBuffer = neg_ctx->max_token_length;
|
||||
out_sec_buff.BufferType = SECBUFFER_TOKEN;
|
||||
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
||||
|
||||
|
||||
if (input_token) {
|
||||
in_buff_desc.ulVersion = 0;
|
||||
in_buff_desc.cBuffers = 1;
|
||||
in_buff_desc.pBuffers = &out_sec_buff;
|
||||
|
||||
in_sec_buff.cbBuffer = input_token_len;
|
||||
in_sec_buff.BufferType = SECBUFFER_TOKEN;
|
||||
in_sec_buff.pvBuffer = input_token;
|
||||
}
|
||||
|
||||
neg_ctx->status = s_pSecFn->InitializeSecurityContext(
|
||||
neg_ctx->credentials,
|
||||
input_token ? neg_ctx->context : 0,
|
||||
neg_ctx->server_name,
|
||||
ISC_REQ_CONFIDENTIALITY,
|
||||
0,
|
||||
SECURITY_NATIVE_DREP,
|
||||
input_token ? &in_buff_desc : 0,
|
||||
0,
|
||||
neg_ctx->context,
|
||||
&out_buff_desc,
|
||||
&context_attributes,
|
||||
&lifetime);
|
||||
|
||||
if ( GSS_ERROR(neg_ctx->status) )
|
||||
return -1;
|
||||
|
||||
if ( neg_ctx->status == SEC_I_COMPLETE_NEEDED ||
|
||||
neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE ) {
|
||||
neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,
|
||||
&out_buff_desc);
|
||||
if ( GSS_ERROR(neg_ctx->status) )
|
||||
return -1;
|
||||
}
|
||||
|
||||
neg_ctx->output_token_length = out_sec_buff.cbBuffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
&conn->data->state.negotiate;
|
||||
char *encoded = NULL;
|
||||
size_t len;
|
||||
char *userp;
|
||||
|
||||
len = Curl_base64_encode(conn->data,
|
||||
(const char*)neg_ctx->output_token,
|
||||
neg_ctx->output_token_length,
|
||||
&encoded);
|
||||
|
||||
if(len == 0)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
userp = aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "",
|
||||
neg_ctx->protocol, encoded);
|
||||
|
||||
if(proxy)
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
else
|
||||
conn->allocptr.userpwd = userp;
|
||||
free(encoded);
|
||||
Curl_cleanup_negotiate (conn->data);
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
{
|
||||
cleanup(&data->state.negotiate);
|
||||
cleanup(&data->state.proxyneg);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
119
lib/idn_win32.c
Normal file
119
lib/idn_win32.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
/***************************************************************************
|
||||
* IDN Implementation using windows native APIs
|
||||
* Pierre Joye <pierre@php.net>
|
||||
***************************************************************************/
|
||||
#if defined(WIN32) && defined(USE_WIN32_IDN)
|
||||
#include "windows.h"
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#define IDN_MAX_LENGTH 255
|
||||
|
||||
static wchar_t *_curl_win32_UTF8_to_wchar(const char *str_utf8)
|
||||
{
|
||||
wchar_t *str_w = NULL;
|
||||
|
||||
if (str_utf8) {
|
||||
int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
|
||||
str_utf8, -1, NULL, 0);
|
||||
if (str_w_len) {
|
||||
str_w = (wchar_t *) malloc(str_w_len * sizeof(wchar_t));
|
||||
if (str_w) {
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
free(str_w);
|
||||
str_w = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_w;
|
||||
}
|
||||
|
||||
static const char *_curl_win32_wchar_to_UTF8(const wchar_t *str_w)
|
||||
{
|
||||
char *str_utf8 = NULL;
|
||||
|
||||
if (str_w) {
|
||||
size_t str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
|
||||
0, NULL, NULL);
|
||||
DWORD err = GetLastError();
|
||||
if (str_utf8_len) {
|
||||
str_utf8 = (char *) malloc(str_utf8_len * sizeof(wchar_t));
|
||||
if (str_w) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
DWORD err = GetLastError();
|
||||
free((void *)str_utf8);
|
||||
str_utf8 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
int curl_win32_idn_to_ascii(const char *in, char **out)
|
||||
{
|
||||
wchar_t *in_w = _curl_win32_UTF8_to_wchar(in);
|
||||
if (in_w) {
|
||||
wchar_t punycode[IDN_MAX_LENGTH];
|
||||
if (IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH) == 0) {
|
||||
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||
free(in_w);
|
||||
return 0;
|
||||
}
|
||||
free(in_w);
|
||||
|
||||
*out = (char *)_curl_win32_wchar_to_UTF8(punycode);
|
||||
if (!(*out)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int curl_win32_ascii_to_idn(const char *in, size_t in_len, char **out_utf8)
|
||||
{
|
||||
if (in) {
|
||||
WCHAR unicode[IDN_MAX_LENGTH];
|
||||
|
||||
if (IdnToUnicode(0, (wchar_t *)in, -1, unicode, IDN_MAX_LENGTH) == 0) {
|
||||
wprintf(L"ERROR %d converting to Punycode\n", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
const char *out_utf8 = _curl_win32_wchar_to_UTF8(unicode);
|
||||
if (!out_utf8) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
typedef int dummy; /* because ISO C forbids an empty translation unit! */
|
||||
#endif
|
||||
/* WIN32 */
|
@@ -256,7 +256,7 @@ static int imap_getsock(struct connectdata *conn,
|
||||
return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
|
||||
}
|
||||
|
||||
/* fucntion that checks for an imap status code at the start of the
|
||||
/* function that checks for an imap status code at the start of the
|
||||
given string */
|
||||
static int imap_endofresp(struct pingpong *pp, int *resp)
|
||||
{
|
||||
|
@@ -6,7 +6,7 @@
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
@@ -36,7 +36,7 @@ use LWP::UserAgent;
|
||||
use strict;
|
||||
use vars qw($opt_b $opt_h $opt_i $opt_l $opt_n $opt_q $opt_t $opt_u $opt_v);
|
||||
|
||||
my $url = 'http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1';
|
||||
my $url = 'http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1';
|
||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||
my $openssl = 'openssl';
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
Option Explicit
|
||||
Const myVersion = "0.3.5"
|
||||
|
||||
Const myUrl = "http://mxr.mozilla.org/firefox/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1"
|
||||
Const myUrl = "http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1"
|
||||
|
||||
Const myOpenssl = "openssl.exe"
|
||||
|
||||
|
13
lib/multi.c
13
lib/multi.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -984,7 +984,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
/* we need to wait for the connect state as only then is the start time
|
||||
stored, but we must not check already completed handles */
|
||||
|
||||
timeout_ms = Curl_timeleft(easy->easy_conn, &now,
|
||||
timeout_ms = Curl_timeleft(data, &now,
|
||||
(easy->state <= CURLM_STATE_WAITDO)?
|
||||
TRUE:FALSE);
|
||||
|
||||
@@ -1408,6 +1408,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
|
||||
/* if both rates are within spec, resume transfer */
|
||||
Curl_pgrsUpdate(easy->easy_conn);
|
||||
if( ( (data->set.max_send_speed == 0) ||
|
||||
(data->progress.ulspeed < data->set.max_send_speed )) &&
|
||||
( (data->set.max_recv_speed == 0) ||
|
||||
@@ -2363,8 +2364,10 @@ static CURLcode addHandleToSendOrPendPipeline(struct SessionHandle *handle,
|
||||
if (pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) {
|
||||
/* this is a new one as head, expire it */
|
||||
conn->writechannel_inuse = FALSE; /* not in use yet */
|
||||
#ifdef DEBUGBUILD
|
||||
infof(conn->data, "%p is at send pipe head!\n",
|
||||
conn->send_pipe->head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||
}
|
||||
|
||||
@@ -2398,8 +2401,10 @@ static int checkPendPipeline(struct connectdata *conn)
|
||||
if(sendhead != conn->send_pipe->head) {
|
||||
/* this is a new one as head, expire it */
|
||||
conn->writechannel_inuse = FALSE; /* not in use yet */
|
||||
#ifdef DEBUGBUILD
|
||||
infof(conn->data, "%p is at send pipe head!\n",
|
||||
conn->send_pipe->head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||
}
|
||||
}
|
||||
@@ -2428,8 +2433,10 @@ static void moveHandleFromSendToRecvPipeline(struct SessionHandle *handle,
|
||||
/* Since there's a new easy handle at the start of the send pipeline,
|
||||
set its timeout value to 1ms to make it trigger instantly */
|
||||
conn->writechannel_inuse = FALSE; /* not used now */
|
||||
#ifdef DEBUGBUILD
|
||||
infof(conn->data, "%p is at send pipe head B!\n",
|
||||
conn->send_pipe->head->ptr);
|
||||
#endif
|
||||
Curl_expire(conn->send_pipe->head->ptr, 1);
|
||||
}
|
||||
|
||||
@@ -2565,7 +2572,9 @@ void Curl_expire(struct SessionHandle *data, long milli)
|
||||
while(list->size > 0)
|
||||
Curl_llist_remove(list, list->tail, NULL);
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
infof(data, "Expire cleared\n");
|
||||
#endif
|
||||
nowp->tv_sec = 0;
|
||||
nowp->tv_usec = 0;
|
||||
}
|
||||
|
36
lib/netrc.c
36
lib/netrc.c
@@ -50,15 +50,9 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Debug this single source file with:
|
||||
'make netrc' then run './netrc'!
|
||||
|
||||
Oh, make sure you have a .netrc file too ;-)
|
||||
*/
|
||||
|
||||
/* Get user and password from .netrc when given a machine name */
|
||||
|
||||
enum {
|
||||
enum host_lookup_state {
|
||||
NOTHING,
|
||||
HOSTFOUND, /* the 'machine' keyword was found */
|
||||
HOSTCOMPLETE, /* the machine name following the keyword was found too */
|
||||
@@ -67,11 +61,6 @@ enum {
|
||||
HOSTEND /* LAST enum */
|
||||
};
|
||||
|
||||
/* make sure we have room for at least this size: */
|
||||
#define LOGINSIZE 64
|
||||
#define PASSWORDSIZE 64
|
||||
|
||||
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char *login,
|
||||
char *password,
|
||||
@@ -83,7 +72,7 @@ int Curl_parsenetrc(const char *host,
|
||||
char *home = NULL;
|
||||
bool home_alloc = FALSE;
|
||||
bool netrc_alloc = FALSE;
|
||||
int state=NOTHING;
|
||||
enum host_lookup_state state=NOTHING;
|
||||
|
||||
char state_login=0; /* Found a login keyword */
|
||||
char state_password=0; /* Found a password keyword */
|
||||
@@ -210,6 +199,10 @@ int Curl_parsenetrc(const char *host,
|
||||
state_our_login = FALSE;
|
||||
}
|
||||
break;
|
||||
case HOSTCOMPLETE:
|
||||
case HOSTEND:
|
||||
/* Should not be reached. */
|
||||
DEBUGASSERT(0);
|
||||
} /* switch (state) */
|
||||
|
||||
tok = strtok_r(NULL, " \t\n", &tok_buf);
|
||||
@@ -226,20 +219,3 @@ int Curl_parsenetrc(const char *host,
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
#ifdef _NETRC_DEBUG
|
||||
int main(int argc, argv_item_t argv[])
|
||||
{
|
||||
char login[64]="";
|
||||
char password[64]="";
|
||||
|
||||
if(argc<2)
|
||||
return -1;
|
||||
|
||||
if(0 == ParseNetrc(argv[1], login, password)) {
|
||||
printf("HOST: %s LOGIN: %s PASSWORD: %s\n",
|
||||
argv[1], login, password);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -21,6 +21,12 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Make sure we have room for at least this size: */
|
||||
#define LOGINSIZE 64
|
||||
#define PASSWORDSIZE 64
|
||||
|
||||
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
|
||||
int Curl_parsenetrc(const char *host,
|
||||
char *login,
|
||||
char *password,
|
||||
|
366
lib/nss.c
366
lib/nss.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "strequal.h"
|
||||
#include "select.h"
|
||||
#include "sslgen.h"
|
||||
#include "llist.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
|
||||
#include <curl/mprintf.h>
|
||||
@@ -90,8 +91,12 @@ typedef struct {
|
||||
PRInt32 version; /* protocol version valid for this cipher */
|
||||
} cipher_s;
|
||||
|
||||
#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
|
||||
(x)->pValue=(v); (x)->ulValueLen = (l)
|
||||
#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \
|
||||
CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \
|
||||
ptr->type = (_type); \
|
||||
ptr->pValue = (_val); \
|
||||
ptr->ulValueLen = (_len); \
|
||||
} while(0)
|
||||
|
||||
#define CERT_NewTempCertificate __CERT_NewTempCertificate
|
||||
|
||||
@@ -277,36 +282,104 @@ static int is_file(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *fmt_nickname(char *str, bool *nickname_alloc)
|
||||
/* Return on heap allocated filename/nickname of a certificate. The returned
|
||||
* string should be later deallocated using free(). *is_nickname is set to TRUE
|
||||
* if the given string is treated as nickname; FALSE if the given string is
|
||||
* treated as file name.
|
||||
*/
|
||||
static char *fmt_nickname(struct SessionHandle *data, enum dupstring cert_kind,
|
||||
bool *is_nickname)
|
||||
{
|
||||
char *nickname = NULL;
|
||||
*nickname_alloc = FALSE;
|
||||
const char *str = data->set.str[cert_kind];
|
||||
const char *n;
|
||||
*is_nickname = TRUE;
|
||||
|
||||
if(is_file(str)) {
|
||||
char *n = strrchr(str, '/');
|
||||
if(n) {
|
||||
*nickname_alloc = TRUE;
|
||||
n++; /* skip last slash */
|
||||
nickname = aprintf("PEM Token #%d:%s", 1, n);
|
||||
}
|
||||
return nickname;
|
||||
if(!is_file(str))
|
||||
/* no such file exists, use the string as nickname */
|
||||
return strdup(str);
|
||||
|
||||
/* search the last slash; we require at least one slash in a file name */
|
||||
n = strrchr(str, '/');
|
||||
if(!n) {
|
||||
infof(data, "warning: certificate file name \"%s\" handled as nickname; "
|
||||
"please use \"./%s\" to force file name\n", str, str);
|
||||
return strdup(str);
|
||||
}
|
||||
|
||||
return str;
|
||||
/* we'll use the PEM reader to read the certificate from file */
|
||||
*is_nickname = FALSE;
|
||||
|
||||
n++; /* skip last slash */
|
||||
return aprintf("PEM Token #%d:%s", 1, n);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
/* Call PK11_CreateGenericObject() with the given obj_class and filename. If
|
||||
* the call succeeds, append the object handle to the list of objects so that
|
||||
* the object can be destroyed in Curl_nss_close(). */
|
||||
static CURLcode nss_create_object(struct ssl_connect_data *ssl,
|
||||
CK_OBJECT_CLASS obj_class,
|
||||
const char *filename, bool cacert)
|
||||
{
|
||||
PK11SlotInfo *slot;
|
||||
PK11GenericObject *obj;
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
|
||||
int attr_cnt = 0;
|
||||
|
||||
const int slot_id = (cacert) ? 0 : 1;
|
||||
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
||||
if(!slot_name)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
slot = PK11_FindSlotByName(slot_name);
|
||||
free(slot_name);
|
||||
if(!slot)
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
|
||||
strlen(filename) + 1);
|
||||
|
||||
if(CKO_CERTIFICATE == obj_class) {
|
||||
CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
|
||||
PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
|
||||
}
|
||||
|
||||
obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
|
||||
PK11_FreeSlot(slot);
|
||||
if(!obj)
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
|
||||
if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) {
|
||||
PK11_DestroyGenericObject(obj);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Destroy the NSS object whose handle is given by ptr. This function is
|
||||
* a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
|
||||
* NSS objects in Curl_nss_close() */
|
||||
static void nss_destroy_object(void *user, void *ptr)
|
||||
{
|
||||
PK11GenericObject *obj = (PK11GenericObject *)ptr;
|
||||
(void) user;
|
||||
PK11_DestroyGenericObject(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nss_load_cert(struct ssl_connect_data *ssl,
|
||||
const char *filename, PRBool cacert)
|
||||
{
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
CK_SLOT_ID slotID;
|
||||
PK11SlotInfo * slot = NULL;
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_ATTRIBUTE theTemplate[20];
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_BBOOL ckfalse = CK_FALSE;
|
||||
CK_OBJECT_CLASS objClass = CKO_CERTIFICATE;
|
||||
char slotname[SLOTSIZE];
|
||||
/* All CA and trust objects go into slot 0. Other slots are used
|
||||
* for storing certificates.
|
||||
*/
|
||||
const int slot_id = (cacert) ? 0 : 1;
|
||||
#endif
|
||||
CERTCertificate *cert;
|
||||
char *nickname = NULL;
|
||||
@@ -333,57 +406,15 @@ static int nss_load_cert(struct ssl_connect_data *ssl,
|
||||
}
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
attrs = theTemplate;
|
||||
|
||||
/* All CA and trust objects go into slot 0. Other slots are used
|
||||
* for storing certificates. With each new user certificate we increment
|
||||
* the slot count. We only support 1 user certificate right now.
|
||||
*/
|
||||
if(cacert)
|
||||
slotID = 0;
|
||||
else
|
||||
slotID = 1;
|
||||
|
||||
snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
|
||||
|
||||
nickname = aprintf("PEM Token #%ld:%s", slotID, n);
|
||||
nickname = aprintf("PEM Token #%d:%s", slot_id, n);
|
||||
if(!nickname)
|
||||
return 0;
|
||||
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
|
||||
if(!slot) {
|
||||
if(CURLE_OK != nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert)) {
|
||||
free(nickname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) );
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) );
|
||||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)filename,
|
||||
strlen(filename)+1);
|
||||
attrs++;
|
||||
if(cacert) {
|
||||
PK11_SETATTRS(attrs, CKA_TRUST, &cktrue, sizeof(CK_BBOOL) );
|
||||
}
|
||||
else {
|
||||
PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) );
|
||||
}
|
||||
attrs++;
|
||||
|
||||
/* This load the certificate in our PEM module into the appropriate
|
||||
* slot.
|
||||
*/
|
||||
ssl->cacert[slotID] = PK11_CreateGenericObject(slot, theTemplate, 4,
|
||||
PR_FALSE /* isPerm */);
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
if(ssl->cacert[slotID] == NULL) {
|
||||
free(nickname);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* We don't have PK11_CreateGenericObject but a file-based cert was passed
|
||||
* in. We need to fail.
|
||||
@@ -503,60 +534,35 @@ static int nss_load_key(struct connectdata *conn, int sockindex,
|
||||
char *key_file)
|
||||
{
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
PK11SlotInfo * slot = NULL;
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_ATTRIBUTE theTemplate[20];
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
|
||||
CK_SLOT_ID slotID;
|
||||
char slotname[SLOTSIZE];
|
||||
struct ssl_connect_data *sslconn = &conn->ssl[sockindex];
|
||||
PK11SlotInfo *slot;
|
||||
SECStatus status;
|
||||
struct ssl_connect_data *ssl = conn->ssl;
|
||||
(void)sockindex; /* unused */
|
||||
|
||||
attrs = theTemplate;
|
||||
|
||||
/* FIXME: grok the various file types */
|
||||
|
||||
slotID = 1; /* hardcoded for now */
|
||||
|
||||
snprintf(slotname, sizeof(slotname), "PEM Token #%ld", slotID);
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
|
||||
if(!slot)
|
||||
return 0;
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)key_file,
|
||||
strlen(key_file)+1); attrs++;
|
||||
|
||||
/* When adding an encrypted key the PKCS#11 will be set as removed */
|
||||
sslconn->key = PK11_CreateGenericObject(slot, theTemplate, 3,
|
||||
PR_FALSE /* isPerm */);
|
||||
if(sslconn->key == NULL) {
|
||||
if(CURLE_OK != nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE)) {
|
||||
PR_SetError(SEC_ERROR_BAD_KEY, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
slot = PK11_FindSlotByName("PEM Token #1");
|
||||
if(!slot)
|
||||
return 0;
|
||||
|
||||
/* This will force the token to be seen as re-inserted */
|
||||
SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
|
||||
PK11_IsPresent(slot);
|
||||
|
||||
/* parg is initialized in nss_Init_Tokens() */
|
||||
if(PK11_Authenticate(slot, PR_TRUE,
|
||||
conn->data->set.str[STRING_KEY_PASSWD]) != SECSuccess) {
|
||||
|
||||
PK11_FreeSlot(slot);
|
||||
return 0;
|
||||
}
|
||||
status = PK11_Authenticate(slot, PR_TRUE,
|
||||
conn->data->set.str[STRING_KEY_PASSWD]);
|
||||
PK11_FreeSlot(slot);
|
||||
|
||||
return 1;
|
||||
return (SECSuccess == status) ? 1 : 0;
|
||||
#else
|
||||
/* If we don't have PK11_CreateGenericObject then we can't load a file-based
|
||||
* key.
|
||||
*/
|
||||
(void)conn; /* unused */
|
||||
(void)key_file; /* unused */
|
||||
(void)sockindex; /* unused */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -1050,12 +1056,8 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
|
||||
connssl->client_nickname = NULL;
|
||||
}
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
if(connssl->key)
|
||||
(void)PK11_DestroyGenericObject(connssl->key);
|
||||
if(connssl->cacert[1])
|
||||
(void)PK11_DestroyGenericObject(connssl->cacert[1]);
|
||||
if(connssl->cacert[0])
|
||||
(void)PK11_DestroyGenericObject(connssl->cacert[0]);
|
||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||
Curl_llist_destroy(connssl->obj_list, NULL);
|
||||
#endif
|
||||
connssl->handle = NULL;
|
||||
}
|
||||
@@ -1095,6 +1097,55 @@ static bool handle_cc_error(PRInt32 err, struct SessionHandle *data)
|
||||
static Curl_recv nss_recv;
|
||||
static Curl_send nss_send;
|
||||
|
||||
static CURLcode nss_load_ca_certificates(struct connectdata *conn,
|
||||
int sockindex)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *cafile = data->set.ssl.CAfile;
|
||||
const char *capath = data->set.ssl.CApath;
|
||||
|
||||
if(cafile && !nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE))
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
|
||||
if(capath) {
|
||||
struct_stat st;
|
||||
if(stat(capath, &st) == -1)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
|
||||
if(S_ISDIR(st.st_mode)) {
|
||||
PRDirEntry *entry;
|
||||
PRDir *dir = PR_OpenDir(capath);
|
||||
if(!dir)
|
||||
return CURLE_SSL_CACERT_BADFILE;
|
||||
|
||||
while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
|
||||
char *fullpath = aprintf("%s/%s", capath, entry->name);
|
||||
if(!fullpath) {
|
||||
PR_CloseDir(dir);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
|
||||
/* This is purposefully tolerant of errors so non-PEM files can
|
||||
* be in the same directory */
|
||||
infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
|
||||
|
||||
free(fullpath);
|
||||
}
|
||||
|
||||
PR_CloseDir(dir);
|
||||
}
|
||||
else
|
||||
infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
|
||||
}
|
||||
|
||||
infof(data, " CAfile: %s\n CApath: %s\n",
|
||||
cafile ? cafile : "none",
|
||||
capath ? capath : "none");
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
PRInt32 err;
|
||||
@@ -1117,9 +1168,10 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
connssl->data = data;
|
||||
|
||||
#ifdef HAVE_PK11_CREATEGENERICOBJECT
|
||||
connssl->cacert[0] = NULL;
|
||||
connssl->cacert[1] = NULL;
|
||||
connssl->key = NULL;
|
||||
/* list of all NSS objects we need to destroy in Curl_nss_close() */
|
||||
connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
|
||||
if(!connssl->obj_list)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
/* FIXME. NSS doesn't support multiple databases open at the same time. */
|
||||
@@ -1236,53 +1288,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
NULL) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
if(!data->set.ssl.verifypeer)
|
||||
/* skip the verifying of the peer */
|
||||
;
|
||||
else if(data->set.ssl.CAfile) {
|
||||
int rc = nss_load_cert(&conn->ssl[sockindex], data->set.ssl.CAfile,
|
||||
PR_TRUE);
|
||||
if(!rc) {
|
||||
curlerr = CURLE_SSL_CACERT_BADFILE;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if(data->set.ssl.CApath) {
|
||||
struct_stat st;
|
||||
PRDir *dir;
|
||||
PRDirEntry *entry;
|
||||
|
||||
if(stat(data->set.ssl.CApath, &st) == -1) {
|
||||
curlerr = CURLE_SSL_CACERT_BADFILE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(S_ISDIR(st.st_mode)) {
|
||||
int rc;
|
||||
|
||||
dir = PR_OpenDir(data->set.ssl.CApath);
|
||||
do {
|
||||
entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN);
|
||||
|
||||
if(entry) {
|
||||
char fullpath[PATH_MAX];
|
||||
|
||||
snprintf(fullpath, sizeof(fullpath), "%s/%s", data->set.ssl.CApath,
|
||||
entry->name);
|
||||
rc = nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE);
|
||||
/* FIXME: check this return value! */
|
||||
}
|
||||
/* This is purposefully tolerant of errors so non-PEM files
|
||||
* can be in the same directory */
|
||||
} while(entry != NULL);
|
||||
PR_CloseDir(dir);
|
||||
}
|
||||
}
|
||||
infof(data,
|
||||
" CAfile: %s\n"
|
||||
" CApath: %s\n",
|
||||
data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
|
||||
data->set.ssl.CApath ? data->set.ssl.CApath : "none");
|
||||
if(data->set.ssl.verifypeer && (CURLE_OK !=
|
||||
(curlerr = nss_load_ca_certificates(conn, sockindex))))
|
||||
goto error;
|
||||
|
||||
if (data->set.ssl.CRLfile) {
|
||||
if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
|
||||
@@ -1295,25 +1303,20 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
}
|
||||
|
||||
if(data->set.str[STRING_CERT]) {
|
||||
bool nickname_alloc = FALSE;
|
||||
char *nickname = fmt_nickname(data->set.str[STRING_CERT], &nickname_alloc);
|
||||
bool is_nickname;
|
||||
char *nickname = fmt_nickname(data, STRING_CERT, &is_nickname);
|
||||
if(!nickname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY])) {
|
||||
if(!is_nickname && !cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
|
||||
data->set.str[STRING_KEY])) {
|
||||
/* failf() is already done in cert_stuff() */
|
||||
if(nickname_alloc)
|
||||
free(nickname);
|
||||
free(nickname);
|
||||
return CURLE_SSL_CERTPROBLEM;
|
||||
}
|
||||
|
||||
/* this "takes over" the pointer to the allocated name or makes a
|
||||
dup of it */
|
||||
connssl->client_nickname = nickname_alloc?nickname:strdup(nickname);
|
||||
if(!connssl->client_nickname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* store the nickname for SelectClientCert() called during handshake */
|
||||
connssl->client_nickname = nickname;
|
||||
}
|
||||
else
|
||||
connssl->client_nickname = NULL;
|
||||
@@ -1344,7 +1347,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
SSL_SetURL(connssl->handle, conn->host.name);
|
||||
|
||||
/* check timeout situation */
|
||||
time_left = Curl_timeleft(conn, NULL, TRUE);
|
||||
time_left = Curl_timeleft(data, NULL, TRUE);
|
||||
if(time_left < 0L) {
|
||||
failf(data, "timed out before SSL handshake");
|
||||
goto error;
|
||||
@@ -1367,18 +1370,17 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
|
||||
display_conn_info(conn, connssl->handle);
|
||||
|
||||
if (data->set.str[STRING_SSL_ISSUERCERT]) {
|
||||
SECStatus ret;
|
||||
bool nickname_alloc = FALSE;
|
||||
char *nickname = fmt_nickname(data->set.str[STRING_SSL_ISSUERCERT],
|
||||
&nickname_alloc);
|
||||
|
||||
SECStatus ret = SECFailure;
|
||||
bool is_nickname;
|
||||
char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
|
||||
if(!nickname)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
if(is_nickname)
|
||||
/* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
|
||||
ret = check_issuer_cert(connssl->handle, nickname);
|
||||
|
||||
if(nickname_alloc)
|
||||
free(nickname);
|
||||
free(nickname);
|
||||
|
||||
if(SECFailure == ret) {
|
||||
infof(data,"SSL certificate issuer check failed\n");
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -514,3 +514,29 @@ time_t curl_getdate(const char *p, const time_t *now)
|
||||
/* everything else is fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
const struct tm *tm;
|
||||
#ifdef HAVE_GMTIME_R
|
||||
/* thread-safe version */
|
||||
tm = (struct tm *)gmtime_r(&intime, store);
|
||||
#else
|
||||
tm = gmtime(&intime);
|
||||
if(tm)
|
||||
*store = *tm; /* copy the pointed struct to the local copy */
|
||||
#endif
|
||||
|
||||
if(!tm)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -43,4 +43,6 @@ int Curl_parsedate(const char *date, time_t *output);
|
||||
#define PARSEDATE_LATER 1
|
||||
#define PARSEDATE_SOONER 2
|
||||
|
||||
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
||||
|
||||
#endif
|
||||
|
@@ -170,7 +170,7 @@ void Curl_pp_init(struct pingpong *pp)
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Curl_pp_sendfv()
|
||||
* Curl_pp_vsendf()
|
||||
*
|
||||
* Send the formated string as a command to a pingpong server. Note that
|
||||
* the string should not have any CRLF appended, as this function will
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
* Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -229,7 +229,7 @@ Curl_polarssl_connect(struct connectdata *conn,
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
} else {
|
||||
/* wait for data from server... */
|
||||
long timeout_ms = Curl_timeleft(conn, NULL, TRUE);
|
||||
long timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
failf(data, "SSL connection timeout");
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -175,7 +175,7 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex)
|
||||
h->exitPgm = Curl_qsossl_trap_cert;
|
||||
|
||||
/* figure out how long time we should wait at maximum */
|
||||
timeout_ms = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
|
36
lib/setup.h
36
lib/setup.h
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -162,13 +162,27 @@
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# define CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_FILE
|
||||
# define CURL_DISABLE_RTSP
|
||||
# ifndef CURL_DISABLE_TFTP
|
||||
# define CURL_DISABLE_TFTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FTP
|
||||
# define CURL_DISABLE_FTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_LDAP
|
||||
# define CURL_DISABLE_LDAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_TELNET
|
||||
# define CURL_DISABLE_TELNET
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_DICT
|
||||
# define CURL_DISABLE_DICT
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_FILE
|
||||
# define CURL_DISABLE_FILE
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -537,10 +551,14 @@ int netware_init(void);
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || defined(USE_QSOSSL) || defined(USE_POLARSSL)
|
||||
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
|
||||
#define USE_HTTP_NEGOTIATE
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM)
|
||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || defined(USE_GNUTLS) || defined(USE_NSS)
|
||||
#define USE_NTLM
|
||||
|
@@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -488,6 +488,5 @@ typedef int sig_atomic_t;
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
|
||||
#endif /* __SETUP_ONCE_H */
|
||||
|
||||
|
10
lib/smtp.c
10
lib/smtp.c
@@ -754,9 +754,13 @@ static CURLcode smtp_mail(struct connectdata *conn)
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* send MAIL */
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s",
|
||||
data->set.str[STRING_MAIL_FROM]);
|
||||
/* send MAIL FROM */
|
||||
if (data->set.str[STRING_MAIL_FROM][0] == '<')
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s",
|
||||
data->set.str[STRING_MAIL_FROM]);
|
||||
else
|
||||
result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:<%s>",
|
||||
data->set.str[STRING_MAIL_FROM]);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -137,7 +137,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* get timeout */
|
||||
timeout = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
@@ -399,7 +399,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
|
||||
}
|
||||
|
||||
/* get timeout */
|
||||
timeout = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout < 0) {
|
||||
/* time-out, bail out, go home */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -139,7 +139,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
|
||||
|
||||
/* get timeout */
|
||||
timeout = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
/* GSSAPI request looks like
|
||||
* +----+------+-----+----------------+
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
* Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -186,7 +186,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
|
||||
char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
|
||||
|
||||
/* get timeout */
|
||||
timeout = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
/* GSSAPI request looks like
|
||||
* +----+------+-----+----------------+
|
||||
|
31
lib/ssh.c
31
lib/ssh.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -985,6 +985,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
sshc->actualcode = CURLE_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
|
||||
}
|
||||
else {
|
||||
/* Return the error type */
|
||||
@@ -1045,14 +1046,22 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
*/
|
||||
if(curl_strequal("pwd", sshc->quote_item->data)) {
|
||||
/* output debug output if that is requested */
|
||||
char *tmp = aprintf("257 \"%s\" is current directory.\n",
|
||||
sftp_scp->path);
|
||||
if(!tmp) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
state(conn, SSH_SFTP_CLOSE);
|
||||
break;
|
||||
}
|
||||
if(data->set.verbose) {
|
||||
char tmp[PATH_MAX+1];
|
||||
|
||||
Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
|
||||
snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
|
||||
sftp_scp->path);
|
||||
Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
|
||||
}
|
||||
/* this sends an FTP-like "header" to the header callback so that the
|
||||
current directory can be read very similar to how it is read when
|
||||
using ordinary FTP. */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
state(conn, SSH_SFTP_NEXT_QUOTE);
|
||||
break;
|
||||
}
|
||||
@@ -2072,6 +2081,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
Curl_safefree(sshc->homedir);
|
||||
sshc->homedir = NULL;
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_DISCONNECT);
|
||||
break;
|
||||
@@ -2290,6 +2300,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
|
||||
|
||||
Curl_safefree(sshc->homedir);
|
||||
sshc->homedir = NULL;
|
||||
conn->data->state.most_recent_ftp_entrypath = NULL;
|
||||
|
||||
state(conn, SSH_SESSION_FREE);
|
||||
break;
|
||||
@@ -2442,11 +2453,19 @@ static CURLcode ssh_easy_statemach(struct connectdata *conn,
|
||||
long left;
|
||||
|
||||
result = ssh_statemach_act(conn, &block);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
else {
|
||||
struct timeval now = Curl_tvnow();
|
||||
result = Curl_speedcheck(data, now);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
|
||||
left = Curl_timeleft(conn, NULL, duringconnect);
|
||||
left = Curl_timeleft(data, NULL, duringconnect);
|
||||
if(left < 0) {
|
||||
failf(data, "Operation timed out\n");
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
|
@@ -57,6 +57,7 @@
|
||||
#include "nssg.h" /* NSS versions */
|
||||
#include "qssl.h" /* QSOSSL versions */
|
||||
#include "polarssl.h" /* PolarSSL versions */
|
||||
#include "axtls.h" /* axTLS versions */
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "url.h"
|
||||
@@ -349,8 +350,11 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
store->name = clone_host; /* clone host name */
|
||||
store->remote_port = conn->remote_port; /* port number */
|
||||
|
||||
if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config))
|
||||
if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) {
|
||||
store->sessionid = NULL; /* let caller free sessionid */
|
||||
free(clone_host);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
144
lib/ssluse.c
144
lib/ssluse.c
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@@ -225,7 +225,8 @@ static int ossl_seed(struct SessionHandle *data)
|
||||
/* If we get here, it means we need to seed the PRNG using a "silly"
|
||||
approach! */
|
||||
#ifdef HAVE_RAND_SCREEN
|
||||
/* if RAND_screen() is present, it was called during global init */
|
||||
/* if RAND_screen() is present, this is windows and thus we assume that the
|
||||
randomness is already taken care of */
|
||||
nread = 100; /* just a value */
|
||||
#else
|
||||
{
|
||||
@@ -324,9 +325,9 @@ int cert_stuff(struct connectdata *conn,
|
||||
* If password has been given, we store that in the global
|
||||
* area (*shudder*) for a while:
|
||||
*/
|
||||
size_t len = strlen(data->set.key_passwd);
|
||||
size_t len = strlen(data->set.str[STRING_KEY_PASSWD]);
|
||||
if(len < sizeof(global_passwd))
|
||||
memcpy(global_passwd, data->set.key_passwd, len+1);
|
||||
memcpy(global_passwd, data->set.str[STRING_KEY_PASSWD], len+1);
|
||||
#else
|
||||
/*
|
||||
* We set the password in the callback userdata
|
||||
@@ -685,13 +686,6 @@ int Curl_ossl_init(void)
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
#ifdef HAVE_RAND_SCREEN
|
||||
/* This one gets a random value by reading the currently shown screen.
|
||||
RAND_screen() is not thread-safe according to OpenSSL devs - although not
|
||||
mentioned in documentation. */
|
||||
RAND_screen();
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1469,7 +1463,8 @@ ossl_connect_step1(struct connectdata *conn,
|
||||
connssl->ctx = SSL_CTX_new(req_method);
|
||||
|
||||
if(!connssl->ctx) {
|
||||
failf(data, "SSL: couldn't create a context!");
|
||||
failf(data, "SSL: couldn't create a context: %s",
|
||||
ERR_error_string(ERR_peek_error(), NULL));
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -1846,31 +1841,35 @@ static void pubkey_show(struct SessionHandle *data,
|
||||
unsigned char *raw,
|
||||
int len)
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t left = sizeof(buffer);
|
||||
size_t left;
|
||||
int i;
|
||||
char *ptr=buffer;
|
||||
char namebuf[32];
|
||||
char *buffer;
|
||||
|
||||
snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
|
||||
|
||||
for(i=0; i< len; i++) {
|
||||
snprintf(ptr, left, "%02x:", raw[i]);
|
||||
ptr += 3;
|
||||
left -= 3;
|
||||
left = sizeof(len*3 + 1);
|
||||
buffer = malloc(left);
|
||||
if(buffer) {
|
||||
char *ptr=buffer;
|
||||
snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
|
||||
for(i=0; i< len; i++) {
|
||||
snprintf(ptr, left, "%02x:", raw[i]);
|
||||
ptr += 3;
|
||||
left -= 3;
|
||||
}
|
||||
infof(data, " %s: %s\n", namebuf, buffer);
|
||||
push_certinfo(data, num, namebuf, buffer);
|
||||
free(buffer);
|
||||
}
|
||||
infof(data, " %s: %s\n", namebuf, buffer);
|
||||
push_certinfo(data, num, namebuf, buffer);
|
||||
}
|
||||
|
||||
#define print_pubkey_BN(_type, _name, _num) \
|
||||
do { \
|
||||
if (pubkey->pkey._type->_name != NULL) { \
|
||||
int len = BN_num_bytes(pubkey->pkey._type->_name); \
|
||||
if(len < (int)sizeof(buf)) { \
|
||||
BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)buf); \
|
||||
buf[len] = 0; \
|
||||
pubkey_show(data, _num, #_type, #_name, (unsigned char*)buf, len); \
|
||||
if(len < CERTBUFFERSIZE) { \
|
||||
BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \
|
||||
bufp[len] = 0; \
|
||||
pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -1986,25 +1985,38 @@ static int init_certinfo(struct SessionHandle *data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This size was previously 512 which has been reported "too small" without
|
||||
* any specifics, so it was enlarged to allow more data to get shown uncut.
|
||||
* The "perfect" size is yet to figure out.
|
||||
*/
|
||||
#define CERTBUFFERSIZE 8192
|
||||
|
||||
static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
struct ssl_connect_data *connssl)
|
||||
|
||||
{
|
||||
STACK_OF(X509) *sk;
|
||||
int i;
|
||||
char buf[512];
|
||||
char *bufp;
|
||||
struct SessionHandle *data = conn->data;
|
||||
int numcerts;
|
||||
|
||||
sk = SSL_get_peer_cert_chain(connssl->handle);
|
||||
|
||||
if(!sk)
|
||||
bufp = malloc(CERTBUFFERSIZE);
|
||||
if(!bufp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
sk = SSL_get_peer_cert_chain(connssl->handle);
|
||||
if(!sk) {
|
||||
free(bufp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
numcerts = sk_X509_num(sk);
|
||||
|
||||
if(init_certinfo(data, numcerts))
|
||||
if(init_certinfo(data, numcerts)) {
|
||||
free(bufp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
infof(data, "--- Certificate chain\n");
|
||||
for (i=0; i<numcerts; i++) {
|
||||
@@ -2024,68 +2036,70 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
int j;
|
||||
char *ptr;
|
||||
|
||||
(void)x509_name_oneline(X509_get_subject_name(x), buf, sizeof(buf));
|
||||
infof(data, "%2d Subject: %s\n",i,buf);
|
||||
push_certinfo(data, i, "Subject", buf);
|
||||
(void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE);
|
||||
infof(data, "%2d Subject: %s\n", i, bufp);
|
||||
push_certinfo(data, i, "Subject", bufp);
|
||||
|
||||
(void)x509_name_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
|
||||
infof(data, " Issuer: %s\n",buf);
|
||||
push_certinfo(data, i, "Issuer", buf);
|
||||
(void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE);
|
||||
infof(data, " Issuer: %s\n", bufp);
|
||||
push_certinfo(data, i, "Issuer", bufp);
|
||||
|
||||
value = X509_get_version(x);
|
||||
infof(data, " Version: %lu (0x%lx)\n", value+1, value);
|
||||
snprintf(buf, sizeof(buf), "%lx", value);
|
||||
push_certinfo(data, i, "Version", buf); /* hex */
|
||||
snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
|
||||
push_certinfo(data, i, "Version", bufp); /* hex */
|
||||
|
||||
num=X509_get_serialNumber(x);
|
||||
if (num->length <= 4) {
|
||||
value = ASN1_INTEGER_get(num);
|
||||
infof(data," Serial Number: %ld (0x%lx)\n", value, value);
|
||||
snprintf(buf, sizeof(buf), "%lx", value);
|
||||
snprintf(bufp, CERTBUFFERSIZE, "%lx", value);
|
||||
}
|
||||
else {
|
||||
int left = CERTBUFFERSIZE;
|
||||
|
||||
ptr = buf;
|
||||
ptr = bufp;
|
||||
*ptr++ = 0;
|
||||
if(num->type == V_ASN1_NEG_INTEGER)
|
||||
*ptr++='-';
|
||||
|
||||
for (j=0; j<num->length; j++) {
|
||||
for (j=0; (j<num->length) && (left>=4); j++) {
|
||||
/* TODO: length restrictions */
|
||||
snprintf(ptr, 3, "%02x%c",num->data[j],
|
||||
((j+1 == num->length)?'\n':':'));
|
||||
ptr += 3;
|
||||
left-=4;
|
||||
}
|
||||
if(num->length)
|
||||
infof(data," Serial Number: %s\n", buf);
|
||||
infof(data," Serial Number: %s\n", bufp);
|
||||
else
|
||||
buf[0]=0;
|
||||
bufp[0]=0;
|
||||
}
|
||||
if(buf[0])
|
||||
push_certinfo(data, i, "Serial Number", buf); /* hex */
|
||||
if(bufp[0])
|
||||
push_certinfo(data, i, "Serial Number", bufp); /* hex */
|
||||
|
||||
cinf = x->cert_info;
|
||||
|
||||
j = asn1_object_dump(cinf->signature->algorithm, buf, sizeof(buf));
|
||||
j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE);
|
||||
if(!j) {
|
||||
infof(data, " Signature Algorithm: %s\n", buf);
|
||||
push_certinfo(data, i, "Signature Algorithm", buf);
|
||||
infof(data, " Signature Algorithm: %s\n", bufp);
|
||||
push_certinfo(data, i, "Signature Algorithm", bufp);
|
||||
}
|
||||
|
||||
certdate = X509_get_notBefore(x);
|
||||
asn1_output(certdate, buf, sizeof(buf));
|
||||
infof(data, " Start date: %s\n", buf);
|
||||
push_certinfo(data, i, "Start date", buf);
|
||||
asn1_output(certdate, bufp, CERTBUFFERSIZE);
|
||||
infof(data, " Start date: %s\n", bufp);
|
||||
push_certinfo(data, i, "Start date", bufp);
|
||||
|
||||
certdate = X509_get_notAfter(x);
|
||||
asn1_output(certdate, buf, sizeof(buf));
|
||||
infof(data, " Expire date: %s\n", buf);
|
||||
push_certinfo(data, i, "Expire date", buf);
|
||||
asn1_output(certdate, bufp, CERTBUFFERSIZE);
|
||||
infof(data, " Expire date: %s\n", bufp);
|
||||
push_certinfo(data, i, "Expire date", bufp);
|
||||
|
||||
j = asn1_object_dump(cinf->key->algor->algorithm, buf, sizeof(buf));
|
||||
j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE);
|
||||
if(!j) {
|
||||
infof(data, " Public Key Algorithm: %s\n", buf);
|
||||
push_certinfo(data, i, "Public Key Algorithm", buf);
|
||||
infof(data, " Public Key Algorithm: %s\n", bufp);
|
||||
push_certinfo(data, i, "Public Key Algorithm", bufp);
|
||||
}
|
||||
|
||||
pubkey = X509_get_pubkey(x);
|
||||
@@ -2096,8 +2110,8 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
case EVP_PKEY_RSA:
|
||||
infof(data, " RSA Public Key (%d bits)\n",
|
||||
BN_num_bits(pubkey->pkey.rsa->n));
|
||||
snprintf(buf, sizeof(buf), "%d", BN_num_bits(pubkey->pkey.rsa->n));
|
||||
push_certinfo(data, i, "RSA Public Key", buf);
|
||||
snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n));
|
||||
push_certinfo(data, i, "RSA Public Key", bufp);
|
||||
|
||||
print_pubkey_BN(rsa, n, i);
|
||||
print_pubkey_BN(rsa, e, i);
|
||||
@@ -2137,6 +2151,8 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
||||
dumpcert(data, x, i);
|
||||
}
|
||||
|
||||
free(bufp);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -2379,7 +2395,7 @@ ossl_connect_common(struct connectdata *conn,
|
||||
|
||||
if(ssl_connect_1==connssl->connecting_state) {
|
||||
/* Find out how much more time we're allowed */
|
||||
timeout_ms = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* no need to continue if time already is up */
|
||||
@@ -2396,7 +2412,7 @@ ossl_connect_common(struct connectdata *conn,
|
||||
ssl_connect_2_writing == connssl->connecting_state) {
|
||||
|
||||
/* check allowed time left */
|
||||
timeout_ms = Curl_timeleft(conn, NULL, TRUE);
|
||||
timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
if(timeout_ms < 0) {
|
||||
/* no need to continue if time already is up */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2004 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2004 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
|
@@ -29,15 +29,15 @@
|
||||
* to implement string conversion to our curl_off_t integral data type.
|
||||
*
|
||||
* Notice that curl_off_t might be 64 or 32 bit wide, and that it might use
|
||||
* an undelying data type which might be 'long', 'int64_t', 'long long' or
|
||||
* an underlying data type which might be 'long', 'int64_t', 'long long' or
|
||||
* '__int64' and more remotely other data types.
|
||||
*
|
||||
* On systems where the size of curl_off_t is greater than the size of 'long'
|
||||
* the conversion funtion to use is strtoll() if it is available, otherwise,
|
||||
* the conversion function to use is strtoll() if it is available, otherwise,
|
||||
* we emulate its functionality with our own clone.
|
||||
*
|
||||
* On systems where the size of curl_off_t is smaller or equal than the size
|
||||
* of 'long' the conversion funtion to use is strtol().
|
||||
* of 'long' the conversion function to use is strtol().
|
||||
*/
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user